diff -Naur glibc-2.3.6.orig/hurd/Makefile glibc-2.3.6.new/hurd/Makefile
--- glibc-2.3.6.orig/hurd/Makefile	2002-10-14 02:03:09.000000000 +0100
+++ glibc-2.3.6.new/hurd/Makefile	2006-05-06 12:34:35.337052152 +0100
@@ -60,6 +60,7 @@
 	   vpprintf \
 	   ports-get ports-set hurdports hurdmsg \
 	   errno-loc \
+	   sysvshm \
 	   $(sig) $(dtable) $(inlines) port-cleanup report-wait
 sig	= hurdsig hurdfault siginfo hurd-raise preempt-sig \
 	  trampoline longjmp-ts catch-exc exc2signal hurdkill sigunwind \
@@ -68,7 +69,7 @@
 	  getdport openport \
 	  fd-close fd-read fd-write hurdioctl ctty-input ctty-output
 inlines = $(inline-headers:%.h=%-inlines)
-distribute = hurdstartup.h hurdfault.h hurdhost.h \
+distribute = hurdstartup.h hurdfault.h hurdhost.h sysvshm.h \
 	     faultexc.defs intr-rpc.defs intr-rpc.h intr-msg.h Notes
 
 # XXX this is a temporary hack; see hurdmalloc.h
diff -Naur glibc-2.3.6.orig/hurd/sysvshm.c glibc-2.3.6.new/hurd/sysvshm.c
--- glibc-2.3.6.orig/hurd/sysvshm.c	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/hurd/sysvshm.c	2006-05-06 12:34:35.338052000 +0100
@@ -0,0 +1,96 @@
+/* Copyright (C) 2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/shm.h>
+
+
+/* Description of an shm attachment.  */
+struct sysvshm_attach
+{
+  /* Linked list.  */
+  struct sysvshm_attach *next;
+
+  /* Map address.  */
+  void *addr;
+
+  /* Map size.  */
+  size_t size;
+};
+
+/* List of attachments.  */
+static struct sysvshm_attach *attach_list;
+
+/* A lock to protect the linked list of shared memory attachments.  */
+static struct mutex sysvshm_lock = MUTEX_INITIALIZER;
+
+
+/* Adds a segment attachment.  */
+error_t
+__sysvshm_add (void *addr, size_t size)
+{
+  struct sysvshm_attach *shm;
+
+  shm = malloc (sizeof (*shm));
+  if (!shm)
+    return errno;
+
+  __mutex_lock (&sysvshm_lock);
+  shm->addr = addr;
+  shm->size = size;
+  shm->next = attach_list;
+  attach_list = shm;
+  __mutex_unlock (&sysvshm_lock);
+
+  return 0;
+}
+
+/* Removes a segment attachment.  Returns its size if found, or EINVAL
+   otherwise.  */
+error_t
+__sysvshm_remove (void *addr, size_t *size)
+{
+  struct sysvshm_attach *shm;
+  struct sysvshm_attach **pshm = &attach_list;
+
+  __mutex_lock (&sysvshm_lock);
+  shm = attach_list;
+  while (shm)
+    {
+      shm = *pshm;
+      if (shm->addr == addr)
+	{
+	  *pshm = shm->next;
+	  *size = shm->size;
+	  __mutex_unlock (&sysvshm_lock);
+	  return 0;
+	}
+      pshm = &shm->next;
+      shm = shm->next;
+    }
+  __mutex_unlock (&sysvshm_lock);
+  return EINVAL;
+}
diff -Naur glibc-2.3.6.orig/hurd/sysvshm.h glibc-2.3.6.new/hurd/sysvshm.h
--- glibc-2.3.6.orig/hurd/sysvshm.h	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/hurd/sysvshm.h	2006-05-06 12:34:35.339051848 +0100
@@ -0,0 +1,47 @@
+/* Copyright (C) 2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <paths.h>
+#include <hurd.h>
+
+/* The area (from top to bottom) that is used for private keys.  These
+   are all keys that have the second highest bit set.  */
+#define SHM_PRIV_KEY_START INT_MAX
+#define SHM_PRIV_KEY_END ((INT_MAX / 2) + 1)
+
+#define SHM_PREFIX "shm-"
+#define SHM_DIR _PATH_DEV "shm/"
+
+/* The maximum number of characters in a shared memory segment file name.
+   32 is the max number of characters in a 128 bit number in hex.  */
+#if __WORDSIZE > 128
+#error Need to increase SHM_NAMEMAX.
+#else
+#define SHM_NAMEMAX (sizeof (SHM_PREFIX) - 1 + 32 + 1)
+#endif
+
+/* Use this with printf and its variants.  */
+#define SHM_NAMEPRI SHM_PREFIX "%0x"
+
+
+/* Adds a segment attachment.  */
+error_t __sysvshm_add (void *addr, size_t size);
+
+/* Removes a segment attachment.  Returns its size if found, or EINVAL
+   otherwise.  */
+error_t __sysvshm_remove (void *addr, size_t *size);
diff -Naur glibc-2.3.6.orig/include/unistd.h glibc-2.3.6.new/include/unistd.h
--- glibc-2.3.6.orig/include/unistd.h	2004-06-30 08:35:39.000000000 +0100
+++ glibc-2.3.6.new/include/unistd.h	2006-05-06 12:32:21.339422888 +0100
@@ -96,10 +96,10 @@
 extern int __setpgid (__pid_t __pid, __pid_t __pgid);
 libc_hidden_proto (__setpgid)
 extern int __setregid (__gid_t __rgid, __gid_t __egid);
-extern int __getresuid (__uid_t *__euid, __uid_t *__ruid, __uid_t *__suid);
-extern int __getresgid (__gid_t *__egid, __gid_t *__rgid, __gid_t *__sgid);
-extern int __setresuid (__uid_t __euid, __uid_t __ruid, __uid_t __suid);
-extern int __setresgid (__gid_t __egid, __gid_t __rgid, __gid_t __sgid);
+extern int __getresuid (__uid_t *__ruid, __uid_t *__euid, __uid_t *__suid);
+extern int __getresgid (__gid_t *__rgid, __gid_t *__egid, __gid_t *__sgid);
+extern int __setresuid (__uid_t __ruid, __uid_t __euid, __uid_t __suid);
+extern int __setresgid (__gid_t __rgid, __gid_t __egid, __gid_t __sgid);
 libc_hidden_proto (__getresuid)
 libc_hidden_proto (__getresgid)
 libc_hidden_proto (__setresuid)
diff -Naur glibc-2.3.6.orig/mach/Machrules glibc-2.3.6.new/mach/Machrules
--- glibc-2.3.6.orig/mach/Machrules	2002-02-17 07:57:18.000000000 +0000
+++ glibc-2.3.6.new/mach/Machrules	2006-05-06 12:33:49.176069688 +0100
@@ -138,10 +138,11 @@
 # We must use $(CFLAGS) to get -O flags that affect #if's in header files.
 	$(include-%.defs) | \
 	$(CC) $(CFLAGS) $(CPPFLAGS) -M -x c - | \
-	sed -e 's,- *:,$@ $(@:.udeps=.ustamp) $(@:.udeps=.uh) $(@:.udeps=.__h)\
-			  $(@:.udeps=_server.c) $(@:.udeps=_server.h):,' \
+	sed -e 's,- *:,$(.udeps-targets):,' \
 	    $(sed-remove-objpfx) > $@.new
 	mv -f $@.new $@
+.udeps-targets = $@ $(@:.udeps=.ustamp) $(@:.udeps=.uh) $(@:.udeps=.__h) \
+		 $(@:.udeps=_server.c) $(@:.udeps=_server.h)
 endif
 
 # Look for the server stub files where they will be written.
diff -Naur glibc-2.3.6.orig/posix/unistd.h glibc-2.3.6.new/posix/unistd.h
--- glibc-2.3.6.orig/posix/unistd.h	2005-04-27 10:50:09.000000000 +0100
+++ glibc-2.3.6.new/posix/unistd.h	2006-05-06 12:32:21.341422584 +0100
@@ -671,21 +671,21 @@
 #endif /* Use BSD.  */
 
 #ifdef __USE_GNU
-/* Fetch the effective user ID, real user ID, and saved-set user ID,
+/* Fetch the real user ID, effective user ID, and saved-set user ID,
    of the calling process.  */
-extern int getresuid (__uid_t *__euid, __uid_t *__ruid, __uid_t *__suid);
+extern int getresuid (__uid_t *__ruid, __uid_t *__euid, __uid_t *__suid);
 
-/* Fetch the effective group ID, real group ID, and saved-set group ID,
+/* Fetch the real group ID, effective group ID, and saved-set group ID,
    of the calling process.  */
-extern int getresgid (__gid_t *__egid, __gid_t *__rgid, __gid_t *__sgid);
+extern int getresgid (__gid_t *__rgid, __gid_t *__egid, __gid_t *__sgid);
 
-/* Set the effective user ID, real user ID, and saved-set user ID,
-   of the calling process to EUID, RUID, and SUID, respectively.  */
-extern int setresuid (__uid_t __euid, __uid_t __ruid, __uid_t __suid);
-
-/* Set the effective group ID, real group ID, and saved-set group ID,
-   of the calling process to EGID, RGID, and SGID, respectively.  */
-extern int setresgid (__gid_t __egid, __gid_t __rgid, __gid_t __sgid);
+/* Set the real user ID, effective user ID, and saved-set user ID,
+   of the calling process to RUID, EUID, and SUID, respectively.  */
+extern int setresuid (__uid_t __ruid, __uid_t __euid, __uid_t __suid);
+
+/* Set the real group ID, effective group ID, and saved-set group ID,
+   of the calling process to RGID, EGID, and SGID, respectively.  */
+extern int setresgid (__gid_t __rgid, __gid_t __egid, __gid_t __sgid);
 #endif
 
 
