[5/6] Make error_t an enumeration on all supported OSes.

Message ID 20170610171738.22362-6-zackw@panix.com
State Superseded
Headers

Commit Message

Zack Weinberg June 10, 2017, 5:17 p.m. UTC
  It occurred to me that by using a GCC 4.5 feature (pragma push_macro)
we could make error_t an enum on all supported OSes, without having
to stop using asm/errno.h on Linux.  bits/errno-enum.h is a generated
file that constructs the error_t enumeration from the macros.  This is
not possible without pragma push_macro, so errno.h falls back to using
'int' for error_t when the compiler feature is unavailable.  You
probably don't want to read the generated bits/errno-enum.h.

We could conceivably change __errno_location to return an error_t,
which would mean 'p errno' in GDB would print symbolic values without
needing to cast it, but I hesitate to make the apparent type of errno
not be 'int'.

	* scripts/make-errno-enum.sh: New script.
	* Makeconfig: Generate bits/errno-enum.h in before-compile phase.
	* stdlib/Makefile: Install bits/errno-enum.h.
	* stdlib/errno.h: Define error_t here, using bits/errno-enum.h when
	possible.

	* sysdeps/mach/hurd/errnos.awk: Do not define enum __errno_codes
	nor error_t.
	* sysdeps/mach/hurd/bits/errno.h: Regenerate.
---
 Makeconfig                     |  13 ++
 NEWS                           |   5 +
 scripts/make-errno-enum.sh     |  69 +++++++
 stdlib/Makefile                |   2 +-
 stdlib/errno.h                 |  11 +-
 sysdeps/mach/hurd/bits/errno.h | 458 +++++++++++------------------------------
 sysdeps/mach/hurd/errnos.awk   |  67 +-----
 7 files changed, 227 insertions(+), 398 deletions(-)
 create mode 100644 scripts/make-errno-enum.sh
  

Comments

Florian Weimer June 14, 2017, 11:08 a.m. UTC | #1
On 06/10/2017 07:17 PM, Zack Weinberg wrote:
> +printf '#include <features.h>\n#include <bits/errno.h>\n' |
> +    $CC -E -dM -xc -D_GNU_SOURCE -D_ERRNO_H "$@" - > "$tmp1"

I'm worried this fails to produce a header which is multi-arch-clean
(i.e., on x86-64, produce something which is compatible with x86-64,
i386, and x32).  Maybe the situation is better than with the system call
list; at least a cursory glimpse at the kernel sources suggests that
these headers don't have multi-arch preprocessor conditionals there.

It would be safer to have a built-in list of possible errno constant
names and generate a header from that, similar to what I did for the
system call names (but for which we failed to reach consensus).

Thanks,
Florian
  
Zack Weinberg June 14, 2017, 11:23 a.m. UTC | #2
On Wed, Jun 14, 2017 at 7:08 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 06/10/2017 07:17 PM, Zack Weinberg wrote:
>> +printf '#include <features.h>\n#include <bits/errno.h>\n' |
>> +    $CC -E -dM -xc -D_GNU_SOURCE -D_ERRNO_H "$@" - > "$tmp1"
>
> I'm worried this fails to produce a header which is multi-arch-clean
> (i.e., on x86-64, produce something which is compatible with x86-64,
> i386, and x32).  Maybe the situation is better than with the system call
> list; at least a cursory glimpse at the kernel sources suggests that
> these headers don't have multi-arch preprocessor conditionals there.

Hmm, yes.  Right now, at least on x86-64, the set of errno constant
*names* is consistent across all three subarchitectures, but there's
no guarantee of that.

> It would be safer to have a built-in list of possible errno constant
> names and generate a header from that, similar to what I did for the
> system call names (but for which we failed to reach consensus).

Come to think of it, we already have such a list - errnos.texi - and
it already has to be exhaustive, otherwise strerror() won't work for
all error numbers.  OK, I'll make that change.

zw
  
Zack Weinberg June 14, 2017, 12:24 p.m. UTC | #3
On Wed, Jun 14, 2017 at 7:23 AM, Zack Weinberg <zackw@panix.com> wrote:
> On Wed, Jun 14, 2017 at 7:08 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> It would be safer to have a built-in list of possible errno constant
>> names and generate a header from that, similar to what I did for the
>> system call names (but for which we failed to reach consensus).
>
> Come to think of it, we already have such a list - errnos.texi - and
> it already has to be exhaustive, otherwise strerror() won't work for
> all error numbers.  OK, I'll make that change.

This turns out not to work for the Hurd, which has a number of errors
that are copied from Mach kernel headers and not defined in
errnos.texi (see sysdeps/mach/hurd/bits/errno.h - the constants
beginning with EMACH_, EKERN_, EMIG_, and ED_).  These are already
problematic, strerror() doesn't work for them and some of them violate
the ISO C requirement for all error constants to be positive numbers,
but since error_t was invented for the Hurd in the first place, I'm
reluctant to drop their error codes out of their enum...  I suppose I
could invent some sort of hook for extending the list of errno
constant names in sysdeps, but does anyone have a better idea?

zw
  
Florian Weimer June 14, 2017, 1:04 p.m. UTC | #4
Zack Weinberg <zackw@panix.com> writes:

> On Wed, Jun 14, 2017 at 7:23 AM, Zack Weinberg <zackw@panix.com> wrote:
>> On Wed, Jun 14, 2017 at 7:08 AM, Florian Weimer <fweimer@redhat.com> wrote:
>>> It would be safer to have a built-in list of possible errno constant
>>> names and generate a header from that, similar to what I did for the
>>> system call names (but for which we failed to reach consensus).
>>
>> Come to think of it, we already have such a list - errnos.texi - and
>> it already has to be exhaustive, otherwise strerror() won't work for
>> all error numbers.  OK, I'll make that change.
>
> This turns out not to work for the Hurd, which has a number of errors
> that are copied from Mach kernel headers and not defined in
> errnos.texi (see sysdeps/mach/hurd/bits/errno.h - the constants
> beginning with EMACH_, EKERN_, EMIG_, and ED_).  These are already
> problematic, strerror() doesn't work for them and some of them violate
> the ISO C requirement for all error constants to be positive numbers,
> but since error_t was invented for the Hurd in the first place, I'm
> reluctant to drop their error codes out of their enum...  I suppose I
> could invent some sort of hook for extending the list of errno
> constant names in sysdeps, but does anyone have a better idea?

