diff options
30 files changed, 1115 insertions, 1898 deletions
@@ -73,6 +73,12 @@ Deprecated and removed features, and other changes affecting compatibility: compatibility symbols to support old binaries. All programs should use strsignal instead. +* The deprecated symbols sys_errlist, _sys_errlist, sys_nerr, and _sys_nerr + are no longer available to newly linked binaries, and their declarations + have been removed from from <stdio.h>. They are exported solely as + compatibility symbols to support old binaries. All programs should use + strerror or strerror_r instead. + Changes to build and runtime requirements: * powerpc64le requires GCC 7.4 or newer. This is required for supporting diff --git a/include/stdio.h b/include/stdio.h index 9df98b2833..9e3bf6fe42 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -186,7 +186,7 @@ ssize_t __libc_readline_unlocked (FILE *fp, char *buffer, size_t length); libc_hidden_proto (__libc_readline_unlocked); extern const char *const _sys_errlist_internal[] attribute_hidden; -extern int _sys_nerr_internal attribute_hidden; +extern const char *__get_errlist (int) attribute_hidden; libc_hidden_ldbl_proto (__asprintf) diff --git a/libio/Makefile b/libio/Makefile index 59e1f68e9c..926df1870b 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -23,7 +23,7 @@ subdir := libio include ../Makeconfig headers := stdio.h \ - bits/stdio.h bits/stdio2.h bits/sys_errlist.h bits/stdio-ldbl.h \ + bits/stdio.h bits/stdio2.h bits/stdio-ldbl.h \ bits/types/FILE.h bits/types/__FILE.h bits/types/struct_FILE.h \ bits/types/__fpos_t.h bits/types/__fpos64_t.h \ bits/types/cookie_io_functions_t.h diff --git a/libio/stdio.h b/libio/stdio.h index 07f2d9afb5..998470943e 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -779,12 +779,6 @@ extern int ferror_unlocked (FILE *__stream) __THROW __wur; marked with __THROW. */ extern void perror (const char *__s); -/* Provide the declarations for `sys_errlist' and `sys_nerr' if they - are available on this system. Even if available, these variables - should not be used directly. The `strerror' function provides - all the necessary functionality. */ -#include <bits/sys_errlist.h> - #ifdef __USE_POSIX /* Return the system file descriptor for STREAM. */ diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py index 8c72b9e571..07e9b457da 100755 --- a/scripts/build-many-glibcs.py +++ b/scripts/build-many-glibcs.py @@ -892,8 +892,7 @@ class Context(object): # Some other files have such dependencies but do not need to # be touched because nothing in a build depends on the files # in question. - for f in ('sysdeps/gnu/errlist.c', - 'sysdeps/mach/hurd/bits/errno.h'): + for f in ('sysdeps/mach/hurd/bits/errno.h',): to_touch = os.path.join(srcdir, f) subprocess.run(['touch', '-c', to_touch], check=True) for dirpath, dirnames, filenames in os.walk(srcdir): diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 1333203046..73bf0da296 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -85,6 +85,8 @@ generated += tst-printf-bz18872.c tst-printf-bz18872.mtrace \ tst-printf-bz25691.mtrace tst-printf-bz25691-mem.out endif +tests-special += $(objpfx)tst-errno-manual.out + include ../Rules ifeq ($(run-built-tests),yes) @@ -129,6 +131,15 @@ $(objpfx)tst-%-mem.out: $(objpfx)tst-%.out $(common-objpfx)malloc/mtrace $(objpfx)tst-$*.mtrace > $@; \ $(evaluate-test) +errlist-h = $(firstword $(wildcard $(addsuffix /errlist.h,$(sysdirs) .))) + +$(objpfx)tst-errno-manual.out: tst-errno-manual.py \ + $(errlist-h) \ + $(..)manual/errno.texi + $(PYTHON) tst-errno-manual.py -m $(..)manual/errno.texi \ + -e $(errlist-h) > $@; \ + $(evaluate-test) + CFLAGS-vfprintf.c += -Wno-uninitialized CFLAGS-vfwprintf.c += -Wno-uninitialized diff --git a/stdio-common/errlist-compat.c b/stdio-common/errlist-compat.c new file mode 100644 index 0000000000..6e25b021ab --- /dev/null +++ b/stdio-common/errlist-compat.c @@ -0,0 +1 @@ +/* Empty. */ diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c index 91fa789be0..df52356066 100644 --- a/stdio-common/errlist.c +++ b/stdio-common/errlist.c @@ -15,22 +15,24 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ +#include <stdio.h> +#include <errno.h> +#include <libintl.h> #include <array_length.h> -#include <stddef.h> -const char *const _sys_errlist[] = +const char *const _sys_errlist_internal[] = { - "Error 0", /* 0 */ - "Argument out of function's domain", /* 1 = EDOM */ - "Result out of range", /* 2 = ERANGE */ - "Operation not implemented", /* 3 = ENOSYS */ - "Invalid argument", /* 4 = EINVAL */ - "Illegal seek", /* 5 = ESPIPE */ - "Bad file descriptor", /* 6 = EBADF */ - "Cannot allocate memory", /* 7 = ENOMEM */ - "Permission denied", /* 8 = EACCES */ - "Too many open files in system", /* 9 = ENFILE */ - "Too many open files", /* 10 = EMFILE */ +#define _S(n, str) [n] = str, +#include <errlist.h> +#undef _S }; -const int _sys_nerr = array_length (_sys_errlist); +const char * +__get_errlist (int errnum) +{ + if (errnum >= 0 && errnum < array_length (_sys_errlist_internal)) + return _sys_errlist_internal[errnum]; + return NULL; +} + +#include <errlist-compat.c> diff --git a/stdio-common/tst-errno-manual.py b/stdio-common/tst-errno-manual.py new file mode 100755 index 0000000000..618120f4f0 --- /dev/null +++ b/stdio-common/tst-errno-manual.py @@ -0,0 +1,73 @@ +#!/usr/bin/python3 +# Check is all errno definitions at errlist.h documented in the manual. +# Copyright (C) 2020 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <https://www.gnu.org/licenses/>. + +import argparse +import sys +import re + +RE_MANUAL = re.compile( + r'(?:^@errno){(\w+)') + +RE_ERRLIST = re.compile( + r'\(E[a-zA-Z0-9]+\)') + +PASS=0 +FAIL=1 + +# Each manual entry is in the form: +# +# errno{EAGAIN, 35, Resource temporarily unavailable} +def parse_manual(f): + errlist = [RE_MANUAL.findall(s) for s in f] + return map(lambda x : x[0], filter(None, errlist)) + +# Each errlist entry is in the form: +# +# _S(ERR_MAP(EAGAIN), N_("Resource temporarily unavailable")) +def parse_errlist(f): + errlist = [RE_ERRLIST.findall(s) for s in f] + # Each element is '[]' or '['(EAGAIN)']' + return map(lambda s : s[0][s[0].find('(')+1:s[0].find(')')], + filter(None, errlist)) + +def check_errno_definitions(manual_fname, errlist_fname): + with open(manual_fname, 'r') as mfile, open(errlist_fname, 'r') as efile: + merr = parse_manual(mfile) + eerr = parse_errlist(efile) + diff = set(eerr).difference(merr) + if not diff: + sys.exit(PASS) + else: + print("Failure: the following value(s) are not in manual:", + ", ".join(str(e) for e in diff)) + sys.exit(FAIL) + +def main(): + parser = argparse.ArgumentParser(description='Generate errlist.h') + parser.add_argument('-m', dest='manual', metavar='FILE', + help='manual errno texi file') + parser.add_argument('-e', dest='errlist', metavar='FILE', + help='errlist with errno definitions') + args = parser.parse_args() + + check_errno_definitions(args.manual, args.errlist) + + +if __name__ == '__main__': + main() diff --git a/string/_strerror.c b/string/_strerror.c index af6be56fdc..01226e3d4b 100644 --- a/string/_strerror.c +++ b/string/_strerror.c @@ -36,8 +36,8 @@ char * __strerror_r (int errnum, char *buf, size_t buflen) { - if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal - || _sys_errlist_internal[errnum] == NULL, 0)) + char *err = (char *) __get_errlist (errnum); + if (__glibc_unlikely (err == NULL)) { /* Buffer we use to print the number in. For a maximum size for `int' of 8 bytes we never need more than 20 digits. */ @@ -68,7 +68,7 @@ __strerror_r (int errnum, char *buf, size_t buflen) return buf; } - return (char *) _(_sys_errlist_internal[errnum]); + return _(err); } weak_alias (__strerror_r, strerror_r) libc_hidden_def (__strerror_r) diff --git a/string/strerror_l.c b/string/strerror_l.c index c8c3d4a6ef..309f42e66b 100644 --- a/string/strerror_l.c +++ b/string/strerror_l.c @@ -40,10 +40,8 @@ translate (const char *str, locale_t loc) char * strerror_l (int errnum, locale_t loc) { - - - if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal - || _sys_errlist_internal[errnum] == NULL, 0)) + char *err = (char *) __get_errlist (errnum); + if (__glibc_unlikely (err == NULL)) { free (last_value); if (__asprintf (&last_value, "%s%d", @@ -53,7 +51,7 @@ strerror_l (int errnum, locale_t loc) return last_value; } - return (char *) translate (_sys_errlist_internal[errnum], loc); + return (char *) translate (err, loc); } void diff --git a/string/xpg-strerror.c b/string/xpg-strerror.c index 5290b63f18..95311b75e9 100644 --- a/string/xpg-strerror.c +++ b/string/xpg-strerror.c @@ -32,16 +32,9 @@ __xpg_strerror_r (int errnum, char *buf, size_t buflen) string) if errnum is invalid, otherwise it returns a string whose storage has indefinite extent. */ if (estr == buf) - { - assert (errnum < 0 || errnum >= _sys_nerr_internal - || _sys_errlist_internal[errnum] == NULL); - return EINVAL; - } + return EINVAL; else { - assert (errnum >= 0 && errnum < _sys_nerr_internal - && _sys_errlist_internal[errnum] != NULL); - size_t estrlen = strlen (estr); /* Terminate the string in any case. */ diff --git a/sysdeps/gnu/Makefile b/sysdeps/gnu/Makefile index 97fcb6fb90..9cf34c8ac6 100644 --- a/sysdeps/gnu/Makefile +++ b/sysdeps/gnu/Makefile @@ -15,49 +15,6 @@ # License along with the GNU C Library; if not, see # <https://www.gnu.org/licenses/>. -# Generate the list of strings for errno codes from the section of the -# manual which documents the codes. - -$(..)sysdeps/gnu/errlist.c: $(..)sysdeps/gnu/errlist.awk \ - $(..)manual/errno.texi - $(AWK) -f $^ > $@-tmp -# Make it unwritable so noone will edit it by mistake. - -chmod a-w $@-tmp - mv -f $@-tmp $@ - -ifeq ($(subdir),stdio-common) - -errlist-c = $(firstword $(wildcard $(addsuffix /errlist.c,$(sysdirs) .))) - -libof-errlist-compat = extramodules - -ifeq ($(build-shared),yes) -$(objpfx)errlist-compat.c: $(errlist-c) $(..)sysdeps/gnu/errlist-compat.awk \ - $(common-objpfx)Versions.v.i $(before-compile) -else -$(objpfx)errlist-compat.c: $(errlist-c) $(..)sysdeps/gnu/errlist-compat.awk \ - $(before-compile) -endif - $(make-target-directory) - $(AWK) -v maxerr=`\ - $(CC) -S $(CPPFLAGS) $(CFLAGS) -DEMIT_ERR_MAX $< -o - \ - | sed -n 's/^.*@@@[^0-9]*\([0-9]*\)[^0-9]*@@@.*$$/\1/p'` \ - -f $(..)sysdeps/gnu/errlist-compat.awk \ - $(wildcard $(sysdirs:=/Versions)) > $@T -# Make it unwritable so noone will edit it by mistake. - -chmod a-w $@T - mv -f $@T $@ -$(objpfx)errlist-compat.h: $(objpfx)errlist-compat.c - sed -n '1p;/ERR_MAX/p' $< > $@T - -chmod a-w $@T - mv -f $@T $@ -generated += errlist-compat.c errlist-compat.h - -# This will force the generation above to happy if need be. -$(foreach o,$(object-suffixes) $(object-suffixes:=.d),\ - $(objpfx)errlist$o): $(objpfx)errlist-compat.h -endif - ifeq ($(subdir),login) sysdep_routines += setutxent getutxent endutxent getutxid getutxline \ pututxline utmpxname updwtmpx getutmpx getutmp diff --git a/sysdeps/gnu/errlist-compat.awk b/sysdeps/gnu/errlist-compat.awk deleted file mode 100644 index 07334c63d8..0000000000 --- a/sysdeps/gnu/errlist-compat.awk +++ /dev/null @@ -1,133 +0,0 @@ -# awk script to generate errlist-compat.c -# Copyright (C) 2002-2020 Free Software Foundation, Inc. -# This file is part of the GNU C Library. - -# The GNU C Library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -# The GNU C Library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public -# License along with the GNU C Library; if not, see -# <https://www.gnu.org/licenses/>. - -# -# This script takes the Versions file as input and looks for #errlist-compat -# magic comments, which have the form: -# #errlist-compat NNN -# where NNN is the number of elements in the sys_errlist for that version set. -# We need the awk variable `maxerr' defined to the current size of sys_errlist. -# -# If there is no magic comment matching the current size, we barf. -# Otherwise we generate code (errlist-compat.c) to define all the -# necessary compatibility symbols for older, smaller versions of sys_errlist. -# - -# These two rules catch the Versions file contents. -NF == 2 && $2 == "{" { last_version = $1; next } -$1 == "#errlist-compat" { - # Don't process any further Versions files - ARGC = ARGIND + 1; - cnt = $2 + 0; - if (cnt < 80) { - print "*** this line seems bogus:", $0 > "/dev/stderr"; - exit 1; - } - version[pos + 0] = cnt SUBSEP last_version; - pos++; - if (cnt < highest) { - printf "*** %s #errlist-compat counts are not sorted\n", ARGV[ARGIND]; - exit 1; - } - if (cnt > highest) - highest = cnt; - highest_version = last_version; - next; -} - -END { - if (! highest_version) { - print "/* No sys_errlist/sys_nerr symbols defined on this platform. */"; - exit 0; - } - - count = maxerr + 1; - - if (highest < count) { - printf "*** errlist.c count %d vs Versions sys_errlist@%s count %d\n", \ - count, highest_version, highest > "/dev/stderr"; - exit 1; - } - - lastv = ""; - for (n = 0; n < pos; ++n) { - split(version[n], t, SUBSEP) - v = t[2]; - gsub(/[^A-Z0-9_]/, "_", v); - if (lastv != "") - compat[lastv] = v; - lastv = v; - vcount[v] = t[1]; - } - - print "/* This file was generated by errlist-compat.awk; DO NOT EDIT! */\n"; - print "#include <shlib-compat.h>\n"; - - if (highest > count) { - printf "*** errlist.c count %d inflated to %s count %d (old errno.h?)\n", \ - count, highest_version, highest > "/dev/stderr"; - printf "#def |