diff -Naur glibc-2.3.6.orig/posix/unistd.h.orig glibc-2.3.6.new/posix/unistd.h.orig
--- glibc-2.3.6.orig/posix/unistd.h.orig	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/posix/unistd.h.orig	2005-04-27 10:50:09.000000000 +0100
@@ -0,0 +1,1045 @@
+/* Copyright (C) 1991-2002,2003,2004,2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/*
+ *	POSIX Standard: 2.10 Symbolic Constants		<unistd.h>
+ */
+
+#ifndef	_UNISTD_H
+#define	_UNISTD_H	1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* These may be used to determine what facilities are present at compile time.
+   Their values can be obtained at run time from `sysconf'.  */
+
+/* POSIX Standard approved as ISO/IEC 9945-1 as of December 2001.  */
+#define	_POSIX_VERSION	200112L
+
+/* These are not #ifdef __USE_POSIX2 because they are
+   in the theoretically application-owned namespace.  */
+
+/* The utilities on GNU systems also correspond to this version.  */
+#define _POSIX2_VERSION	200112L
+
+/* If defined, the implementation supports the
+   C Language Bindings Option.  */
+#define	_POSIX2_C_BIND	200112L
+
+/* If defined, the implementation supports the
+   C Language Development Utilities Option.  */
+#define	_POSIX2_C_DEV	200112L
+
+/* If defined, the implementation supports the
+   Software Development Utilities Option.  */
+#define	_POSIX2_SW_DEV	200112L
+
+/* If defined, the implementation supports the
+   creation of locales with the localedef utility.  */
+#define _POSIX2_LOCALEDEF       200112L
+
+/* X/Open version number to which the library conforms.  It is selectable.  */
+#ifdef __USE_UNIX98
+# define _XOPEN_VERSION	500
+#else
+# define _XOPEN_VERSION	4
+#endif
+
+/* Commands and utilities from XPG4 are available.  */
+#define _XOPEN_XCU_VERSION	4
+
+/* We are compatible with the old published standards as well.  */
+#define _XOPEN_XPG2	1
+#define _XOPEN_XPG3	1
+#define _XOPEN_XPG4	1
+
+/* The X/Open Unix extensions are available.  */
+#define _XOPEN_UNIX	1
+
+/* Encryption is present.  */
+#define	_XOPEN_CRYPT	1
+
+/* The enhanced internationalization capabilities according to XPG4.2
+   are present.  */
+#define	_XOPEN_ENH_I18N	1
+
+/* The legacy interfaces are also available.  */
+#define _XOPEN_LEGACY	1
+
+
+/* Get values of POSIX options:
+
+   If these symbols are defined, the corresponding features are
+   always available.  If not, they may be available sometimes.
+   The current values can be obtained with `sysconf'.
+
+   _POSIX_JOB_CONTROL		Job control is supported.
+   _POSIX_SAVED_IDS		Processes have a saved set-user-ID
+				and a saved set-group-ID.
+   _POSIX_REALTIME_SIGNALS	Real-time, queued signals are supported.
+   _POSIX_PRIORITY_SCHEDULING	Priority scheduling is supported.
+   _POSIX_TIMERS		POSIX.4 clocks and timers are supported.
+   _POSIX_ASYNCHRONOUS_IO	Asynchronous I/O is supported.
+   _POSIX_PRIORITIZED_IO	Prioritized asynchronous I/O is supported.
+   _POSIX_SYNCHRONIZED_IO	Synchronizing file data is supported.
+   _POSIX_FSYNC			The fsync function is present.
+   _POSIX_MAPPED_FILES		Mapping of files to memory is supported.
+   _POSIX_MEMLOCK		Locking of all memory is supported.
+   _POSIX_MEMLOCK_RANGE		Locking of ranges of memory is supported.
+   _POSIX_MEMORY_PROTECTION	Setting of memory protections is supported.
+   _POSIX_MESSAGE_PASSING	POSIX.4 message queues are supported.
+   _POSIX_SEMAPHORES		POSIX.4 counting semaphores are supported.
+   _POSIX_SHARED_MEMORY_OBJECTS	POSIX.4 shared memory objects are supported.
+   _POSIX_THREADS		POSIX.1c pthreads are supported.
+   _POSIX_THREAD_ATTR_STACKADDR	Thread stack address attribute option supported.
+   _POSIX_THREAD_ATTR_STACKSIZE	Thread stack size attribute option supported.
+   _POSIX_THREAD_SAFE_FUNCTIONS	Thread-safe functions are supported.
+   _POSIX_THREAD_PRIORITY_SCHEDULING
+				POSIX.1c thread execution scheduling supported.
+   _POSIX_THREAD_PRIO_INHERIT	Thread priority inheritance option supported.
+   _POSIX_THREAD_PRIO_PROTECT	Thread priority protection option supported.
+   _POSIX_THREAD_PROCESS_SHARED	Process-shared synchronization supported.
+   _POSIX_PII			Protocol-independent interfaces are supported.
+   _POSIX_PII_XTI		XTI protocol-indep. interfaces are supported.
+   _POSIX_PII_SOCKET		Socket protocol-indep. interfaces are supported.
+   _POSIX_PII_INTERNET		Internet family of protocols supported.
+   _POSIX_PII_INTERNET_STREAM	Connection-mode Internet protocol supported.
+   _POSIX_PII_INTERNET_DGRAM	Connectionless Internet protocol supported.
+   _POSIX_PII_OSI		ISO/OSI family of protocols supported.
+   _POSIX_PII_OSI_COTS		Connection-mode ISO/OSI service supported.
+   _POSIX_PII_OSI_CLTS		Connectionless ISO/OSI service supported.
+   _POSIX_POLL			Implementation supports `poll' function.
+   _POSIX_SELECT		Implementation supports `select' and `pselect'.
+
+   _XOPEN_REALTIME		X/Open realtime support is available.
+   _XOPEN_REALTIME_THREADS	X/Open realtime thread support is available.
+   _XOPEN_SHM			Shared memory interface according to XPG4.2.
+
+   _XBS5_ILP32_OFF32		Implementation provides environment with 32-bit
+				int, long, pointer, and off_t types.
+   _XBS5_ILP32_OFFBIG		Implementation provides environment with 32-bit
+				int, long, and pointer and off_t with at least
+				64 bits.
+   _XBS5_LP64_OFF64		Implementation provides environment with 32-bit
+				int, and 64-bit long, pointer, and off_t types.
+   _XBS5_LPBIG_OFFBIG		Implementation provides environment with at
+				least 32 bits int and long, pointer, and off_t
+				with at least 64 bits.
+
+   If any of these symbols is defined as -1, the corresponding option is not
+   true for any file.  If any is defined as other than -1, the corresponding
+   option is true for all files.  If a symbol is not defined at all, the value
+   for a specific file can be obtained from `pathconf' and `fpathconf'.
+
+   _POSIX_CHOWN_RESTRICTED	Only the super user can use `chown' to change
+				the owner of a file.  `chown' can only be used
+				to change the group ID of a file to a group of
+				which the calling process is a member.
+   _POSIX_NO_TRUNC		Pathname components longer than
+				NAME_MAX generate an error.
+   _POSIX_VDISABLE		If defined, if the value of an element of the
+				`c_cc' member of `struct termios' is
+				_POSIX_VDISABLE, no character will have the
+				effect associated with that element.
+   _POSIX_SYNC_IO		Synchronous I/O may be performed.
+   _POSIX_ASYNC_IO		Asynchronous I/O may be performed.
+   _POSIX_PRIO_IO		Prioritized Asynchronous I/O may be performed.
+
+   Support for the Large File Support interface is not generally available.
+   If it is available the following constants are defined to one.
+   _LFS64_LARGEFILE		Low-level I/O supports large files.
+   _LFS64_STDIO			Standard I/O supports large files.
+   */
+
+#include <bits/posix_opt.h>
+
+/* Get the environment definitions from Unix98.  */
+#ifdef __USE_UNIX98
+# include <bits/environments.h>
+#endif
+
+/* Standard file descriptors.  */
+#define	STDIN_FILENO	0	/* Standard input.  */
+#define	STDOUT_FILENO	1	/* Standard output.  */
+#define	STDERR_FILENO	2	/* Standard error output.  */
+
+
+/* All functions that are not declared anywhere else.  */
+
+#include <bits/types.h>
+
+#ifndef	__ssize_t_defined
+typedef __ssize_t ssize_t;
+# define __ssize_t_defined
+#endif
+
+#define	__need_size_t
+#define __need_NULL
+#include <stddef.h>
+
+#if defined __USE_XOPEN || defined __USE_XOPEN2K
+/* The Single Unix specification says that some more types are
+   available here.  */
+# ifndef __gid_t_defined
+typedef __gid_t gid_t;
+#  define __gid_t_defined
+# endif
+
+# ifndef __uid_t_defined
+typedef __uid_t uid_t;
+#  define __uid_t_defined
+# endif
+
+# ifndef __off_t_defined
+#  ifndef __USE_FILE_OFFSET64
+typedef __off_t off_t;
+#  else
+typedef __off64_t off_t;
+#  endif
+#  define __off_t_defined
+# endif
+# if defined __USE_LARGEFILE64 && !defined __off64_t_defined
+typedef __off64_t off64_t;
+#  define __off64_t_defined
+# endif
+
+# ifndef __useconds_t_defined
+typedef __useconds_t useconds_t;
+#  define __useconds_t_defined
+# endif
+
+# ifndef __pid_t_defined
+typedef __pid_t pid_t;
+#  define __pid_t_defined
+# endif
+#endif	/* X/Open */
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
+# ifndef __intptr_t_defined
+typedef __intptr_t intptr_t;
+#  define __intptr_t_defined
+# endif
+#endif
+
+#if defined __USE_BSD || defined __USE_XOPEN
+# ifndef __socklen_t_defined
+typedef __socklen_t socklen_t;
+#  define __socklen_t_defined
+# endif
+#endif
+
+/* Values for the second argument to access.
+   These may be OR'd together.  */
+#define	R_OK	4		/* Test for read permission.  */
+#define	W_OK	2		/* Test for write permission.  */
+#define	X_OK	1		/* Test for execute permission.  */
+#define	F_OK	0		/* Test for existence.  */
+
+/* Test for access to NAME using the real UID and real GID.  */
+extern int access (__const char *__name, int __type) __THROW __nonnull ((1));
+
+#ifdef __USE_GNU
+/* Test for access to NAME using the effective UID and GID
+   (as normal file operations use).  */
+extern int euidaccess (__const char *__name, int __type)
+     __THROW __nonnull ((1));
+#endif
+
+
+/* Values for the WHENCE argument to lseek.  */
+#ifndef	_STDIO_H		/* <stdio.h> has the same definitions.  */
+# define SEEK_SET	0	/* Seek from beginning of file.  */
+# define SEEK_CUR	1	/* Seek from current position.  */
+# define SEEK_END	2	/* Seek from end of file.  */
+#endif
+
+#if defined __USE_BSD && !defined L_SET
+/* Old BSD names for the same constants; just for compatibility.  */
+# define L_SET		SEEK_SET
+# define L_INCR		SEEK_CUR
+# define L_XTND		SEEK_END
+#endif
+
+
+/* Move FD's file position to OFFSET bytes from the
+   beginning of the file (if WHENCE is SEEK_SET),
+   the current position (if WHENCE is SEEK_CUR),
+   or the end of the file (if WHENCE is SEEK_END).
+   Return the new file position.  */
+#ifndef __USE_FILE_OFFSET64
+extern __off_t lseek (int __fd, __off_t __offset, int __whence) __THROW;
+#else
+# ifdef __REDIRECT_NTH
+extern __off64_t __REDIRECT_NTH (lseek,
+				 (int __fd, __off64_t __offset, int __whence),
+				 lseek64);
+# else
+#  define lseek lseek64
+# endif
+#endif
+#ifdef __USE_LARGEFILE64
+extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence) __THROW;
+#endif
+
+/* Close the file descriptor FD.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int close (int __fd);
+
+/* Read NBYTES into BUF from FD.  Return the
+   number read, -1 for errors or 0 for EOF.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern ssize_t read (int __fd, void *__buf, size_t __nbytes);
+
+/* Write N bytes of BUF to FD.  Return the number written, or -1.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern ssize_t write (int __fd, __const void *__buf, size_t __n);
+
+#ifdef __USE_UNIX98
+# ifndef __USE_FILE_OFFSET64
+/* Read NBYTES into BUF from FD at the given position OFFSET without
+   changing the file pointer.  Return the number read, -1 for errors
+   or 0 for EOF.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern ssize_t pread (int __fd, void *__buf, size_t __nbytes,
+		      __off_t __offset);
+
+/* Write N bytes of BUF to FD at the given position OFFSET without
+   changing the file pointer.  Return the number written, or -1.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern ssize_t pwrite (int __fd, __const void *__buf, size_t __n,
+		       __off_t __offset);
+# else
+#  ifdef __REDIRECT
+extern ssize_t __REDIRECT (pread, (int __fd, void *__buf, size_t __nbytes,
+				   __off64_t __offset),
+			   pread64);
+extern ssize_t __REDIRECT (pwrite, (int __fd, __const void *__buf,
+				    size_t __nbytes, __off64_t __offset),
+			   pwrite64);
+#  else
+#   define pread pread64
+#   define pwrite pwrite64
+#  endif
+# endif
+
+# ifdef __USE_LARGEFILE64
+/* Read NBYTES into BUF from FD at the given position OFFSET without
+   changing the file pointer.  Return the number read, -1 for errors
+   or 0 for EOF.  */
+extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
+			__off64_t __offset);
+/* Write N bytes of BUF to FD at the given position OFFSET without
+   changing the file pointer.  Return the number written, or -1.  */
+extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n,
+			 __off64_t __offset);
+# endif
+#endif
+
+/* Create a one-way communication channel (pipe).
+   If successful, two file descriptors are stored in PIPEDES;
+   bytes written on PIPEDES[1] can be read from PIPEDES[0].
+   Returns 0 if successful, -1 if not.  */
+extern int pipe (int __pipedes[2]) __THROW;
+
+/* Schedule an alarm.  In SECONDS seconds, the process will get a SIGALRM.
+   If SECONDS is zero, any currently scheduled alarm will be cancelled.
+   The function returns the number of seconds remaining until the last
+   alarm scheduled would have signaled, or zero if there wasn't one.
+   There is no return value to indicate an error, but you can set `errno'
+   to 0 and check its value after calling `alarm', and this might tell you.
+   The signal may come late due to processor scheduling.  */
+extern unsigned int alarm (unsigned int __seconds) __THROW;
+
+/* Make the process sleep for SECONDS seconds, or until a signal arrives
+   and is not ignored.  The function returns the number of seconds less
+   than SECONDS which it actually slept (thus zero if it slept the full time).
+   If a signal handler does a `longjmp' or modifies the handling of the
+   SIGALRM signal while inside `sleep' call, the handling of the SIGALRM
+   signal afterwards is undefined.  There is no return value to indicate
+   error, but if `sleep' returns SECONDS, it probably didn't work.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern unsigned int sleep (unsigned int __seconds);
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Set an alarm to go off (generating a SIGALRM signal) in VALUE
+   microseconds.  If INTERVAL is nonzero, when the alarm goes off, the
+   timer is reset to go off every INTERVAL microseconds thereafter.
+   Returns the number of microseconds remaining before the alarm.  */
+extern __useconds_t ualarm (__useconds_t __value, __useconds_t __interval)
+     __THROW;
+
+/* Sleep USECONDS microseconds, or until a signal arrives that is not blocked
+   or ignored.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int usleep (__useconds_t __useconds);
+#endif
+
+
+/* Suspend the process until a signal arrives.
+   This always returns -1 and sets `errno' to EINTR.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int pause (void);
+
+
+/* Change the owner and group of FILE.  */
+extern int chown (__const char *__file, __uid_t __owner, __gid_t __group)
+     __THROW __nonnull ((1));
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Change the owner and group of the file that FD is open on.  */
+extern int fchown (int __fd, __uid_t __owner, __gid_t __group) __THROW;
+
+
+/* Change owner and group of FILE, if it is a symbolic
+   link the ownership of the symbolic link is changed.  */
+extern int lchown (__const char *__file, __uid_t __owner, __gid_t __group)
+     __THROW __nonnull ((1));
+
+#endif /* Use BSD || X/Open Unix.  */
+
+/* Change the process's working directory to PATH.  */
+extern int chdir (__const char *__path) __THROW __nonnull ((1));
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Change the process's working directory to the one FD is open on.  */
+extern int fchdir (int __fd) __THROW;
+#endif
+
+/* Get the pathname of the current working directory,
+   and put it in SIZE bytes of BUF.  Returns NULL if the
+   directory couldn't be determined or SIZE was too small.
+   If successful, returns BUF.  In GNU, if BUF is NULL,
+   an array is allocated with `malloc'; the array is SIZE
+   bytes long, unless SIZE == 0, in which case it is as
+   big as necessary.  */
+extern char *getcwd (char *__buf, size_t __size) __THROW;
+
+#ifdef	__USE_GNU
+/* Return a malloc'd string containing the current directory name.
+   If the environment variable `PWD' is set, and its value is correct,
+   that value is used.  */
+extern char *get_current_dir_name (void) __THROW;
+#endif
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Put the absolute pathname of the current working directory in BUF.
+   If successful, return BUF.  If not, put an error message in
+   BUF and return NULL.  BUF should be at least PATH_MAX bytes long.  */
+extern char *getwd (char *__buf) __THROW __nonnull ((1));
+#endif
+
+
+/* Duplicate FD, returning a new file descriptor on the same file.  */
+extern int dup (int __fd) __THROW;
+
+/* Duplicate FD to FD2, closing FD2 and making it open on the same file.  */
+extern int dup2 (int __fd, int __fd2) __THROW;
+
+/* NULL-terminated array of "NAME=VALUE" environment variables.  */
+extern char **__environ;
+#ifdef __USE_GNU
+extern char **environ;
+#endif
+
+
+/* Replace the current process, executing PATH with arguments ARGV and
+   environment ENVP.  ARGV and ENVP are terminated by NULL pointers.  */
+extern int execve (__const char *__path, char *__const __argv[],
+		   char *__const __envp[]) __THROW __nonnull ((1));
+
+#ifdef __USE_GNU
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+extern int fexecve (int __fd, char *__const __argv[], char *__const __envp[])
+     __THROW;
+#endif
+
+
+/* Execute PATH with arguments ARGV and environment from `environ'.  */
+extern int execv (__const char *__path, char *__const __argv[])
+     __THROW __nonnull ((1));
+
+/* Execute PATH with all arguments after PATH until a NULL pointer,
+   and the argument after that for environment.  */
+extern int execle (__const char *__path, __const char *__arg, ...)
+     __THROW __nonnull ((1));
+
+/* Execute PATH with all arguments after PATH until
+   a NULL pointer and environment from `environ'.  */
+extern int execl (__const char *__path, __const char *__arg, ...)
+     __THROW __nonnull ((1));
+
+/* Execute FILE, searching in the `PATH' environment variable if it contains
+   no slashes, with arguments ARGV and environment from `environ'.  */
+extern int execvp (__const char *__file, char *__const __argv[])
+     __THROW __nonnull ((1));
+
+/* Execute FILE, searching in the `PATH' environment variable if
+   it contains no slashes, with all arguments after FILE until a
+   NULL pointer and environment from `environ'.  */
+extern int execlp (__const char *__file, __const char *__arg, ...)
+     __THROW __nonnull ((1));
+
+
+#if defined __USE_MISC || defined __USE_XOPEN
+/* Add INC to priority of the current process.  */
+extern int nice (int __inc) __THROW;
+#endif
+
+
+/* Terminate program execution with the low-order 8 bits of STATUS.  */
+extern void _exit (int __status) __attribute__ ((__noreturn__));
+
+
+/* Get the `_PC_*' symbols for the NAME argument to `pathconf' and `fpathconf';
+   the `_SC_*' symbols for the NAME argument to `sysconf';
+   and the `_CS_*' symbols for the NAME argument to `confstr'.  */
+#include <bits/confname.h>
+
+/* Get file-specific configuration information about PATH.  */
+extern long int pathconf (__const char *__path, int __name)
+     __THROW __nonnull ((1));
+
+/* Get file-specific configuration about descriptor FD.  */
+extern long int fpathconf (int __fd, int __name) __THROW;
+
+/* Get the value of the system variable NAME.  */
+extern long int sysconf (int __name) __THROW __attribute__ ((__const__));
+
+#ifdef	__USE_POSIX2
+/* Get the value of the string-valued system variable NAME.  */
+extern size_t confstr (int __name, char *__buf, size_t __len) __THROW;
+#endif
+
+
+/* Get the process ID of the calling process.  */
+extern __pid_t getpid (void) __THROW;
+
+/* Get the process ID of the calling process's parent.  */
+extern __pid_t getppid (void) __THROW;
+
+/* Get the process group ID of the calling process.
+   This function is different on old BSD. */
+#ifndef __FAVOR_BSD
+extern __pid_t getpgrp (void) __THROW;
+#else
+# ifdef __REDIRECT_NTH
+extern __pid_t __REDIRECT_NTH (getpgrp, (__pid_t __pid), __getpgid);
+# else
+#  define getpgrp __getpgid
+# endif
+#endif
+
+/* Get the process group ID of process PID.  */
+extern __pid_t __getpgid (__pid_t __pid) __THROW;
+#ifdef __USE_XOPEN_EXTENDED
+extern __pid_t getpgid (__pid_t __pid) __THROW;
+#endif
+
+
+/* Set the process group ID of the process matching PID to PGID.
+   If PID is zero, the current process's process group ID is set.
+   If PGID is zero, the process ID of the process is used.  */
+extern int setpgid (__pid_t __pid, __pid_t __pgid) __THROW;
+
+#if defined __USE_SVID || defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Both System V and BSD have `setpgrp' functions, but with different
+   calling conventions.  The BSD function is the same as POSIX.1 `setpgid'
+   (above).  The System V function takes no arguments and puts the calling
+   process in its on group like `setpgid (0, 0)'.
+
+   New programs should always use `setpgid' instead.
+
+   The default in GNU is to provide the System V function.  The BSD
+   function is available under -D_BSD_SOURCE.  */
+
+# ifndef __FAVOR_BSD
+
+/* Set the process group ID of the calling process to its own PID.
+   This is exactly the same as `setpgid (0, 0)'.  */
+extern int setpgrp (void) __THROW;
+
+# else
+
+/* Another name for `setpgid' (above).  */
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (setpgrp, (__pid_t __pid, __pid_t __pgrp), setpgid);
+#  else
+#   define setpgrp setpgid
+#  endif
+
+# endif	/* Favor BSD.  */
+#endif	/* Use SVID or BSD.  */
+
+/* Create a new session with the calling process as its leader.
+   The process group IDs of the session and the calling process
+   are set to the process ID of the calling process, which is returned.  */
+extern __pid_t setsid (void) __THROW;
+
+#ifdef __USE_XOPEN_EXTENDED
+/* Return the session ID of the given process.  */
+extern __pid_t getsid (__pid_t __pid) __THROW;
+#endif
+
+/* Get the real user ID of the calling process.  */
+extern __uid_t getuid (void) __THROW;
+
+/* Get the effective user ID of the calling process.  */
+extern __uid_t geteuid (void) __THROW;
+
+/* Get the real group ID of the calling process.  */
+extern __gid_t getgid (void) __THROW;
+
+/* Get the effective group ID of the calling process.  */
+extern __gid_t getegid (void) __THROW;
+
+/* If SIZE is zero, return the number of supplementary groups
+   the calling process is in.  Otherwise, fill in the group IDs
+   of its supplementary groups in LIST and return the number written.  */
+extern int getgroups (int __size, __gid_t __list[]) __THROW;
+
+#ifdef	__USE_GNU
+/* Return nonzero iff the calling process is in group GID.  */
+extern int group_member (__gid_t __gid) __THROW;
+#endif
+
+/* Set the user ID of the calling process to UID.
+   If the calling process is the super-user, set the real
+   and effective user IDs, and the saved set-user-ID to UID;
+   if not, the effective user ID is set to UID.  */
+extern int setuid (__uid_t __uid) __THROW;
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Set the real user ID of the calling process to RUID,
+   and the effective user ID of the calling process to EUID.  */
+extern int setreuid (__uid_t __ruid, __uid_t __euid) __THROW;
+#endif
+
+#if defined __USE_BSD || defined __USE_XOPEN2K
+/* Set the effective user ID of the calling process to UID.  */
+extern int seteuid (__uid_t __uid) __THROW;
+#endif /* Use BSD.  */
+
+/* Set the group ID of the calling process to GID.
+   If the calling process is the super-user, set the real
+   and effective group IDs, and the saved set-group-ID to GID;
+   if not, the effective group ID is set to GID.  */
+extern int setgid (__gid_t __gid) __THROW;
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Set the real group ID of the calling process to RGID,
+   and the effective group ID of the calling process to EGID.  */
+extern int setregid (__gid_t __rgid, __gid_t __egid) __THROW;
+#endif
+
+#if defined __USE_BSD || defined __USE_XOPEN2K
+/* Set the effective group ID of the calling process to GID.  */
+extern int setegid (__gid_t __gid) __THROW;
+#endif /* Use BSD.  */
+
+#ifdef __USE_GNU
+/* Fetch the effective user ID, real user ID, and saved-set user ID,
+   of the calling process.  */
+extern int getresuid (__uid_t *__euid, __uid_t *__ruid, __uid_t *__suid);
+
+/* Fetch the effective group ID, real group ID, and saved-set group ID,
+   of the calling process.  */
+extern int getresgid (__gid_t *__egid, __gid_t *__rgid, __gid_t *__sgid);
+
+/* Set the effective user ID, real user ID, and saved-set user ID,
+   of the calling process to EUID, RUID, and SUID, respectively.  */
+extern int setresuid (__uid_t __euid, __uid_t __ruid, __uid_t __suid);
+
+/* Set the effective group ID, real group ID, and saved-set group ID,
+   of the calling process to EGID, RGID, and SGID, respectively.  */
+extern int setresgid (__gid_t __egid, __gid_t __rgid, __gid_t __sgid);
+#endif
+
+
+/* Clone the calling process, creating an exact copy.
+   Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+extern __pid_t fork (void) __THROW;
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+extern __pid_t vfork (void) __THROW;
+#endif /* Use BSD. */
+
+
+/* Return the pathname of the terminal FD is open on, or NULL on errors.
+   The returned storage is good only until the next call to this function.  */
+extern char *ttyname (int __fd) __THROW;
+
+/* Store at most BUFLEN characters of the pathname of the terminal FD is
+   open on in BUF.  Return 0 on success, otherwise an error number.  */
+extern int ttyname_r (int __fd, char *__buf, size_t __buflen)
+     __THROW __nonnull ((2));
+
+/* Return 1 if FD is a valid descriptor associated
+   with a terminal, zero if not.  */
+extern int isatty (int __fd) __THROW;
+
+#if defined __USE_BSD \
+    || (defined __USE_XOPEN_EXTENDED && !defined __USE_UNIX98)
+/* Return the index into the active-logins file (utmp) for
+   the controlling terminal.  */
+extern int ttyslot (void) __THROW;
+#endif
+
+
+/* Make a link to FROM named TO.  */
+extern int link (__const char *__from, __const char *__to)
+     __THROW __nonnull ((1, 2));
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K
+/* Make a symbolic link to FROM named TO.  */
+extern int symlink (__const char *__from, __const char *__to)
+     __THROW __nonnull ((1, 2));
+
+/* Read the contents of the symbolic link PATH into no more than
+   LEN bytes of BUF.  The contents are not null-terminated.
+   Returns the number of characters read, or -1 for errors.  */
+extern int readlink (__const char *__restrict __path, char *__restrict __buf,
+		     size_t __len) __THROW __nonnull ((1, 2));
+#endif /* Use BSD.  */
+
+/* Remove the link NAME.  */
+extern int unlink (__const char *__name) __THROW __nonnull ((1));
+
+/* Remove the directory PATH.  */
+extern int rmdir (__const char *__path) __THROW __nonnull ((1));
+
+
+/* Return the foreground process group ID of FD.  */
+extern __pid_t tcgetpgrp (int __fd) __THROW;
+
+/* Set the foreground process group ID of FD set PGRP_ID.  */
+extern int tcsetpgrp (int __fd, __pid_t __pgrp_id) __THROW;
+
+
+/* Return the login name of the user.
+
+   This function is a possible cancellation points and therefore not
+   marked with __THROW.  */
+extern char *getlogin (void);
+#if defined __USE_REENTRANT || defined __USE_UNIX98
+/* Return at most NAME_LEN characters of the login name of the user in NAME.
+   If it cannot be determined or some other error occurred, return the error
+   code.  Otherwise return 0.
+
+   This function is a possible cancellation points and therefore not
+   marked with __THROW.  */
+extern int getlogin_r (char *__name, size_t __name_len) __nonnull ((1));
+#endif
+
+#ifdef	__USE_BSD
+/* Set the login name returned by `getlogin'.  */
+extern int setlogin (__const char *__name) __THROW __nonnull ((1));
+#endif
+
+
+#ifdef	__USE_POSIX2
+/* Get definitions and prototypes for functions to process the
+   arguments in ARGV (ARGC of them, minus the program name) for
+   options given in OPTS.  */
+# define __need_getopt
+# include <getopt.h>
+#endif
+
+
+#if defined __USE_BSD || defined __USE_UNIX98
+/* Put the name of the current host in no more than LEN bytes of NAME.
+   The result is null-terminated if LEN is large enough for the full
+   name and the terminator.  */
+extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1));
+#endif
+
+
+#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98)
+/* Set the name of the current host to NAME, which is LEN bytes long.
+   This call is restricted to the super-user.  */
+extern int sethostname (__const char *__name, size_t __len)
+     __THROW __nonnull ((1));
+
+/* Set the current machine's Internet number to ID.
+   This call is restricted to the super-user.  */
+extern int sethostid (long int __id) __THROW;
+
+
+/* Get and set the NIS (aka YP) domain name, if any.
+   Called just like `gethostname' and `sethostname'.
+   The NIS domain name is usually the empty string when not using NIS.  */
+extern int getdomainname (char *__name, size_t __len)
+     __THROW __nonnull ((1));
+extern int setdomainname (__const char *__name, size_t __len)
+     __THROW __nonnull ((1));
+
+
+/* Revoke access permissions to all processes currently communicating
+   with the control terminal, and then send a SIGHUP signal to the process
+   group of the control terminal.  */
+extern int vhangup (void) __THROW;
+
+/* Revoke the access of all descriptors currently open on FILE.  */
+extern int revoke (__const char *__file) __THROW __nonnull ((1));
+
+
+/* Enable statistical profiling, writing samples of the PC into at most
+   SIZE bytes of SAMPLE_BUFFER; every processor clock tick while profiling
+   is enabled, the system examines the user PC and increments
+   SAMPLE_BUFFER[((PC - OFFSET) / 2) * SCALE / 65536].  If SCALE is zero,
+   disable profiling.  Returns zero on success, -1 on error.  */
+extern int profil (unsigned short int *__sample_buffer, size_t __size,
+		   size_t __offset, unsigned int __scale)
+     __THROW __nonnull ((1));
+
+
+/* Turn accounting on if NAME is an existing file.  The system will then write
+   a record for each process as it terminates, to this file.  If NAME is NULL,
+   turn accounting off.  This call is restricted to the super-user.  */
+extern int acct (__const char *__name) __THROW;
+
+
+/* Successive calls return the shells listed in `/etc/shells'.  */
+extern char *getusershell (void) __THROW;
+extern void endusershell (void) __THROW; /* Discard cached info.  */
+extern void setusershell (void) __THROW; /* Rewind and re-read the file.  */
+
+
+/* Put the program in the background, and dissociate from the controlling
+   terminal.  If NOCHDIR is zero, do `chdir ("/")'.  If NOCLOSE is zero,
+   redirects stdin, stdout, and stderr to /dev/null.  */
+extern int daemon (int __nochdir, int __noclose) __THROW;
+#endif /* Use BSD || X/Open.  */
+
+
+#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_XOPEN2K)
+/* Make PATH be the root directory (the starting point for absolute paths).
+   This call is restricted to the super-user.  */
+extern int chroot (__const char *__path) __THROW __nonnull ((1));
+
+/* Prompt with PROMPT and read a string from the terminal without echoing.
+   Uses /dev/tty if possible; otherwise stderr and stdin.  */
+extern char *getpass (__const char *__prompt) __nonnull ((1));
+#endif /* Use BSD || X/Open.  */
+
+
+#if defined __USE_BSD || defined __USE_XOPEN
+/* Make all changes done to FD actually appear on disk.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int fsync (int __fd);
+#endif /* Use BSD || X/Open.  */
+
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+
+/* Return identifier for the current host.  */
+extern long int gethostid (void);
+
+/* Make all changes done to all files actually appear on disk.  */
+extern void sync (void) __THROW;
+
+
+/* Return the number of bytes in a page.  This is the system's page size,
+   which is not necessarily the same as the hardware page size.  */
+extern int getpagesize (void)  __THROW __attribute__ ((__const__));
+
+
+/* Return the maximum number of file descriptors
+   the current process could possibly have.  */
+extern int getdtablesize (void) __THROW;
+
+
+/* Truncate FILE to LENGTH bytes.  */
+# ifndef __USE_FILE_OFFSET64
+extern int truncate (__const char *__file, __off_t __length)
+     __THROW __nonnull ((1));
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (truncate,
+			   (__const char *__file, __off64_t __length),
+			   truncate64) __nonnull ((1));
+#  else
+#   define truncate truncate64
+#  endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int truncate64 (__const char *__file, __off64_t __length)
+     __THROW __nonnull ((1));
+# endif
+
+#endif /* Use BSD || X/Open Unix.  */
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K
+
+/* Truncate the file FD is open on to LENGTH bytes.  */
+# ifndef __USE_FILE_OFFSET64
+extern int ftruncate (int __fd, __off_t __length) __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (ftruncate, (int __fd, __off64_t __length),
+			   ftruncate64);
+#  else
+#   define ftruncate ftruncate64
+#  endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int ftruncate64 (int __fd, __off64_t __length) __THROW;
+# endif
+
+#endif /* Use BSD || X/Open Unix || POSIX 2003.  */
+
+
+#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
+
+/* Set the end of accessible data space (aka "the break") to ADDR.
+   Returns zero on success and -1 for errors (with errno set).  */
+extern int brk (void *__addr) __THROW;
+
+/* Increase or decrease the end of accessible data space by DELTA bytes.
+   If successful, returns the address the previous end of data space
+   (i.e. the beginning of the new space, if DELTA > 0);
+   returns (void *) -1 for errors (with errno set).  */
+extern void *sbrk (intptr_t __delta) __THROW;
+#endif
+
+
+#ifdef __USE_MISC
+/* Invoke `system call' number SYSNO, passing it the remaining arguments.
+   This is completely system-dependent, and not often useful.
+
+   In Unix, `syscall' sets `errno' for all errors and most calls return -1
+   for errors; in many systems you cannot pass arguments or get return
+   values for all system calls (`pipe', `fork', and `getppid' typically
+   among them).
+
+   In Mach, all system calls take normal arguments and always return an
+   error code (zero for success).  */
+extern long int syscall (long int __sysno, ...) __THROW;
+
+#endif	/* Use misc.  */
+
+
+#if (defined __USE_MISC || defined __USE_XOPEN_EXTENDED) && !defined F_LOCK
+/* NOTE: These declarations also appear in <fcntl.h>; be sure to keep both
+   files consistent.  Some systems have them there and some here, and some
+   software depends on the macros being defined without including both.  */
+
+/* `lockf' is a simpler interface to the locking facilities of `fcntl'.
+   LEN is always relative to the current file position.
+   The CMD argument is one of the following.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+
+# define F_ULOCK 0	/* Unlock a previously locked region.  */
+# define F_LOCK  1	/* Lock a region for exclusive use.  */
+# define F_TLOCK 2	/* Test and lock a region for exclusive use.  */
+# define F_TEST  3	/* Test a region for other processes locks.  */
+
+# ifndef __USE_FILE_OFFSET64
+extern int lockf (int __fd, int __cmd, __off_t __len);
+# else
+#  ifdef __REDIRECT
+extern int __REDIRECT (lockf, (int __fd, int __cmd, __off64_t __len),
+		       lockf64);
+#  else
+#   define lockf lockf64
+#  endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int lockf64 (int __fd, int __cmd, __off64_t __len);
+# endif
+#endif /* Use misc and F_LOCK not already defined.  */
+
+
+#ifdef __USE_GNU
+
+/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
+   set to EINTR.  */
+
+# define TEMP_FAILURE_RETRY(expression) \
+  (__extension__							      \
+    ({ long int __result;						      \
+       do __result = (long int) (expression);				      \
+       while (__result == -1L && errno == EINTR);			      \
+       __result; }))
+#endif
+
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
+/* Synchronize at least the data part of a file with the underlying
+   media.  */
+extern int fdatasync (int __fildes) __THROW;
+#endif /* Use POSIX199309 */
+
+
+/* XPG4.2 specifies that prototypes for the encryption functions must
+   be defined here.  */
+#ifdef	__USE_XOPEN
+/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
+extern char *crypt (__const char *__key, __const char *__salt)
+     __THROW __nonnull ((1, 2));
+
+/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
+   block in place.  */
+extern void encrypt (char *__block, int __edflag) __THROW __nonnull ((1));
+
+
+/* Swab pairs bytes in the first N bytes of the area pointed to by
+   FROM and copy the result to TO.  The value of TO must not be in the
+   range [FROM - N + 1, FROM - 1].  If N is odd the first byte in FROM
+   is without partner.  */
+extern void swab (__const void *__restrict __from, void *__restrict __to,
+		  ssize_t __n) __THROW __nonnull ((1, 2));
+#endif
+
+
+/* The Single Unix specification demands this prototype to be here.
+   It is also found in <stdio.h>.  */
+#ifdef __USE_XOPEN
+/* Return the name of the controlling terminal.  */
+extern char *ctermid (char *__s) __THROW __nonnull ((1));
+#endif
+
+__END_DECLS
+
+#endif /* unistd.h  */
diff -Naur glibc-2.3.6.orig/sysdeps/generic/getresgid.c glibc-2.3.6.new/sysdeps/generic/getresgid.c
--- glibc-2.3.6.orig/sysdeps/generic/getresgid.c	2002-10-14 02:03:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/generic/getresgid.c	2006-05-06 12:32:21.343422280 +0100
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1995,1996,1997,1998,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1995,1996,1997,1998,2002,2006
+     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
@@ -19,10 +20,10 @@
 #include <errno.h>
 #include <unistd.h>
 