Realistically, your only chance is not to change the Hurd code at all
because we currently do not have a way to test it, do we?

So for Linux, you could come up with a separate mechanism and generate
error_t there.  But I have no concrete advice in that direction, sorry.

Thanks,
Florian
  
Florian Weimer June 14, 2017, 1:10 p.m. UTC | #5
Zack Weinberg <zackw@panix.com> writes:

> We could conceivably change __errno_location to return an error_t,
> which would mean 'p errno' in GDB would print symbolic values without
> needing to cast it, but I hesitate to make the apparent type of errno
> not be 'int'.

That sounds a bit hackish because I'm not sure int * and error_t * are
types with that level of compatibility.

You would get a long list of warnings from code like this:

  switch (errno)
    {
      case ENOSYS:
        ...
        break;
      case EINVAL:
        ...
        break;
    }

We might also run into problems if the kernel ever adds error constants
with values which change the representation of error_t.

Florian
  
Joseph Myers June 14, 2017, 1:44 p.m. UTC | #6
On Wed, 14 Jun 2017, Florian Weimer wrote:

> Zack Weinberg <zackw@panix.com> writes:
> 
> > We could conceivably change __errno_location to return an error_t,
> > which would mean 'p errno' in GDB would print symbolic values without
> > needing to cast it, but I hesitate to make the apparent type of errno
> > not be 'int'.
> 
> That sounds a bit hackish because I'm not sure int * and error_t * are
> types with that level of compatibility.

Type compatibility is not transitive, and errno is required to have type 
int.  Thus, if enum foo is an enum whose type is compatible with int 
(following the implementation-defined rules for what integer type an enum 
is compatible with), then _Generic (errno, enum foo: 0) is a valid C11 
expression, which would not be valid if errno had an enum type other than 
enum foo (two enum types compatible with the same integer type are not 
compatible with each other).

> We might also run into problems if the kernel ever adds error constants
> with values which change the representation of error_t.

If error_t is defined as an enum, I'd expect it to include INT_MIN and 
INT_MAX explicitly to ensure (in practice) that the underlying type is 
int.
  
Florian Weimer June 14, 2017, 1:57 p.m. UTC | #7
Joseph Myers <joseph@codesourcery.com> writes:

> On Wed, 14 Jun 2017, Florian Weimer wrote:
>
>> Zack Weinberg <zackw@panix.com> writes:
>> 
>> > We could conceivably change __errno_location to return an error_t,
>> > which would mean 'p errno' in GDB would print symbolic values without
>> > needing to cast it, but I hesitate to make the apparent type of errno
>> > not be 'int'.
>> 
>> That sounds a bit hackish because I'm not sure int * and error_t * are
>> types with that level of compatibility.
>
> Type compatibility is not transitive, and errno is required to have type 
> int.  Thus, if enum foo is an enum whose type is compatible with int 
> (following the implementation-defined rules for what integer type an enum 
> is compatible with), then _Generic (errno, enum foo: 0) is a valid C11 
> expression, which would not be valid if errno had an enum type other than 
> enum foo (two enum types compatible with the same integer type are not 
> compatible with each other).

Wow, interesting.

Perhaps a GDB plugin would be a better way to add this functionality?

Thanks,
Florian
  

Patch

diff --git a/Makeconfig b/Makeconfig
index 80aed2a987..a282b1f65a 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -1139,6 +1139,19 @@  $(common-objpfx)dl-tunable-list.stmp: \
 	touch $@
 endif
 
+# Build errno-enum.h early, ditto.
+before-compile += $(common-objpfx)bits/errno-enum.h
+common-generated += bits/error_t.h bits/errno-enum.stmp
+$(common-objpfx)bits/errno-enum.h: $(common-objpfx)bits/errno-enum.stmp; @:
+$(common-objpfx)bits/errno-enum.stmp: $(..)scripts/make-errno-enum.sh \
+				      bits/errno.h
+	[ -d $(common-objpfx)bits ] || mkdir $(common-objpfx)bits
+	CC="$(CC)" AWK="$(AWK)" \
+	    $(SHELL) $(..)scripts/make-errno-enum.sh $(+includes) \
+	    > ${@:stmp=T}
+	$(move-if-change) ${@:stmp=T} ${@:stmp=h}
+	touch $@
+
 # The name under which the run-time dynamic linker is installed.
 # We are currently going for the convention that `/lib/ld.so.1'
 # names the SVR4/ELF ABI-compliant dynamic linker.
diff --git a/NEWS b/NEWS
index 71a9ad6053..1b96b3897d 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,11 @@  Version 2.26
   supported operating systems.  In this context, it will only define the
   Exxxx constants, as preprocessor macros expanding to integer literals.
 
+* error_t, a debugging aid, is now available on all supported operating
+  systems for programs compiled with GCC 4.5 or higher.  'p (error_t) errno'
+  in GDB will print the Exxxx constant corresponding to the current value of
+  errno.
+
 * The rpcgen, librpcsvc and related headers will only be built and
   installed when glibc is configured with --enable-obsolete-rpc.
   This allows alternative RPC implementations, like TIRPC, to be used
diff --git a/scripts/make-errno-enum.sh b/scripts/make-errno-enum.sh
new file mode 100644
index 0000000000..30b00a5b42
--- /dev/null
+++ b/scripts/make-errno-enum.sh
@@ -0,0 +1,69 @@ 
+#! /bin/sh
+# Script to produce bits/error_t.h.
+
+# Copyright (C) 2017 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
+# <http://www.gnu.org/licenses/>.
+
+# This script is invoked with no input.
+# AWK and CC are expected to be set in the environment.
+# "$@" is expected to be a sequence of -I switches to pass to the compiler.
+# The generated error_t.h is written to stdout.
+
+set -e
+
+# Note: the steps below that may fail under normal circumstances are
+# carefully arranged to be at the ends of pipelines.
+tmp1=`mktemp -t me1.XXXXXXXXX`
+tmp2=`mktemp -t me2.XXXXXXXXX`
+trap "rm -f '$tmp1' '$tmp2'" 0
+
+# Note: the expansion of $CC should be word-split, as it may contain
+# command line switches (e.g. "gcc -m32 -march=i486").
+# We cannot include errno.h at this point because it will try to include
+# the file we haven't yet generated.
+printf '#include <features.h>\n#include <bits/errno.h>\n' |
+    $CC -E -dM -xc -D_GNU_SOURCE -D_ERRNO_H "$@" - > "$tmp1"
+
+LC_ALL=C sort -n -k3 < "$tmp1" | "$AWK" > "$tmp2" '
+  /^#define E[A-Z0-9][A-Z0-9_]* [^E]/ {
+    name = $2;
+    printf("\n#ifdef %s\n# pragma push_macro (\"%s\")\n# undef %s\n  %s =\n",
+           name, name, name, name);
+    printf("# pragma pop_macro (\"%s\")\n    %s,\n#endif\n",
+           name, name);
+  }
+'
+
+echo '/* Errno codes as enum constants.'
+echo '   This file was generated by make-errno-enum.sh from bits/errno.h.  */'
+echo
+echo '#ifndef _BITS_ERRNO_ENUM_H'
+echo '#define _BITS_ERRNO_ENUM_H 1'
+echo
+echo 'enum __error_t_codes'
+echo '{'
+echo '  /* Zero indicates success.  Including this entry may prevent'
+echo '     warnings from some compilers if "case 0" appears in a switch'
+echo '     statement over an error_t value.  */'
+echo '  ESUCCESS = 0,'
+cat "$tmp2"
+echo
+echo '  /* Force the enum to be a signed type.  */'
+echo '  __FORCE_ERROR_T_CODES_SIGNED = -1'
+echo '};'
+echo
+echo '#endif /* bits/errno-enum.h.  */'
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 9b0acce8cc..5e3d6e61ed 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -25,7 +25,7 @@  include ../Makeconfig
 headers	:= stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h      \
 	   monetary.h bits/monetary-ldbl.h				      \
 	   inttypes.h stdint.h bits/wordsize.h				      \
-	   errno.h sys/errno.h bits/errno.h				      \
+	   errno.h sys/errno.h bits/errno.h bits/errno-enum.h		      \
 	   ucontext.h sys/ucontext.h					      \
 	   alloca.h fmtmsg.h						      \
 	   bits/stdlib-bsearch.h sys/random.h bits/stdint-intn.h	      \
diff --git a/stdlib/errno.h b/stdlib/errno.h
index 118525c8fd..4514da4eb9 100644
--- a/stdlib/errno.h
+++ b/stdlib/errno.h
@@ -45,11 +45,18 @@  extern int *__errno_location (void) __THROW __attribute_const__;
 extern char *program_invocation_name;
 extern char *program_invocation_short_name;
 
-/* bits/errno.h may have defined this type.  If it didn't, provide a
-   fallback definition.  */
+/* The type error_t, a debugging aid.  With sufficiently new compilers
+   you can type 'p (error_t) errno' in GDB and see the symbolic name
+   of the errno value.  Also used to make the return value of certain
+   GNU extension functions more self-documenting.  */
 #   ifndef __error_t_defined
 #    define __error_t_defined 1
+#    if __GNUC_PREREQ (4, 5)
+#     include <bits/errno-enum.h>
+typedef enum __error_t_codes error_t;
+#     else
 typedef int error_t;
+#     endif
 #   endif
 
 #  endif /* __USE_GNU */
diff --git a/sysdeps/mach/hurd/bits/errno.h b/sysdeps/mach/hurd/bits/errno.h
index 8f3c210001..81e76be70d 100644
--- a/sysdeps/mach/hurd/bits/errno.h
+++ b/sysdeps/mach/hurd/bits/errno.h
@@ -13,323 +13,109 @@ 
 # error "Never include <bits/errno.h> directly; use <errno.h> instead."
 #endif
 