-/* Fetch the effective group ID, real group ID, and saved-set group ID,
+/* Fetch the real group ID, effective group ID, and saved-set group ID,
    of the calling process.  */
 int
-__getresgid (gid_t *egid, gid_t *rgid, gid_t *sgid)
+__getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid)
 {
   __set_errno (ENOSYS);
   return -1;
diff -Naur glibc-2.3.6.orig/sysdeps/generic/getresuid.c glibc-2.3.6.new/sysdeps/generic/getresuid.c
--- glibc-2.3.6.orig/sysdeps/generic/getresuid.c	2002-10-14 02:03:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/generic/getresuid.c	2006-05-06 12:32:21.343422280 +0100
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1995,1996,1997,1998,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1995,1996,1997,1998,2002,2006
+     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
@@ -19,10 +20,10 @@
 #include <errno.h>
 #include <unistd.h>
 
-/* Fetch the effective user ID, real user ID, and saved-set user ID,
+/* Fetch the real user ID, effective user ID, and saved-set user ID,
    of the calling process.  */
 int
-__getresuid (uid_t *euid, uid_t *ruid, uid_t *suid)
+__getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)
 {
   __set_errno (ENOSYS);
   return -1;
diff -Naur glibc-2.3.6.orig/sysdeps/generic/setresgid.c glibc-2.3.6.new/sysdeps/generic/setresgid.c
--- glibc-2.3.6.orig/sysdeps/generic/setresgid.c	2002-10-14 02:03:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/generic/setresgid.c	2006-05-06 12:32:21.344422128 +0100
@@ -1,5 +1,5 @@
-/* setresgid -- set effective group ID, real group ID, and saved-set group ID
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* setresgid -- set real group ID, effective group ID, and saved-set group ID
+   Copyright (C) 2002, 2006 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
@@ -20,10 +20,10 @@
 #include <errno.h>
 #include <unistd.h>
 
-/* Set the effective group ID, real group ID, and saved-set group ID,
-   of the calling process to EGID, RGID, and SGID, respectively.  */
+/* Set the real group ID, effective group ID, and saved-set group ID,
+   of the calling process to RGID, EGID, and SGID, respectively.  */
 int
-__setresgid (gid_t egid, gid_t rgid, gid_t sgid)
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
 {
   __set_errno (ENOSYS);
   return -1;
diff -Naur glibc-2.3.6.orig/sysdeps/generic/setresuid.c glibc-2.3.6.new/sysdeps/generic/setresuid.c
--- glibc-2.3.6.orig/sysdeps/generic/setresuid.c	2002-10-14 02:03:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/generic/setresuid.c	2006-05-06 12:32:21.345421976 +0100
@@ -1,5 +1,5 @@
-/* setresuid -- set effective user ID, real user ID, and saved-set user ID
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* setresuid -- set real user ID, effective user ID, and saved-set user ID
+   Copyright (C) 2002, 2006 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
@@ -20,10 +20,10 @@
 #include <errno.h>
 #include <unistd.h>
 
-/* Set the effective user ID, real user ID, and saved-set user ID,
-   of the calling process to EUID, RUID, and SUID, respectively.  */
+/* Set the real user ID, effective user ID, and saved-set user ID,
+   of the calling process to RUID, EUID, and SUID, respectively.  */
 int
-__setresuid (uid_t euid, uid_t ruid, uid_t suid)
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
 {
   __set_errno (ENOSYS);
   return -1;
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/bits/ioctls.h glibc-2.3.6.new/sysdeps/mach/hurd/bits/ioctls.h
--- glibc-2.3.6.orig/sysdeps/mach/hurd/bits/ioctls.h	2001-07-06 05:55:58.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/bits/ioctls.h	2006-05-06 12:34:21.602140176 +0100
@@ -118,6 +118,7 @@
    _IOT_foobar is defined either in this file,
    or where struct foobar is defined.  */
 #define	_IO(g, n)	_IOC (IOC_VOID, (g), (n), 0)
+#define	_IOIW(g, n, t)	_IOC (IOC_VOID, (g), (n), _IOC_ENCODE_TYPE (t))
 #define	_IOR(g, n, t)	_IOC (IOC_OUT, (g), (n), _IOC_ENCODE_TYPE (t))
 #define	_IOW(g, n, t)	_IOC (IOC_IN, (g), (n), _IOC_ENCODE_TYPE (t))
 #define	_IOWR(g, n, t)	_IOC (IOC_INOUT, (g), (n), _IOC_ENCODE_TYPE (t))
@@ -226,6 +227,7 @@
 #define	SIOCSIFADDR	_IOW('i', 12, struct ifreq)	/* set ifnet address */
 #define	OSIOCGIFADDR	_IOWR('i',13, struct ifreq)	/* get ifnet address */
 #define	SIOCGIFADDR	_IOWR('i',33, struct ifreq)	/* get ifnet address */
+#define	SIOCGIFHWADDR	_IOWR('i',39, struct ifreq)	/* get hwaddress */
 #define	SIOCSIFDSTADDR	_IOW('i', 14, struct ifreq)	/* set p-p address */
 #define	OSIOCGIFDSTADDR	_IOWR('i',15, struct ifreq)	/* get p-p address */
 #define	SIOCGIFDSTADDR	_IOWR('i',34, struct ifreq)	/* get p-p address */
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/bits/stat.h glibc-2.3.6.new/sysdeps/mach/hurd/bits/stat.h
--- glibc-2.3.6.orig/sysdeps/mach/hurd/bits/stat.h	2001-07-06 05:55:58.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/bits/stat.h	2006-05-06 12:34:35.340051696 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 93, 94, 96, 97, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1992,93,94,96,97,99,2000,2005 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
@@ -182,8 +182,11 @@
 /* All the bits relevant to translators */
 #define S_ITRANS	000070000000
 
+/* Definitely no mmaps to this.  */
+#define S_IMMAP0	000100000000
+
 /* ALL the unused bits.  */
-#define	S_ISPARE	(~(S_IFMT|S_ITRANS|S_INOCACHE|    \
+#define	S_ISPARE	(~(S_IFMT|S_ITRANS|S_INOCACHE|S_IMMAP0|    \
 			   S_IUSEUNK|S_IUNKNOWN|07777))
 #endif
 
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/ftok.c glibc-2.3.6.new/sysdeps/mach/hurd/ftok.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/ftok.c	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/ftok.c	2006-05-06 12:34:35.340051696 +0100
@@ -0,0 +1,43 @@
+/* Copyright (C) 1995, 1996, 2000, 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sys/ipc.h>
+#include <sys/stat.h>
+
+
+/* In the Hurd, we use the second-to-most-significant bit as flag for
+   private keys.  We use a different order of the components so that
+   the biggest one---the inode number---is affected by this.  */
+
+key_t
+ftok (pathname, proj_id)
+     const char *pathname;
+     int proj_id;
+{
+  struct stat64 st;
+  key_t key;
+
+  if (__xstat64 (_STAT_VER, pathname, &st) < 0)
+    return (key_t) -1;
+
+  key = ((st.st_dev & 0xff) | ((proj_id & 0xff) << 8)
+	 | ((st.st_ino & 0x3fff) << 16));
+
+  return key;
+}
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/getresgid.c glibc-2.3.6.new/sysdeps/mach/hurd/getresgid.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/getresgid.c	2002-10-14 02:03:11.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/getresgid.c	2006-05-06 12:32:21.346421824 +0100
@@ -1,5 +1,5 @@
-/* getresgid -- fetch effective group ID, real group ID, and saved-set group ID
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* getresgid -- fetch real group ID, effective group ID, and saved-set group ID
+   Copyright (C) 2002, 2006 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
@@ -22,13 +22,13 @@
 #include <hurd.h>
 #include <hurd/id.h>
 
-/* Fetch the effective group ID, real group ID, and saved-set group ID,
+/* Fetch the real group ID, effective group ID, and saved-set group ID,
    of the calling process.  */
 int
-__getresgid (gid_t *egid, gid_t *rgid, gid_t *sgid)
+__getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid)
 {
   error_t err;
-  gid_t eff, real, saved;
+  gid_t real, eff, saved;
 
   HURD_CRITICAL_BEGIN;
   __mutex_lock (&_hurd_id.lock);
@@ -42,8 +42,8 @@
       else
 	{
 	  real = _hurd_id.aux.gids[0];
-	  saved = _hurd_id.aux.ngids < 2 ? real :_hurd_id.aux.gids[1];
 	  eff = _hurd_id.gen.ngids < 1 ? real : _hurd_id.gen.gids[0];
+	  saved = _hurd_id.aux.ngids < 2 ? real : _hurd_id.aux.gids[1];
 	}
     }
 