-#ifndef __ASSEMBLER__
-
-enum __error_t_codes
-{
-  /* The value zero always means success and it is perfectly fine
-     for code to use 0 explicitly (or implicitly, e.g. via Boolean
-     coercion.)  Having an enum entry for zero both makes the
-     debugger print the name for error_t-typed zero values, and
-     prevents the compiler from issuing warnings about 'case 0:'
-     in a switch on an error_t-typed value.  */
-  ESUCCESS                       = 0,
-
-  /* The Hurd uses Mach error system 0x10, subsystem 0. */
-  EPERM                          = 0x40000001,	/* Operation not permitted */
-  ENOENT                         = 0x40000002,	/* No such file or directory */
-  ESRCH                          = 0x40000003,	/* No such process */
-  EINTR                          = 0x40000004,	/* Interrupted system call */
-  EIO                            = 0x40000005,	/* Input/output error */
-  ENXIO                          = 0x40000006,	/* No such device or address */
-  E2BIG                          = 0x40000007,	/* Argument list too long */
-  ENOEXEC                        = 0x40000008,	/* Exec format error */
-  EBADF                          = 0x40000009,	/* Bad file descriptor */
-  ECHILD                         = 0x4000000a,	/* No child processes */
-  EDEADLK                        = 0x4000000b,	/* Resource deadlock avoided */
-  ENOMEM                         = 0x4000000c,	/* Cannot allocate memory */
-  EACCES                         = 0x4000000d,	/* Permission denied */
-  EFAULT                         = 0x4000000e,	/* Bad address */
-  ENOTBLK                        = 0x4000000f,	/* Block device required */
-  EBUSY                          = 0x40000010,	/* Device or resource busy */
-  EEXIST                         = 0x40000011,	/* File exists */
-  EXDEV                          = 0x40000012,	/* Invalid cross-device link */
-  ENODEV                         = 0x40000013,	/* No such device */
-  ENOTDIR                        = 0x40000014,	/* Not a directory */
-  EISDIR                         = 0x40000015,	/* Is a directory */
-  EINVAL                         = 0x40000016,	/* Invalid argument */
-  EMFILE                         = 0x40000018,	/* Too many open files */
-  ENFILE                         = 0x40000017,	/* Too many open files in system */
-  ENOTTY                         = 0x40000019,	/* Inappropriate ioctl for device */
-  ETXTBSY                        = 0x4000001a,	/* Text file busy */
-  EFBIG                          = 0x4000001b,	/* File too large */
-  ENOSPC                         = 0x4000001c,	/* No space left on device */
-  ESPIPE                         = 0x4000001d,	/* Illegal seek */
-  EROFS                          = 0x4000001e,	/* Read-only file system */
-  EMLINK                         = 0x4000001f,	/* Too many links */
-  EPIPE                          = 0x40000020,	/* Broken pipe */
-  EDOM                           = 0x40000021,	/* Numerical argument out of domain */
-  ERANGE                         = 0x40000022,	/* Numerical result out of range */
-  EAGAIN                         = 0x40000023,	/* Resource temporarily unavailable */
-  EINPROGRESS                    = 0x40000024,	/* Operation now in progress */
-  EALREADY                       = 0x40000025,	/* Operation already in progress */
-  ENOTSOCK                       = 0x40000026,	/* Socket operation on non-socket */
-  EMSGSIZE                       = 0x40000028,	/* Message too long */
-  EPROTOTYPE                     = 0x40000029,	/* Protocol wrong type for socket */
-  ENOPROTOOPT                    = 0x4000002a,	/* Protocol not available */
-  EPROTONOSUPPORT                = 0x4000002b,	/* Protocol not supported */
-  ESOCKTNOSUPPORT                = 0x4000002c,	/* Socket type not supported */
-  EOPNOTSUPP                     = 0x4000002d,	/* Operation not supported */
-  EPFNOSUPPORT                   = 0x4000002e,	/* Protocol family not supported */
-  EAFNOSUPPORT                   = 0x4000002f,	/* Address family not supported by protocol */
-  EADDRINUSE                     = 0x40000030,	/* Address already in use */
-  EADDRNOTAVAIL                  = 0x40000031,	/* Cannot assign requested address */
-  ENETDOWN                       = 0x40000032,	/* Network is down */
-  ENETUNREACH                    = 0x40000033,	/* Network is unreachable */
-  ENETRESET                      = 0x40000034,	/* Network dropped connection on reset */
-  ECONNABORTED                   = 0x40000035,	/* Software caused connection abort */
-  ECONNRESET                     = 0x40000036,	/* Connection reset by peer */
-  ENOBUFS                        = 0x40000037,	/* No buffer space available */
-  EISCONN                        = 0x40000038,	/* Transport endpoint is already connected */
-  ENOTCONN                       = 0x40000039,	/* Transport endpoint is not connected */
-  EDESTADDRREQ                   = 0x40000027,	/* Destination address required */
-  ESHUTDOWN                      = 0x4000003a,	/* Cannot send after transport endpoint shutdown */
-  ETOOMANYREFS                   = 0x4000003b,	/* Too many references: cannot splice */
-  ETIMEDOUT                      = 0x4000003c,	/* Connection timed out */
-  ECONNREFUSED                   = 0x4000003d,	/* Connection refused */
-  ELOOP                          = 0x4000003e,	/* Too many levels of symbolic links */
-  ENAMETOOLONG                   = 0x4000003f,	/* File name too long */
-  EHOSTDOWN                      = 0x40000040,	/* Host is down */
-  EHOSTUNREACH                   = 0x40000041,	/* No route to host */
-  ENOTEMPTY                      = 0x40000042,	/* Directory not empty */
-  EPROCLIM                       = 0x40000043,	/* Too many processes */
-  EUSERS                         = 0x40000044,	/* Too many users */
-  EDQUOT                         = 0x40000045,	/* Disk quota exceeded */
-  ESTALE                         = 0x40000046,	/* Stale file handle */
-  EREMOTE                        = 0x40000047,	/* Object is remote */
-  EBADRPC                        = 0x40000048,	/* RPC struct is bad */
-  ERPCMISMATCH                   = 0x40000049,	/* RPC version wrong */
-  EPROGUNAVAIL                   = 0x4000004a,	/* RPC program not available */
-  EPROGMISMATCH                  = 0x4000004b,	/* RPC program version wrong */
-  EPROCUNAVAIL                   = 0x4000004c,	/* RPC bad procedure for program */
-  ENOLCK                         = 0x4000004d,	/* No locks available */
-  EFTYPE                         = 0x4000004f,	/* Inappropriate file type or format */
-  EAUTH                          = 0x40000050,	/* Authentication error */
-  ENEEDAUTH                      = 0x40000051,	/* Need authenticator */
-  ENOSYS                         = 0x4000004e,	/* Function not implemented */
-  ENOTSUP                        = 0x40000076,	/* Not supported */
-  EILSEQ                         = 0x4000006a,	/* Invalid or incomplete multibyte or wide character */
-  EBACKGROUND                    = 0x40000064,	/* Inappropriate operation for background process */
-  EDIED                          = 0x40000065,	/* Translator died */
-  ED                             = 0x40000066,	/* ? */
-  EGREGIOUS                      = 0x40000067,	/* You really blew it this time */
-  EIEIO                          = 0x40000068,	/* Computer bought the farm */
-  EGRATUITOUS                    = 0x40000069,	/* Gratuitous error */
-  EBADMSG                        = 0x4000006b,	/* Bad message */
-  EIDRM                          = 0x4000006c,	/* Identifier removed */
-  EMULTIHOP                      = 0x4000006d,	/* Multihop attempted */
-  ENODATA                        = 0x4000006e,	/* No data available */
-  ENOLINK                        = 0x4000006f,	/* Link has been severed */
-  ENOMSG                         = 0x40000070,	/* No message of desired type */
-  ENOSR                          = 0x40000071,	/* Out of streams resources */
-  ENOSTR                         = 0x40000072,	/* Device not a stream */
-  EOVERFLOW                      = 0x40000073,	/* Value too large for defined data type */
-  EPROTO                         = 0x40000074,	/* Protocol error */
-  ETIME                          = 0x40000075,	/* Timer expired */
-  ECANCELED                      = 0x40000077,	/* Operation canceled */
-  
-/* Errors from <mach/message.h>.  */
-  EMACH_SEND_IN_PROGRESS         = 0x10000001,
-  EMACH_SEND_INVALID_DATA        = 0x10000002,
-  EMACH_SEND_INVALID_DEST        = 0x10000003,
-  EMACH_SEND_TIMED_OUT           = 0x10000004,
-  EMACH_SEND_WILL_NOTIFY         = 0x10000005,
-  EMACH_SEND_NOTIFY_IN_PROGRESS  = 0x10000006,
-  EMACH_SEND_INTERRUPTED         = 0x10000007,
-  EMACH_SEND_MSG_TOO_SMALL       = 0x10000008,
-  EMACH_SEND_INVALID_REPLY       = 0x10000009,
-  EMACH_SEND_INVALID_RIGHT       = 0x1000000a,
-  EMACH_SEND_INVALID_NOTIFY      = 0x1000000b,
-  EMACH_SEND_INVALID_MEMORY      = 0x1000000c,
-  EMACH_SEND_NO_BUFFER           = 0x1000000d,
-  EMACH_SEND_NO_NOTIFY           = 0x1000000e,
-  EMACH_SEND_INVALID_TYPE        = 0x1000000f,
-  EMACH_SEND_INVALID_HEADER      = 0x10000010,
-  EMACH_RCV_IN_PROGRESS          = 0x10004001,
-  EMACH_RCV_INVALID_NAME         = 0x10004002,
-  EMACH_RCV_TIMED_OUT            = 0x10004003,
-  EMACH_RCV_TOO_LARGE            = 0x10004004,
-  EMACH_RCV_INTERRUPTED          = 0x10004005,
-  EMACH_RCV_PORT_CHANGED         = 0x10004006,
-  EMACH_RCV_INVALID_NOTIFY       = 0x10004007,
-  EMACH_RCV_INVALID_DATA         = 0x10004008,
-  EMACH_RCV_PORT_DIED            = 0x10004009,
-  EMACH_RCV_IN_SET               = 0x1000400a,
-  EMACH_RCV_HEADER_ERROR         = 0x1000400b,
-  EMACH_RCV_BODY_ERROR           = 0x1000400c,
-  
-/* Errors from <mach/kern_return.h>.  */
-  EKERN_INVALID_ADDRESS          = 1,
-  EKERN_PROTECTION_FAILURE       = 2,
-  EKERN_NO_SPACE                 = 3,
-  EKERN_INVALID_ARGUMENT         = 4,
-  EKERN_FAILURE                  = 5,
-  EKERN_RESOURCE_SHORTAGE        = 6,
-  EKERN_NOT_RECEIVER             = 7,
-  EKERN_NO_ACCESS                = 8,
-  EKERN_MEMORY_FAILURE           = 9,
-  EKERN_MEMORY_ERROR             = 10,
-  EKERN_NOT_IN_SET               = 12,
-  EKERN_NAME_EXISTS              = 13,
-  EKERN_ABORTED                  = 14,
-  EKERN_INVALID_NAME             = 15,
-  EKERN_INVALID_TASK             = 16,
-  EKERN_INVALID_RIGHT            = 17,
-  EKERN_INVALID_VALUE            = 18,
-  EKERN_UREFS_OVERFLOW           = 19,
-  EKERN_INVALID_CAPABILITY       = 20,
-  EKERN_RIGHT_EXISTS             = 21,
-  EKERN_INVALID_HOST             = 22,
-  EKERN_MEMORY_PRESENT           = 23,
-  EKERN_WRITE_PROTECTION_FAILURE = 24,
-  EKERN_TERMINATED               = 26,
-  EKERN_TIMEDOUT                 = 27,
-  EKERN_INTERRUPTED              = 28,
-  
-/* Errors from <mach/mig_errors.h>.  */
-  EMIG_TYPE_ERROR                = -300,	/* client type check failure */
-  EMIG_REPLY_MISMATCH            = -301,	/* wrong reply message ID */
-  EMIG_REMOTE_ERROR              = -302,	/* server detected error */
-  EMIG_BAD_ID                    = -303,	/* bad request message ID */
-  EMIG_BAD_ARGUMENTS             = -304,	/* server type check failure */
-  EMIG_NO_REPLY                  = -305,	/* no reply should be sent */
-  EMIG_EXCEPTION                 = -306,	/* server raised exception */
-  EMIG_ARRAY_TOO_LARGE           = -307,	/* array not large enough */
-  EMIG_SERVER_DIED               = -308,	/* server died */
-  EMIG_DESTROY_REQUEST           = -309,	/* destroy request with no reply */
-  
-/* Errors from <device/device_types.h>.  */
-  ED_IO_ERROR                    = 2500,	/* hardware IO error */
-  ED_WOULD_BLOCK                 = 2501,	/* would block, but D_NOWAIT set */
-  ED_NO_SUCH_DEVICE              = 2502,	/* no such device */
-  ED_ALREADY_OPEN                = 2503,	/* exclusive-use device already open */
-  ED_DEVICE_DOWN                 = 2504,	/* device has been shut down */
-  ED_INVALID_OPERATION           = 2505,	/* bad operation for device */
-  ED_INVALID_RECNUM              = 2506,	/* invalid record (block) number */
-  ED_INVALID_SIZE                = 2507,	/* invalid IO size */
-  ED_NO_MEMORY                   = 2508,	/* memory allocation failure */
-  ED_READ_ONLY                   = 2509,	/* device cannot be written to */
-
-  /* Because the C standard requires that errno have type 'int',
-     this enumeration must be a signed type.  */
-  __FORCE_ERROR_T_CODES_SIGNED = -1
-};
-
-/* User-visible type of error codes.  It is ok to use 'int' or
-   'kern_return_t' for these, but with 'error_t' the debugger prints
-   symbolic values.  */
-# if !defined __error_t_defined && defined __USE_GNU
-#  define __error_t_defined 1
-typedef enum __error_t_codes error_t;
-# endif
-
-#endif /* not __ASSEMBLER__ */
-
-/* The C standard requires that all of the E-constants be
-   defined as macros.  */
-
-#define EPERM                          0x40000001
-#define ENOENT                         0x40000002
-#define ESRCH                          0x40000003
-#define EINTR                          0x40000004
-#define EIO                            0x40000005
-#define ENXIO                          0x40000006
-#define E2BIG                          0x40000007
-#define ENOEXEC                        0x40000008
-#define EBADF                          0x40000009
-#define ECHILD                         0x4000000a
-#define EDEADLK                        0x4000000b
-#define ENOMEM                         0x4000000c
-#define EACCES                         0x4000000d
-#define EFAULT                         0x4000000e
-#define ENOTBLK                        0x4000000f
-#define EBUSY                          0x40000010
-#define EEXIST                         0x40000011
-#define EXDEV                          0x40000012
-#define ENODEV                         0x40000013
-#define ENOTDIR                        0x40000014
-#define EISDIR                         0x40000015
-#define EINVAL                         0x40000016
-#define EMFILE                         0x40000018
-#define ENFILE                         0x40000017
-#define ENOTTY                         0x40000019
-#define ETXTBSY                        0x4000001a
-#define EFBIG                          0x4000001b
-#define ENOSPC                         0x4000001c
-#define ESPIPE                         0x4000001d
-#define EROFS                          0x4000001e
-#define EMLINK                         0x4000001f
-#define EPIPE                          0x40000020
-#define EDOM                           0x40000021
-#define ERANGE                         0x40000022
-#define EAGAIN                         0x40000023
+/* The Hurd uses Mach error system 0x10, subsystem 0.  */
+#define EPERM                          0x40000001	/* Operation not permitted */
+#define ENOENT                         0x40000002	/* No such file or directory */
+#define ESRCH                          0x40000003	/* No such process */
+#define EINTR                          0x40000004	/* Interrupted system call */
+#define EIO                            0x40000005	/* Input/output error */
+#define ENXIO                          0x40000006	/* No such device or address */
+#define E2BIG                          0x40000007	/* Argument list too long */
+#define ENOEXEC                        0x40000008	/* Exec format error */
+#define EBADF                          0x40000009	/* Bad file descriptor */
+#define ECHILD                         0x4000000a	/* No child processes */
+#define EDEADLK                        0x4000000b	/* Resource deadlock avoided */
+#define ENOMEM                         0x4000000c	/* Cannot allocate memory */
+#define EACCES                         0x4000000d	/* Permission denied */
+#define EFAULT                         0x4000000e	/* Bad address */
+#define ENOTBLK                        0x4000000f	/* Block device required */
+#define EBUSY                          0x40000010	/* Device or resource busy */
+#define EEXIST                         0x40000011	/* File exists */
+#define EXDEV                          0x40000012	/* Invalid cross-device link */
+#define ENODEV                         0x40000013	/* No such device */
+#define ENOTDIR                        0x40000014	/* Not a directory */
+#define EISDIR                         0x40000015	/* Is a directory */
+#define EINVAL                         0x40000016	/* Invalid argument */
+#define EMFILE                         0x40000018	/* Too many open files */
+#define ENFILE                         0x40000017	/* Too many open files in system */
+#define ENOTTY                         0x40000019	/* Inappropriate ioctl for device */
+#define ETXTBSY                        0x4000001a	/* Text file busy */
+#define EFBIG                          0x4000001b	/* File too large */
+#define ENOSPC                         0x4000001c	/* No space left on device */
+#define ESPIPE                         0x4000001d	/* Illegal seek */
+#define EROFS                          0x4000001e	/* Read-only file system */
+#define EMLINK                         0x4000001f	/* Too many links */
+#define EPIPE                          0x40000020	/* Broken pipe */
+#define EDOM                           0x40000021	/* Numerical argument out of domain */
+#define ERANGE                         0x40000022	/* Numerical result out of range */
+#define EAGAIN                         0x40000023	/* Resource temporarily unavailable */
 #define EWOULDBLOCK                    EAGAIN