@@ -53,8 +53,8 @@
   if (err)
     return __hurd_fail (err);
 
-  *egid = eff;
   *rgid = real;
+  *egid = eff;
   *sgid = saved;
   return 0;
 }
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/getresuid.c glibc-2.3.6.new/sysdeps/mach/hurd/getresuid.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/getresuid.c	2002-10-14 02:03:11.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/getresuid.c	2006-05-06 12:32:21.347421672 +0100
@@ -1,5 +1,5 @@
-/* getresuid -- fetch effective user ID, real user ID, and saved-set user ID
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* getresuid -- fetch real user ID, effective user ID, and saved-set user ID
+   Copyright (C) 2002, 2006 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
@@ -22,13 +22,13 @@
 #include <hurd.h>
 #include <hurd/id.h>
 
-/* Fetch the effective user ID, real user ID, and saved-set user ID,
+/* Fetch the real user ID, effective user ID, and saved-set user ID,
    of the calling process.  */
 int
-__getresuid (uid_t *euid, uid_t *ruid, uid_t *suid)
+__getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)
 {
   error_t err;
-  uid_t eff, real, saved;
+  uid_t real, eff, saved;
 
   HURD_CRITICAL_BEGIN;
   __mutex_lock (&_hurd_id.lock);
@@ -42,8 +42,8 @@
       else
 	{
 	  real = _hurd_id.aux.uids[0];
-	  saved = _hurd_id.aux.nuids < 2 ? real :_hurd_id.aux.uids[1];
 	  eff = _hurd_id.gen.nuids < 1 ? real : _hurd_id.gen.uids[0];
+	  saved = _hurd_id.aux.nuids < 2 ? real : _hurd_id.aux.uids[1];
 	}
     }
 
@@ -53,8 +53,8 @@
   if (err)
     return __hurd_fail (err);
 
-  *euid = eff;
   *ruid = real;
+  *euid = eff;
   *suid = saved;
   return 0;
 }
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/ioctl.c glibc-2.3.6.new/sysdeps/mach/hurd/ioctl.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/ioctl.c	2005-10-23 01:55:46.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/ioctl.c	2006-05-06 12:34:21.601140328 +0100
@@ -80,7 +80,7 @@
   void *p;
 #endif
 
-  void *arg;
+  void *arg = NULL;
 
   error_t err;
 
@@ -131,7 +131,7 @@
 	  in (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
 	  in (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
 	}
-      else if (_IOC_INOUT (request) == IOC_VOID)
+      else if ((_IOC_INOUT (request) == IOC_VOID) && _IOT_COUNT0 (type))
 	{
 	  /* The RPC takes a single integer_t argument.
 	     Rather than pointing to the value, ARG is the value itself.  */
@@ -200,11 +200,15 @@
       return msg.header.RetCode;
     }
 
-  va_list ap;
+  if (_IOT_COUNT0 (type))
+    {
+      /* Data need either be sent, received, or even both.  */
+      va_list ap;
 
-  va_start (ap, request);
-  arg = va_arg (ap, void *);
-  va_end (ap);
+      va_start (ap, request);
+      arg = va_arg (ap, void *);
+      va_end (ap);
+    }
 
   {
     /* Check for a registered handler for REQUEST.  */
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/ioctl.c.orig glibc-2.3.6.new/sysdeps/mach/hurd/ioctl.c.orig
--- glibc-2.3.6.orig/sysdeps/mach/hurd/ioctl.c.orig	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/ioctl.c.orig	2005-10-23 01:55:46.000000000 +0100
@@ -0,0 +1,315 @@
+/* Copyright (C) 1992,93,94,95,96,97,99,2000,2002,2005
+	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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/signal.h>
+#include <stdarg.h>
+#include <mach/notify.h>
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include <hurd/ioctl.h>
+#include <mach/mig_support.h>
+
+#include <hurd/ioctls.defs>
+
+#define typesize(type)	(1 << (type))
+
+
+/* Perform the I/O control operation specified by REQUEST on FD.
+   The actual type and use of ARG and the return value depend on REQUEST.  */
+int
+__ioctl (int fd, unsigned long int request, ...)
+{
+#ifdef MACH_MSG_TYPE_CHAR
+  /* Map individual type fields to Mach IPC types.  */
+  static const int mach_types[] =
+    { MACH_MSG_TYPE_CHAR, MACH_MSG_TYPE_INTEGER_16, MACH_MSG_TYPE_INTEGER_32,
+      MACH_MSG_TYPE_INTEGER_64 };
+#define io2mach_type(count, type) \
+  ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 })
+#endif
+
+  /* Extract the type information encoded in the request.  */
+  unsigned int type = _IOC_TYPE (request);
+
+  /* Message buffer.  */
+#define msg_align(x) \
+  (((x) + sizeof (mach_msg_type_t) - 1) & ~(sizeof (mach_msg_type_t) - 1))
+  struct
+  {
+#ifdef MACH_MSG_TYPE_BIT
+    mig_reply_header_t header;
+    char data[3 * sizeof (mach_msg_type_t) +
+	     msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))) +
+	     msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type))) +
+	     _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+#else  /* Untyped Mach IPC format.  */
+    mig_reply_error_t header;
+    char data[_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)) +
+	     _IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)) +
+	     _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+    mach_msg_trailer_t trailer;
+#endif
+  } msg;
+  mach_msg_header_t *const m = &msg.header.Head;
+  mach_msg_id_t msgid;
+  unsigned int reply_size;
+#ifdef MACH_MSG_TYPE_BIT
+  mach_msg_type_t *t;
+#else
+  void *p;
+#endif
+
+  void *arg;
+
+  error_t err;
+
+  /* Send the RPC already packed up in MSG to IOPORT
+     and decode the return value.  */
+  error_t send_rpc (io_t ioport)
+    {
+      error_t err;
+#ifdef MACH_MSG_TYPE_BIT
+      mach_msg_type_t *t = &msg.header.RetCodeType;
+#else
+      void *p = &msg.header.RetCode;
+#endif
+
+      /* Marshal the request arguments into the message buffer.
+	 We must redo this work each time we retry the RPC after a SIGTTOU,
+	 because the reply message containing the EBACKGROUND error code
+	 clobbers the same message buffer also used for the request.  */
+
+      if (_IOC_INOUT (request) & IOC_IN)
+	{
+	  /* We don't want to advance ARG since it will be used to copy out
+             too if IOC_OUT is also set.  */
+	  void *argptr = arg;
+
+	  /* Pack an argument into the message buffer.  */
+	  void in (unsigned int count, enum __ioctl_datum type)
+	    {
+	      if (count > 0)
+		{
+		  const size_t len = count * typesize ((unsigned int) type);
+#ifdef MACH_MSG_TYPE_BIT
+		  void *p = &t[1];
+		  *t = io2mach_type (count, type);
+		  p = __mempcpy (p, argptr, len);
+		  p = (void *) (((uintptr_t) p + sizeof (*t) - 1)
+				& ~(sizeof (*t) - 1));
+		  t = p;
+#else
+		  p = __mempcpy (p, argptr, len);
+#endif
+		  argptr += len;
+		}
+	    }
+
+	  /* Pack the argument data.  */
+	  in (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
+	  in (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
+	  in (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
+	}
+      else if (_IOC_INOUT (request) == IOC_VOID)
+	{
+	  /* The RPC takes a single integer_t argument.
+	     Rather than pointing to the value, ARG is the value itself.  */
+#ifdef MACH_MSG_TYPE_BIT
+	  *t++ = io2mach_type (1, _IOTS (integer_t));
+	  *(integer_t *) t = (integer_t) arg;
+	  t = (void *) t + sizeof (integer_t);
+#else
+	  *(integer_t *) p = (integer_t) arg;
+	  p = (void *) p + sizeof (integer_t);
+#endif
+	}
+
+      memset (m, 0, sizeof *m);	/* Clear unused fields.  */
+      m->msgh_size = (
+#ifdef MACH_MSG_TYPE_BIT
+		      (char *) t
+#else
+		      (char *) p
+#endif
+		      - (char *) &msg);
+      m->msgh_remote_port = ioport;
+      m->msgh_local_port = __mig_get_reply_port ();
+      m->msgh_id = msgid;
+      m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
+				     MACH_MSG_TYPE_MAKE_SEND_ONCE);
+      err = _hurd_intr_rpc_mach_msg (m, MACH_SEND_MSG|MACH_RCV_MSG,
+				     m->msgh_size, sizeof (msg),
+				     m->msgh_local_port,
+				     MACH_MSG_TIMEOUT_NONE,
+				     MACH_PORT_NULL);
+      switch (err)
+	{
+	case MACH_MSG_SUCCESS:
+	  break;
+	case MACH_SEND_INVALID_REPLY:
+	case MACH_RCV_INVALID_NAME:
+	  __mig_dealloc_reply_port (m->msgh_local_port);
+	default:
+	  return err;
+	}
+
+      if ((m->msgh_bits & MACH_MSGH_BITS_COMPLEX))
+	{
+	  /* Allow no ports or VM.  */
+	  __mach_msg_destroy (m);
+	  /* Want to return a different error below for a different msgid.  */
+	  if (m->msgh_id == msgid + 100)
+	    return MIG_TYPE_ERROR;
+	}
+
+      if (m->msgh_id != msgid + 100)
+	return (m->msgh_id == MACH_NOTIFY_SEND_ONCE ?
+		MIG_SERVER_DIED : MIG_REPLY_MISMATCH);
+
+      if (m->msgh_size != reply_size &&
+	  m->msgh_size != sizeof msg.header)
+	return MIG_TYPE_ERROR;
+
+#ifdef MACH_MSG_TYPE_BIT
+      if (*(int *) &msg.header.RetCodeType !=
+	  ((union { mach_msg_type_t t; int i; })
+	   { t: io2mach_type (1, _IOTS (msg.header.RetCode)) }).i)
+	return MIG_TYPE_ERROR;
+#endif
+      return msg.header.RetCode;
+    }
+
+  va_list ap;
+
+  va_start (ap, request);
+  arg = va_arg (ap, void *);
+  va_end (ap);
+
+  {
+    /* Check for a registered handler for REQUEST.  */
+    ioctl_handler_t handler = _hurd_lookup_ioctl_handler (request);
+    if (handler)
+      {
+	/* This handler groks REQUEST.  Se lo puntamonos.  */
+	int save = errno;
+	int result = (*handler) (fd, request, arg);
+	if (result != -1 || errno != ENOTTY)
+	  return result;
+
+	/* The handler doesn't really grok this one.
+	   Try the normal RPC translation.  */
+	errno = save;
+      }
+  }
+
+  /* Compute the Mach message ID for the RPC from the group and command
+     parts of the ioctl request.  */
+  msgid = IOC_MSGID (request);
+
+  /* Compute the expected size of the reply.  There is a standard header
+     consisting of the message header and the reply code.  Then, for out
+     and in/out ioctls, there come the data with their type headers.  */
+  reply_size = sizeof msg.header;
+
+  if (_IOC_INOUT (request) & IOC_OUT)
+    {
+      inline void figure_reply (unsigned int count, enum __ioctl_datum type)
+	{
+	  if (count > 0)
+	    {
+#ifdef MACH_MSG_TYPE_BIT
+	      /* Add the size of the type and data.  */
+	      reply_size += sizeof (mach_msg_type_t) + typesize (type) * count;
+	      /* Align it to word size.  */
+	      reply_size += sizeof (mach_msg_type_t) - 1;
+	      reply_size &= ~(sizeof (mach_msg_type_t) - 1);
+#else
+	      reply_size += typesize (type) * count;
+#endif
+	    }
+	}
+      figure_reply (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
+      figure_reply (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
+      figure_reply (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
+    }
+
+  /* Marshal the arguments into the request message and make the RPC.
+     This wrapper function handles EBACKGROUND returns, turning them
+     into either SIGTTOU or EIO.  */
+  err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc));
+
+#ifdef MACH_MSG_TYPE_BIT
+  t = (mach_msg_type_t *) msg.data;
+#else
+  p = (void *) msg.data;
+#endif
+  switch (err)
+    {
+      /* Unpack the message buffer into the argument location.  */
+      int out (unsigned int count, unsigned int type,
+	       void *store, void **update)
+	{
+	  if (count > 0)
+	    {
+	      const size_t len = count * typesize (type);
+#ifdef MACH_MSG_TYPE_BIT
+	      union { mach_msg_type_t t; int i; } ipctype;
+	      ipctype.t = io2mach_type (count, type);
+	      if (*(int *) t != ipctype.i)
+		return 1;
+	      ++t;
+	      memcpy (store, t, len);
+	      if (update != NULL)
+		*update += len;
+	      t = (void *) (((uintptr_t) t + len + sizeof (*t) - 1)
+			    & ~(sizeof (*t) - 1));
+#else
+	      memcpy (store, p, len);
+	      p += len;
+	      if (update != NULL)
+		*update += len;
+#endif
+	    }
+	  return 0;
+	}
+
+    case 0:
+      if (m->msgh_size != reply_size ||
+	  ((_IOC_INOUT (request) & IOC_OUT) &&
+	   (out (_IOT_COUNT0 (type), _IOT_TYPE0 (type), arg, &arg) ||
+	    out (_IOT_COUNT1 (type), _IOT_TYPE1 (type), arg, &arg) ||
+	    out (_IOT_COUNT2 (type), _IOT_TYPE2 (type), arg, &arg))))
+	return __hurd_fail (MIG_TYPE_ERROR);
+      return 0;
+
+    case MIG_BAD_ID:
+    case EOPNOTSUPP:
+      /* The server didn't understand the RPC.  */
+      err = ENOTTY;
+    default:
+      return __hurd_fail (err);
+    }
+}
+
+weak_alias (__ioctl, ioctl)
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/setresgid.c glibc-2.3.6.new/sysdeps/mach/hurd/setresgid.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/setresgid.c	2005-02-18 00:08:17.000000000 +0000
+++ glibc-2.3.6.new/sysdeps/mach/hurd/setresgid.c	2006-05-06 12:32:21.348421520 +0100
@@ -1,5 +1,5 @@
-/* setresgid -- set effective group ID, real group ID, and saved-set group ID
-   Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+/* setresgid -- set real group ID, effective group ID, and saved-set group ID
+   Copyright (C) 2002, 2005, 2006 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
@@ -22,10 +22,10 @@
 #include <hurd.h>
 #include <hurd/id.h>
 
-/* Set the effective group ID, real group ID, and saved-set group ID,
-   of the calling process to EGID, RGID, and SGID, respectively.  */
+/* Set the real group ID, effective group ID, and saved-set group ID,
+   of the calling process to RGID, EGID, and SGID, respectively.  */
 int
-__setresgid (gid_t egid, gid_t rgid, gid_t sgid)
+__setresgid (gid_t rgid, gid_t egid, gid_t sgid)
 {
   auth_t newauth;
   error_t err;
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/setresuid.c glibc-2.3.6.new/sysdeps/mach/hurd/setresuid.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/setresuid.c	2005-02-18 00:08:16.000000000 +0000
+++ glibc-2.3.6.new/sysdeps/mach/hurd/setresuid.c	2006-05-06 12:32:21.349421368 +0100
@@ -1,5 +1,5 @@
-/* setresuid -- set effective user ID, real user ID, and saved-set user ID
-   Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+/* setresuid -- set real user ID, effective user ID, and saved-set user ID
+   Copyright (C) 2002, 2005, 2006 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
@@ -22,10 +22,10 @@
 #include <hurd.h>
 #include <hurd/id.h>
 
-/* Set the effective user ID, real user ID, and saved-set user ID,
-   of the calling process to EUID, RUID, and SUID, respectively.  */
+/* Set the real user ID, effective user ID, and saved-set user ID,
+   of the calling process to RUID, EUID, and SUID, respectively.  */
 int
-__setresuid (uid_t euid, uid_t ruid, uid_t suid)
+__setresuid (uid_t ruid, uid_t euid, uid_t suid)
 {
   auth_t newauth;
   error_t err;
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/shmat.c glibc-2.3.6.new/sysdeps/mach/hurd/shmat.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/shmat.c	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/shmat.c	2006-05-06 12:34:35.341051544 +0100
@@ -0,0 +1,78 @@
+/* Copyright (C) 2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <utime.h>
+#include <stdio.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "sysvshm.h"
+
+/* Attach the shared memory segment associated with SHMID to the data
+   segment of the calling process.  SHMADDR and SHMFLG determine how
+   and where the segment is attached.  */
+void *
+__shmat (int shmid, const void *shmaddr, int shmflg)
+{
+  error_t err;
+  char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX];
+  int fd;
+  void *addr;
+  struct stat statbuf;
+  int res;
+
+  sprintf (filename, SHM_DIR SHM_NAMEPRI, shmid);
+  fd = __open (filename, (shmflg & SHM_RDONLY) ? O_RDONLY : O_RDWR);
+  if (fd < 0)
+    {
+      if (errno == ENOENT)
+	errno = EINVAL;
+      return (void *) -1;
+    }
+
+  res = __fstat (fd, &statbuf);
+  if (res < 0)
+    {
+      __close (fd);
+      return (void *) -1;
+    }
+
+  addr = __mmap ((void *) shmaddr, statbuf.st_size,
+		 PROT_READ | ((shmflg & SHM_RDONLY) ? 0 : PROT_WRITE),
+		 MAP_SHARED, fd, 0);
+  __close (fd);
+  if (addr == MAP_FAILED)
+    return (void *) -1;
+
+  err = __sysvshm_add (addr, statbuf.st_size);
+  if (err)
+    {
+      munmap (addr, statbuf.st_size);
+      return (void *) -1;
+    }
+
+  return addr;
+}
+
+weak_alias(__shmat, shmat)
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/shmctl.c glibc-2.3.6.new/sysdeps/mach/hurd/shmctl.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/shmctl.c	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/shmctl.c	2006-05-06 12:34:35.342051392 +0100
@@ -0,0 +1,132 @@
+/* Copyright (C) 2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "sysvshm.h"
+
+/* Provide operations to control over shared memory segments.  */
+int
+__shmctl (int id, int cmd, struct shmid_ds *buf)
+{
+  error_t err = 0;
+  int fd;
+  int res;
+  char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX];
+  struct stat statbuf;
+
+  sprintf (filename, SHM_DIR SHM_NAMEPRI, id);
+  /* SysV requires read access for IPC_STAT.  */
+  fd = __open (filename, O_NORW);
+  if (fd < 0)
+    {
+      if (errno == ENOENT)
+	errno = EINVAL;
+      return -1;
+    }
+
+  res = __fstat (fd, &statbuf);
+  if (res < 0)
+    {
+      err = errno;
+      __close (fd);
+      errno = err;
+      return -1;
+    }
+  
+  switch (cmd)
+    {
+    case IPC_STAT:
+
+      buf->shm_perm.__key = id;
+      buf->shm_perm.uid = statbuf.st_uid;
+      buf->shm_perm.gid = statbuf.st_gid;
+
+      /* We do not support the creator.  */
+      buf->shm_perm.cuid = statbuf.st_uid;
+      buf->shm_perm.cgid = statbuf.st_gid;
+
+      /* We just want the protection bits.  */
+      buf->shm_perm.mode = statbuf.st_mode & 0777;
+      /* Hopeless.  We do not support a sequence number.  */
+      buf->shm_perm.__seq = statbuf.st_ino;
+      buf->shm_segsz = statbuf.st_size;
+
+      /* Hopeless.  We do not support any of these.  */
+      buf->shm_atime = statbuf.st_atime;
+      buf->shm_dtime = statbuf.st_mtime;
+      /* Well, this comes at least close.  */
+      buf->shm_ctime = statbuf.st_ctime;
+
+      /* We do not support the PID.  */
+      buf->shm_cpid = 0;
+      buf->shm_lpid = 0;
+
+      if (statbuf.st_mode & S_IMMAP0)
+        buf->shm_nattch = 0;
+      else
+        /* 42 is the answer.  Of course this is bogus, but for most
+	   applications, this should be fine.  */
+        buf->shm_nattch = 42;
+
+      break;
+
+    case IPC_SET:
+      if (statbuf.st_uid != buf->shm_perm.uid
+	  || statbuf.st_gid != buf->shm_perm.gid)
+	{
+	  res = __fchown (fd,
+			  (statbuf.st_uid != buf->shm_perm.uid)
+			  ? buf->shm_perm.uid : -1,
+			  (statbuf.st_gid != buf->shm_perm.gid)
+			  ? buf->shm_perm.gid : -1);
+	  if (res < 0)
+	    err = errno;
+	}
+
+      if (!err && statbuf.st_mode & 0777 != buf->shm_perm.mode & 0777)
+	{
+	  res = __fchmod (fd, (statbuf.st_mode & ~0777)
+			  | (buf->shm_perm.mode & 0777));
+	  if (res < 0)
+	    err = errno;
+	}
+      break;
+
+    case IPC_RMID:
+      res = __unlink (filename);
+      /* FIXME: Check error (mapping ENOENT to EINVAL).  */
+      break;
+
+    default:
+      err = EINVAL;
+    }
+
+  __close (fd);
+  errno = err;
+  return err ? -1 : 0;
+}
+
+weak_alias(__shmctl, shmctl)
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/shmdt.c glibc-2.3.6.new/sysdeps/mach/hurd/shmdt.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/shmdt.c	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/shmdt.c	2006-05-06 12:34:35.343051240 +0100
@@ -0,0 +1,51 @@
+/* Copyright (C) 2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include "sysvshm.h"
+
+/* Detach shared memory segment starting at address specified by
+   SHMADDR from the caller's data segment.  */
+int
+__shmdt (const void *shmaddr)
+{
+  error_t err;
+  size_t size;
+
+  err = __sysvshm_remove ((void *) shmaddr, &size);
+  if (err)
+    {
+      errno = err;
+      return -1;
+    }
+
+  __munmap ((void *) shmaddr, size);
+  return 0;
+}
+
+weak_alias(__shmdt, shmdt)
diff -Naur glibc-2.3.6.orig/sysdeps/mach/hurd/shmget.c glibc-2.3.6.new/sysdeps/mach/hurd/shmget.c
--- glibc-2.3.6.orig/sysdeps/mach/hurd/shmget.c	1970-01-01 01:00:00.000000000 +0100
+++ glibc-2.3.6.new/sysdeps/mach/hurd/shmget.c	2006-05-06 12:34:35.344051088 +0100
@@ -0,0 +1,245 @@
+/* Copyright (C) 2005 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <hurd/fd.h>
+
+#include "sysvshm.h"
+
+/* Create a new shared memory segment file without linking it into the
+   filesystem.  Return the directory and file ports in R_DIR and R_FILE.  */
+static error_t
+create_shm_file (size_t size, int flags, file_t *r_dir, file_t *r_file)
+{
+  error_t err;
+  file_t dir;
+  file_t file;
+
+  flags &= 0777;
+
+  /* Get a port to the directory that will contain the file.  */
+  dir = __file_name_lookup (SHM_DIR, 0, 0);
+  if (dir == MACH_PORT_NULL)
+    return errno;
+
+  /* Create an unnamed file in the directory.  */
+  err = __dir_mkfile (dir, O_RDWR, flags, &file);
+  if (err)
+    {
+      __mach_port_deallocate (__mach_task_self (), dir);
+      return err;
+    }
+
+  err = __file_set_size (file, size);
+  if (err)
+    {
+      __mach_port_deallocate (__mach_task_self (), file);
+      __mach_port_deallocate (__mach_task_self (), dir);
+
+      return err;
+    }
+
+  *r_dir = dir;
+  *r_file = file;
+
+  return 0;
+}
+  
+
+/* Open the shared memory segment *R_KEY and return a file descriptor
+   to it in R_FD.  If KEY is IPC_PRIVATE, use a private key and return
+   it in R_KEY.  */
+static error_t
+get_exclusive (int shmflags, size_t size, key_t *r_key, int *r_fd)
+{
+  error_t err;
+  file_t dir;
+  file_t file;
+  char filename[SHM_NAMEMAX];
+  key_t key = *r_key;
+  bool is_private;
+
+  /* Create the shared memory segment.  */
+  err = create_shm_file (size, shmflags, &dir, &file);
+  if (err)
+    return err;
+
+  if (key == IPC_PRIVATE)
+    {
+      is_private = true;
+      key = SHM_PRIV_KEY_START;
+
+      /* Try to link the shared memory segment into the filesystem
+	 (exclusively).  Private segments have negative keys.  */
+      do
+	{
+	  sprintf (filename, SHM_NAMEPRI, key);
+	  err = __dir_link (dir, file, filename, 1);
+	  if (!err)
+	    {
+	      /* We are done.  */
+	      *r_key = key;
+	      break;
+	    }
+	  else if (err == EEXIST)
+	    {
+	      /* Check if we ran out of keys.  If not, try again with new
+		 key.  */
+	      if (key == SHM_PRIV_KEY_END)
+		err = ENOSPC;
+	      else
+		err = 0;
+
+	      key--;
+	    }
+	}
+      while (!err);
+    }
+  else
+    {
+      /* Try to link the shared memory segment into the filesystem
+	 (exclusively) under the given key.  */
+      sprintf (filename, SHM_NAMEPRI, key);
+      err = __dir_link (dir, file, filename, 1);
+    }
+
+  __mach_port_deallocate (__mach_task_self (), dir);
+
+  if (!err)
+    {
+      int fd;
+
+      /* Get a file descriptor for that port.  */
+      fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */
+      if (fd < 0)
+	err = errno;
+      else
+	*r_fd = fd;
+    }
+
+  return err;
+}
+
+
+/* Open the shared memory segment KEY (creating it if it doesn't yet
+   exist) and return a file descriptor to it in R_FD.  */
+static error_t
+get_shared (int shmflags, size_t size, key_t key, int *r_fd)
+{
+  error_t err = 0;
+  char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX];
+  int fd = -1;
+  int create_flag;
+
+  create_flag = (shmflags & IPC_CREAT) ? O_CREAT : 0;
+  sprintf (filename, SHM_DIR SHM_NAMEPRI, key);
+
+  do
+    {
+      fd = __open (filename, O_NORW | create_flag, shmflags & 0777);
+
+      if (fd < 0 && errno != ENOENT)
+	/* We give up.  */
+	return errno;
+      else if (fd >= 0)
+	{
+	  int res;
+	  struct stat statbuf;
+
+	  /* Check the size (we only need to do this if we did not
+	     create the shared memory segment file ourselves).  */
+	  res = __fstat (fd, &statbuf);
+	  if (res < 0)
+	    {
+	      err = errno;
+	      __close (fd);
+	      return err;
+	    }
+
+	  if (statbuf.st_size < size)
+	    {
+	      __close (fd);
+	      return EINVAL;
+	    }
+	}	  
+      else
+	{
+	  /* The memory segment doesn't exist.  */
+	  if (create_flag)
+	    {
+	      /* Try to create it exclusively.  */
+	      err = get_exclusive (shmflags, size, &key, &fd);
+	      if (err == EEXIST)
+		/* If somebody created it in the meanwhile, just try again.  */
+		err = 0;
+	    }
+	  else
+	    err = ENOENT;
+	}
+    }
+  while (fd < 0 && !err);
+
+  if (!err)
+    *r_fd = fd;
+  else
+    *r_fd = -1;
+
+  return err;
+}
+
+/* Return an identifier for an shared memory segment of at least size
+   SIZE which is associated with KEY.  */
+int
+__shmget (key_t key, size_t size, int shmflags)
+{
+  error_t err;
+  int fd;
+
+  if (key == IPC_PRIVATE || shmflags & IPC_EXCL)
+    /* An exclusive shared memory segment must be created.  */
+    err = get_exclusive (shmflags, size, &key, &fd);
+  else
+    err = get_shared (shmflags, size, key, &fd);
+
+  if (err)
+    {
+      errno = err;
+      return -1;
+    }
+
+  /* From here, we can't fail.  That's important, as otherwise we
+     would need to unlink the file if we created it (in that case, the
+     code above would have to be changed to pass a "created" flag down
+     to the caller).  */
+
+  __close (fd);
+
+  return key;
+}
+
+weak_alias(__shmget, shmget)