-#define EINPROGRESS                    0x40000024
-#define EALREADY                       0x40000025
-#define ENOTSOCK                       0x40000026
-#define EMSGSIZE                       0x40000028
-#define EPROTOTYPE                     0x40000029
-#define ENOPROTOOPT                    0x4000002a
-#define EPROTONOSUPPORT                0x4000002b
-#define ESOCKTNOSUPPORT                0x4000002c
-#define EOPNOTSUPP                     0x4000002d
-#define EPFNOSUPPORT                   0x4000002e
-#define EAFNOSUPPORT                   0x4000002f
-#define EADDRINUSE                     0x40000030
-#define EADDRNOTAVAIL                  0x40000031
-#define ENETDOWN                       0x40000032
-#define ENETUNREACH                    0x40000033
-#define ENETRESET                      0x40000034
-#define ECONNABORTED                   0x40000035
-#define ECONNRESET                     0x40000036
-#define ENOBUFS                        0x40000037
-#define EISCONN                        0x40000038
-#define ENOTCONN                       0x40000039
-#define EDESTADDRREQ                   0x40000027
-#define ESHUTDOWN                      0x4000003a
-#define ETOOMANYREFS                   0x4000003b
-#define ETIMEDOUT                      0x4000003c
-#define ECONNREFUSED                   0x4000003d
-#define ELOOP                          0x4000003e
-#define ENAMETOOLONG                   0x4000003f
-#define EHOSTDOWN                      0x40000040
-#define EHOSTUNREACH                   0x40000041
-#define ENOTEMPTY                      0x40000042
-#define EPROCLIM                       0x40000043
-#define EUSERS                         0x40000044
-#define EDQUOT                         0x40000045
-#define ESTALE                         0x40000046
-#define EREMOTE                        0x40000047
-#define EBADRPC                        0x40000048
-#define ERPCMISMATCH                   0x40000049
-#define EPROGUNAVAIL                   0x4000004a
-#define EPROGMISMATCH                  0x4000004b
-#define EPROCUNAVAIL                   0x4000004c
-#define ENOLCK                         0x4000004d
-#define EFTYPE                         0x4000004f
-#define EAUTH                          0x40000050
-#define ENEEDAUTH                      0x40000051
-#define ENOSYS                         0x4000004e
-#define ENOTSUP                        0x40000076
-#define EILSEQ                         0x4000006a
-#define EBACKGROUND                    0x40000064
-#define EDIED                          0x40000065
-#define ED                             0x40000066
-#define EGREGIOUS                      0x40000067
-#define EIEIO                          0x40000068
-#define EGRATUITOUS                    0x40000069
-#define EBADMSG                        0x4000006b
-#define EIDRM                          0x4000006c
-#define EMULTIHOP                      0x4000006d
-#define ENODATA                        0x4000006e
-#define ENOLINK                        0x4000006f
-#define ENOMSG                         0x40000070
-#define ENOSR                          0x40000071
-#define ENOSTR                         0x40000072
-#define EOVERFLOW                      0x40000073
-#define EPROTO                         0x40000074
-#define ETIME                          0x40000075
-#define ECANCELED                      0x40000077
+#define EINPROGRESS                    0x40000024	/* Operation now in progress */
+#define EALREADY                       0x40000025	/* Operation already in progress */
+#define ENOTSOCK                       0x40000026	/* Socket operation on non-socket */
+#define EMSGSIZE                       0x40000028	/* Message too long */
+#define EPROTOTYPE                     0x40000029	/* Protocol wrong type for socket */
+#define ENOPROTOOPT                    0x4000002a	/* Protocol not available */
+#define EPROTONOSUPPORT                0x4000002b	/* Protocol not supported */
+#define ESOCKTNOSUPPORT                0x4000002c	/* Socket type not supported */
+#define EOPNOTSUPP                     0x4000002d	/* Operation not supported */
+#define EPFNOSUPPORT                   0x4000002e	/* Protocol family not supported */
+#define EAFNOSUPPORT                   0x4000002f	/* Address family not supported by protocol */
+#define EADDRINUSE                     0x40000030	/* Address already in use */
+#define EADDRNOTAVAIL                  0x40000031	/* Cannot assign requested address */
+#define ENETDOWN                       0x40000032	/* Network is down */
+#define ENETUNREACH                    0x40000033	/* Network is unreachable */
+#define ENETRESET                      0x40000034	/* Network dropped connection on reset */
+#define ECONNABORTED                   0x40000035	/* Software caused connection abort */
+#define ECONNRESET                     0x40000036	/* Connection reset by peer */
+#define ENOBUFS                        0x40000037	/* No buffer space available */
+#define EISCONN                        0x40000038	/* Transport endpoint is already connected */
+#define ENOTCONN                       0x40000039	/* Transport endpoint is not connected */
+#define EDESTADDRREQ                   0x40000027	/* Destination address required */
+#define ESHUTDOWN                      0x4000003a	/* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS                   0x4000003b	/* Too many references: cannot splice */
+#define ETIMEDOUT                      0x4000003c	/* Connection timed out */
+#define ECONNREFUSED                   0x4000003d	/* Connection refused */
+#define ELOOP                          0x4000003e	/* Too many levels of symbolic links */
+#define ENAMETOOLONG                   0x4000003f	/* File name too long */
+#define EHOSTDOWN                      0x40000040	/* Host is down */
+#define EHOSTUNREACH                   0x40000041	/* No route to host */
+#define ENOTEMPTY                      0x40000042	/* Directory not empty */
+#define EPROCLIM                       0x40000043	/* Too many processes */
+#define EUSERS                         0x40000044	/* Too many users */
+#define EDQUOT                         0x40000045	/* Disk quota exceeded */
+#define ESTALE                         0x40000046	/* Stale file handle */
+#define EREMOTE                        0x40000047	/* Object is remote */
+#define EBADRPC                        0x40000048	/* RPC struct is bad */
+#define ERPCMISMATCH                   0x40000049	/* RPC version wrong */
+#define EPROGUNAVAIL                   0x4000004a	/* RPC program not available */
+#define EPROGMISMATCH                  0x4000004b	/* RPC program version wrong */
+#define EPROCUNAVAIL                   0x4000004c	/* RPC bad procedure for program */
+#define ENOLCK                         0x4000004d	/* No locks available */
+#define EFTYPE                         0x4000004f	/* Inappropriate file type or format */
+#define EAUTH                          0x40000050	/* Authentication error */
+#define ENEEDAUTH                      0x40000051	/* Need authenticator */
+#define ENOSYS                         0x4000004e	/* Function not implemented */
+#define ENOTSUP                        0x40000076	/* Not supported */
+#define EILSEQ                         0x4000006a	/* Invalid or incomplete multibyte or wide character */
+#define EBACKGROUND                    0x40000064	/* Inappropriate operation for background process */
+#define EDIED                          0x40000065	/* Translator died */
+#define ED                             0x40000066	/* ? */
+#define EGREGIOUS                      0x40000067	/* You really blew it this time */
+#define EIEIO                          0x40000068	/* Computer bought the farm */
+#define EGRATUITOUS                    0x40000069	/* Gratuitous error */
+#define EBADMSG                        0x4000006b	/* Bad message */
+#define EIDRM                          0x4000006c	/* Identifier removed */
+#define EMULTIHOP                      0x4000006d	/* Multihop attempted */
+#define ENODATA                        0x4000006e	/* No data available */
+#define ENOLINK                        0x4000006f	/* Link has been severed */
+#define ENOMSG                         0x40000070	/* No message of desired type */
+#define ENOSR                          0x40000071	/* Out of streams resources */
+#define ENOSTR                         0x40000072	/* Device not a stream */
+#define EOVERFLOW                      0x40000073	/* Value too large for defined data type */
+#define EPROTO                         0x40000074	/* Protocol error */
+#define ETIME                          0x40000075	/* Timer expired */
+#define ECANCELED                      0x40000077	/* Operation canceled */
 
 /* Errors from <mach/message.h>.  */
 #define EMACH_SEND_IN_PROGRESS         0x10000001
@@ -390,28 +176,28 @@  typedef enum __error_t_codes error_t;
 #define EKERN_INTERRUPTED              28
 
 /* Errors from <mach/mig_errors.h>.  */
-#define EMIG_TYPE_ERROR                -300
-#define EMIG_REPLY_MISMATCH            -301
-#define EMIG_REMOTE_ERROR              -302
-#define EMIG_BAD_ID                    -303
-#define EMIG_BAD_ARGUMENTS             -304
-#define EMIG_NO_REPLY                  -305
-#define EMIG_EXCEPTION                 -306
-#define EMIG_ARRAY_TOO_LARGE           -307
-#define EMIG_SERVER_DIED               -308
-#define EMIG_DESTROY_REQUEST           -309
+#define EMIG_TYPE_ERROR                -300	/* client type check failure */
+#define EMIG_REPLY_MISMATCH            -301	/* wrong reply message ID */
+#define EMIG_REMOTE_ERROR              -302	/* server detected error */
+#define EMIG_BAD_ID                    -303	/* bad request message ID */
+#define EMIG_BAD_ARGUMENTS             -304	/* server type check failure */
+#define EMIG_NO_REPLY                  -305	/* no reply should be sent */
+#define EMIG_EXCEPTION                 -306	/* server raised exception */
+#define EMIG_ARRAY_TOO_LARGE           -307	/* array not large enough */
+#define EMIG_SERVER_DIED               -308	/* server died */
+#define EMIG_DESTROY_REQUEST           -309	/* destroy request with no reply */
 
 /* Errors from <device/device_types.h>.  */
-#define ED_IO_ERROR                    2500
-#define ED_WOULD_BLOCK                 2501
-#define ED_NO_SUCH_DEVICE              2502
-#define ED_ALREADY_OPEN                2503
-#define ED_DEVICE_DOWN                 2504
-#define ED_INVALID_OPERATION           2505
-#define ED_INVALID_RECNUM              2506
-#define ED_INVALID_SIZE                2507
-#define ED_NO_MEMORY                   2508
-#define ED_READ_ONLY                   2509
+#define ED_IO_ERROR                    2500	/* hardware IO error */
+#define ED_WOULD_BLOCK                 2501	/* would block, but D_NOWAIT set */
+#define ED_NO_SUCH_DEVICE              2502	/* no such device */
+#define ED_ALREADY_OPEN                2503	/* exclusive-use device already open */
+#define ED_DEVICE_DOWN                 2504	/* device has been shut down */
+#define ED_INVALID_OPERATION           2505	/* bad operation for device */
+#define ED_INVALID_RECNUM              2506	/* invalid record (block) number */
+#define ED_INVALID_SIZE                2507	/* invalid IO size */
+#define ED_NO_MEMORY                   2508	/* memory allocation failure */
+#define ED_READ_ONLY                   2509	/* device cannot be written to */
 
 #define _HURD_ERRNOS 120
 
diff --git a/sysdeps/mach/hurd/errnos.awk b/sysdeps/mach/hurd/errnos.awk
index d1ed8c4877..daf2943c83 100644
--- a/sysdeps/mach/hurd/errnos.awk
+++ b/sysdeps/mach/hurd/errnos.awk
@@ -147,73 +147,22 @@  in_device_errors && $1 == "#endif" \
     in_device_errors = 0;
   }
 
-function print_errno_enum(maxseq)
+END \
 {
   print "";
-  print "#ifndef __ASSEMBLER__";
-  print "";
-  print "enum __error_t_codes";
-  print "{";
-  print "  /* The value zero always means success and it is perfectly fine";
-  print "     for code to use 0 explicitly (or implicitly, e.g. via Boolean";
-  print "     coercion.)  Having an enum entry for zero both makes the";
-  print "     debugger print the name for error_t-typed zero values, and";
-  print "     prevents the compiler from issuing warnings about 'case 0:'";
-  print "     in a switch on an error_t-typed value.  */";
-  printf("  %-*s = 0,\n", maxerrlen, "ESUCCESS");
-
-  print "";
-  print "  /* The Hurd uses Mach error system 0x10, subsystem 0. */";
-  for (i = 0; i < maxseq; i++)
-    {
-      if (i in annot)
-	print "  " annot[i];
-      else if (i in etexts && etexts[i] != "")
-	printf("  %-*s = %s,\t/* %s */\n",
-	       maxerrlen, econsts[i], errnos[i], etexts[i]);
-      else if (errnos[i] != "EAGAIN")
-	printf("  %-*s = %s,\n", maxerrlen, econsts[i], errnos[i]);
-    }
-
-  print "";
-  print "  /* Because the C standard requires that errno have type 'int',"
-  print "     this enumeration must be a signed type.  */";
-  print "  __FORCE_ERROR_T_CODES_SIGNED = -1";
-  print "};";
-  print "";
-  print "/* User-visible type of error codes.  It is ok to use 'int' or";
-  print "   'kern_return_t' for these, but with 'error_t' the debugger prints";
-  print "   symbolic values.  */";
-  print "# if !defined __error_t_defined && defined __USE_GNU";
-  print "#  define __error_t_defined 1";
-  print "typedef enum __error_t_codes error_t;"
-  print "# endif";
-  print "";
-  print "#endif /* not __ASSEMBLER__ */";
-}
-
-function print_errno_defines(maxseq)
-{
-  print "";
-  print "/* The C standard requires that all of the E-constants be"
-  print "   defined as macros.  */"
-  print "";
-  for (i = 0; i < maxseq; i++)
+  print "/* The Hurd uses Mach error system 0x10, subsystem 0.  */";
+  for (i = 0; i < seq; i++)
     {
       if (i in annot)
 	print annot[i];
+      else if (i in etexts && etexts[i] != "")
+	printf("#define %-*s %s\t/* %s */\n",
+	       maxerrlen, econsts[i], errnos[i], etexts[i]);
       else
 	printf("#define %-*s %s\n", maxerrlen, econsts[i], errnos[i]);
     }
   print "";
   printf("#define _HURD_ERRNOS %d\n", maxerrno+1);
+  print "";
+  print "#endif /* bits/errno.h.  */";
 }
-
-END \
-  {
-    print_errno_enum(seq);
-    print_errno_defines(seq);
-
-    print "";
-    print "#endif /* bits/errno.h.  */";
-  }