summary refs log tree commit diff
path: root/sysdeps/mach/hurd
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-02-18 01:27:10 +0000
committerRoland McGrath <roland@gnu.org>1995-02-18 01:27:10 +0000
commit28f540f45bbacd939bfd07f213bcad2bf730b1bf (patch)
tree15f07c4c43d635959c6afee96bde71fb1b3614ee /sysdeps/mach/hurd
downloadglibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.gz
glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.xz
glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.zip
initial import
Diffstat (limited to 'sysdeps/mach/hurd')
-rw-r--r--sysdeps/mach/hurd/.cvsignore4
-rw-r--r--sysdeps/mach/hurd/Dist3
-rw-r--r--sysdeps/mach/hurd/Implies2
-rw-r--r--sysdeps/mach/hurd/Makefile132
-rw-r--r--sysdeps/mach/hurd/Subdirs1
-rw-r--r--sysdeps/mach/hurd/_exit.c54
-rw-r--r--sysdeps/mach/hurd/accept.c71
-rw-r--r--sysdeps/mach/hurd/access.c138
-rw-r--r--sysdeps/mach/hurd/adjtime.c53
-rw-r--r--sysdeps/mach/hurd/alpha/exc2signal.c76
-rw-r--r--sysdeps/mach/hurd/alpha/longjmp-ctx.c38
-rw-r--r--sysdeps/mach/hurd/alpha/longjmp-ts.c41
-rw-r--r--sysdeps/mach/hurd/alpha/sigcontext.h65
-rw-r--r--sysdeps/mach/hurd/alpha/sigreturn.c212
-rw-r--r--sysdeps/mach/hurd/alpha/trampoline.c286
-rw-r--r--sysdeps/mach/hurd/bind.c102
-rw-r--r--sysdeps/mach/hurd/brk.c130
-rw-r--r--sysdeps/mach/hurd/chdir.c45
-rw-r--r--sysdeps/mach/hurd/chflags.c38
-rw-r--r--sysdeps/mach/hurd/chmod.c40
-rw-r--r--sysdeps/mach/hurd/chown.c41
-rw-r--r--sysdeps/mach/hurd/chroot.c45
-rw-r--r--sysdeps/mach/hurd/close.c36
-rw-r--r--sysdeps/mach/hurd/closedir.c52
-rwxr-xr-xsysdeps/mach/hurd/configure21
-rw-r--r--sysdeps/mach/hurd/configure.in19
-rw-r--r--sysdeps/mach/hurd/connect.c75
-rw-r--r--sysdeps/mach/hurd/defs.c85
-rw-r--r--sysdeps/mach/hurd/dirstream.h40
-rw-r--r--sysdeps/mach/hurd/dup2.c114
-rw-r--r--sysdeps/mach/hurd/err_hurd.sub11
-rw-r--r--sysdeps/mach/hurd/errlist.awk77
-rw-r--r--sysdeps/mach/hurd/errlist.c93
-rw-r--r--sysdeps/mach/hurd/errnos.awk157
-rw-r--r--sysdeps/mach/hurd/errnos.h266
-rw-r--r--sysdeps/mach/hurd/execve.c45
-rw-r--r--sysdeps/mach/hurd/fchdir.c45
-rw-r--r--sysdeps/mach/hurd/fchflags.c36
-rw-r--r--sysdeps/mach/hurd/fchmod.c38
-rw-r--r--sysdeps/mach/hurd/fchown.c39
-rw-r--r--sysdeps/mach/hurd/fcntl.c159
-rw-r--r--sysdeps/mach/hurd/fcntlbits.h178
-rw-r--r--sysdeps/mach/hurd/fdopen.c69
-rw-r--r--sysdeps/mach/hurd/fexecve.c34
-rw-r--r--sysdeps/mach/hurd/flock.c39
-rw-r--r--sysdeps/mach/hurd/fork.c574
-rw-r--r--sysdeps/mach/hurd/fstat.c38
-rw-r--r--sysdeps/mach/hurd/fsync.c33
-rw-r--r--sysdeps/mach/hurd/ftruncate.c34
-rw-r--r--sysdeps/mach/hurd/getcwd.c250
-rw-r--r--sysdeps/mach/hurd/getdents.c62
-rw-r--r--sysdeps/mach/hurd/getdtsz.c39
-rw-r--r--sysdeps/mach/hurd/getegid.c58
-rw-r--r--sysdeps/mach/hurd/geteuid.c58
-rw-r--r--sysdeps/mach/hurd/getgid.c55
-rw-r--r--sysdeps/mach/hurd/getgroups.c68
-rw-r--r--sysdeps/mach/hurd/gethostid.c33
-rw-r--r--sysdeps/mach/hurd/gethostname.c48
-rw-r--r--sysdeps/mach/hurd/getitimer.c104
-rw-r--r--sysdeps/mach/hurd/getlogin.c40
-rw-r--r--sysdeps/mach/hurd/getpeername.c59
-rw-r--r--sysdeps/mach/hurd/getpgid.c44
-rw-r--r--sysdeps/mach/hurd/getpid.c32
-rw-r--r--sysdeps/mach/hurd/getppid.c34
-rw-r--r--sysdeps/mach/hurd/getpriority.c73
-rw-r--r--sysdeps/mach/hurd/getrlimit.c46
-rw-r--r--sysdeps/mach/hurd/getsockname.c58
-rw-r--r--sysdeps/mach/hurd/getsockopt.c53
-rw-r--r--sysdeps/mach/hurd/getuid.c55
-rw-r--r--sysdeps/mach/hurd/hppa/sigcontext.h86
-rw-r--r--sysdeps/mach/hurd/hppa/trampoline.c258
-rw-r--r--sysdeps/mach/hurd/i386/exc2signal.c165
-rw-r--r--sysdeps/mach/hurd/i386/init-fault.c41
-rw-r--r--sysdeps/mach/hurd/i386/longjmp-ctx.c35
-rw-r--r--sysdeps/mach/hurd/i386/longjmp-ts.c39
-rw-r--r--sysdeps/mach/hurd/i386/sigcontext.h106
-rw-r--r--sysdeps/mach/hurd/i386/sigreturn.c126
-rw-r--r--sysdeps/mach/hurd/i386/trampoline.c271
-rw-r--r--sysdeps/mach/hurd/ioctl.c242
-rw-r--r--sysdeps/mach/hurd/ioctls.h323
-rw-r--r--sysdeps/mach/hurd/isatty.c39
-rw-r--r--sysdeps/mach/hurd/kill.c106
-rw-r--r--sysdeps/mach/hurd/libc-ldscript5
-rw-r--r--sysdeps/mach/hurd/link.c60
-rw-r--r--sysdeps/mach/hurd/listen.c36
-rw-r--r--sysdeps/mach/hurd/local_lim.h40
-rw-r--r--sysdeps/mach/hurd/lseek.c35
-rw-r--r--sysdeps/mach/hurd/lstat.c40
-rw-r--r--sysdeps/mach/hurd/mig-reply.c86
-rw-r--r--sysdeps/mach/hurd/mips/exc2signal.c98
-rw-r--r--sysdeps/mach/hurd/mips/init-fault.c41
-rw-r--r--sysdeps/mach/hurd/mips/longjmp-ctx.c41
-rw-r--r--sysdeps/mach/hurd/mips/longjmp-ts.c45
-rw-r--r--sysdeps/mach/hurd/mips/sigcontext.h71
-rw-r--r--sysdeps/mach/hurd/mips/sigreturn.c169
-rw-r--r--sysdeps/mach/hurd/mips/trampoline.c260
-rw-r--r--sysdeps/mach/hurd/mkdir.c41
-rw-r--r--sysdeps/mach/hurd/mknod.c114
-rw-r--r--sysdeps/mach/hurd/mmap.c105
-rw-r--r--sysdeps/mach/hurd/open.c51
-rw-r--r--sysdeps/mach/hurd/opendir.c60
-rw-r--r--sysdeps/mach/hurd/pipe.c99
-rw-r--r--sysdeps/mach/hurd/ptrace.c392
-rw-r--r--sysdeps/mach/hurd/read.c34
-rw-r--r--sysdeps/mach/hurd/readdir.c90
-rw-r--r--sysdeps/mach/hurd/readlink.c76
-rw-r--r--sysdeps/mach/hurd/reboot.c51
-rw-r--r--sysdeps/mach/hurd/recv.c60
-rw-r--r--sysdeps/mach/hurd/recvfrom.c85
-rw-r--r--sysdeps/mach/hurd/rename.c47
-rw-r--r--sysdeps/mach/hurd/rewinddir.c31
-rw-r--r--sysdeps/mach/hurd/rmdir.c41
-rw-r--r--sysdeps/mach/hurd/sbrk.c42
-rw-r--r--sysdeps/mach/hurd/seekdir.c35
-rw-r--r--sysdeps/mach/hurd/select.c275
-rw-r--r--sysdeps/mach/hurd/send.c40
-rw-r--r--sysdeps/mach/hurd/sendto.c60
-rw-r--r--sysdeps/mach/hurd/setegid.c67
-rw-r--r--sysdeps/mach/hurd/seteuid.c67
-rw-r--r--sysdeps/mach/hurd/setgid.c76
-rw-r--r--sysdeps/mach/hurd/setgroups.c63
-rw-r--r--sysdeps/mach/hurd/sethostid.c31
-rw-r--r--sysdeps/mach/hurd/sethostname.c34
-rw-r--r--sysdeps/mach/hurd/setitimer.c332
-rw-r--r--sysdeps/mach/hurd/setlogin.c32
-rw-r--r--sysdeps/mach/hurd/setpgid.c57
-rw-r--r--sysdeps/mach/hurd/setpriority.c85
-rw-r--r--sysdeps/mach/hurd/setregid.c71
-rw-r--r--sysdeps/mach/hurd/setreuid.c71
-rw-r--r--sysdeps/mach/hurd/setrlimit.c58
-rw-r--r--sysdeps/mach/hurd/setsid.c59
-rw-r--r--sysdeps/mach/hurd/setsockopt.c40
-rw-r--r--sysdeps/mach/hurd/settimeofday.c56
-rw-r--r--sysdeps/mach/hurd/setuid.c76
-rw-r--r--sysdeps/mach/hurd/shutdown.c40
-rw-r--r--sysdeps/mach/hurd/sigaction.c84
-rw-r--r--sysdeps/mach/hurd/sigaltstack.c62
-rw-r--r--sysdeps/mach/hurd/sigpending.c46
-rw-r--r--sysdeps/mach/hurd/sigprocmask.c87
-rw-r--r--sysdeps/mach/hurd/sigstack.c46
-rw-r--r--sysdeps/mach/hurd/sigsuspend.c81
-rw-r--r--sysdeps/mach/hurd/socket.c57
-rw-r--r--sysdeps/mach/hurd/socketpair.c93
-rw-r--r--sysdeps/mach/hurd/start.c316
-rw-r--r--sysdeps/mach/hurd/stat.c40
-rw-r--r--sysdeps/mach/hurd/statbuf.h119
-rw-r--r--sysdeps/mach/hurd/stdio_init.c63
-rw-r--r--sysdeps/mach/hurd/symlink.c68
-rw-r--r--sysdeps/mach/hurd/sync.c33
-rw-r--r--sysdeps/mach/hurd/sys/param.h135
-rw-r--r--sysdeps/mach/hurd/sysd-stdio.c237
-rw-r--r--sysdeps/mach/hurd/telldir.c31
-rw-r--r--sysdeps/mach/hurd/truncate.c42
-rw-r--r--sysdeps/mach/hurd/ttyname.c38
-rw-r--r--sysdeps/mach/hurd/umask.c34
-rw-r--r--sysdeps/mach/hurd/uname.c31
-rw-r--r--sysdeps/mach/hurd/unlink.c46
-rw-r--r--sysdeps/mach/hurd/utimes.c43
-rw-r--r--sysdeps/mach/hurd/wait4.c40
-rw-r--r--sysdeps/mach/hurd/write.c35
160 files changed, 13208 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/.cvsignore b/sysdeps/mach/hurd/.cvsignore
new file mode 100644
index 0000000000..1f69fd919a
--- /dev/null
+++ b/sysdeps/mach/hurd/.cvsignore
@@ -0,0 +1,4 @@
+*.gz *.Z *.tar *.tgz
+=*
+TODO COPYING* AUTHORS copyr-* copying.*
+glibc-*
diff --git a/sysdeps/mach/hurd/Dist b/sysdeps/mach/hurd/Dist
new file mode 100644
index 0000000000..89a6b56f32
--- /dev/null
+++ b/sysdeps/mach/hurd/Dist
@@ -0,0 +1,3 @@
+errnos.awk errlist.awk err_hurd.sub
+libc-ldscript
+
diff --git a/sysdeps/mach/hurd/Implies b/sysdeps/mach/hurd/Implies
new file mode 100644
index 0000000000..b6e4d864d5
--- /dev/null
+++ b/sysdeps/mach/hurd/Implies
@@ -0,0 +1,2 @@
+# The Hurd provides a rough superset of the functionality of 4.4 BSD.
+unix/bsd/bsd4.4
diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile
new file mode 100644
index 0000000000..70b6ec5d49
--- /dev/null
+++ b/sysdeps/mach/hurd/Makefile
@@ -0,0 +1,132 @@
+# Copyright (C) 1993, 1994, 1995 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 Library General Public License
+# as published by the Free Software Foundation; either version 2 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
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB.  If
+# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+# Cambridge, MA 02139, USA.
+
+# Get mach-srcdir defined.
+old-in-Makerules := $(in-Makerules)
+in-Makerules :=
+include $(..)sysdeps/mach/Makefile
+in-Makerules := $(old-in-Makerules)
+
+
+ifndef hurd-srcdir-computed
+hurd-srcdir-computed := yes
+
+# If we were configured with `--with-hurd=DIR', then config.make sets
+# hurd-srcdir to DIR.  Otherwise guess we are in a big source tree.
+ifndef hurd-srcdir
+hurd-srcdir = ../hurd
+endif
+
+# hurd-srcdir is now set to the logical directory name.  This name might be
+# relative to $(objdir), might be relative to the source directory $(..), or
+# might be absolute.  We choose among these possibilities by looking for a
+# canonical file in each of those places (in that order).
+f := hurd/hurd_types.defs # Random file that identifies the Hurd source dir.
+f := $(strip $f)
+hurd-srcdir := $(firstword $(patsubst %/$f,%,$(wildcard $(addsuffix /$f,\
+	       $(objpfx)$(hurd-srcdir) $(..)$(hurd-srcdir)))) $(hurd-srcdir))
+
+endif	# ! hurd-srcdir-computed
+
+ifdef in-Makerules
+
+# For the time being, elide directories where nothing at all works.
+subdirs := $(filter-out sunrpc manual,$(subdirs)) # XXX
+
+# Look for header files in hurd/ under the top-level library source directory.
+includes += -I$(..)hurd
+
+# When compiling, use the Hurd header files directly from the sources.
+includes += -I$(hurd-srcdir)
+
+# When compiling, find cthreads.h in the Hurd cthreads source.
+# This directory has some other (private) header file with
+# conflicting names, so we put it last.
+last-includes += -I$(hurd-srcdir)/libthreads
+
+# Find the Hurd header files in the Hurd source.
+vpath hurd/%.h $(hurd-srcdir)
+
+# Do not use any assembly code from sysdeps/unix (and subdirectories).
+# This bypasses all the system call stubs and uses any existing posix or
+# generic C files instead.
+inhibit-sysdep-asm += unix*
+
+# Don't try to generate anything from the installed Unix system and its
+# libraries.  That is only of use when building for a Unix system, so as to
+# be compatible with some existing binaries for that system.
+inhibit-glue = yes
+
+
+ifeq (,$(filter mach hurd,$(subdir)))
+# Subdirectories other than hurd/ might use the generated Hurd headers.
+# So make sure we get a chance to run in hurd/ to make them before all else.
+# (But we don't want to do this in mach/, because hurd/ needs some things
+# there, and we know mach/ doesn't need anything from hurd/.)
+
+ifdef objpfx
+hurd-objpfx = $(objpfx)
+else
+hurd-objpfx = $(..)hurd/
+endif
+
+# These are all the generated headers that <hurd.h> includes.
+before-compile += $(patsubst %,$(hurd-objpfx)hurd/%.h,io fs process)
+$(patsubst %,$(hurd-objpfx)hurd/%.%,io fs process):
+	$(MAKE) -C $(..)hurd generated no_deps=t
+endif
+
+# Generate errnos.h and sys_errlist.c from the section of the manual that
+# lists all the errno codes.
+
+errno.texinfo = $(..)manual/errno.texi
+
+hurd = $(..)sysdeps/mach/hurd
+
+$(hurd)/errnos.h: $(objpfx)stamp-errnos ;
+$(objpfx)stamp-errnos: $(hurd)/errnos.awk $(errno.texinfo) \
+		       $(mach-srcdir)/mach/message.h \
+		       $(mach-srcdir)/mach/kern_return.h \
+		       $(mach-srcdir)/mach/mig_errors.h \
+		       $(mach-srcdir)/device/device_types.h
+	gawk -f $^ > $(hurd)/errnos.h-tmp
+# Make it unwritable so noone will edit it by mistake.
+	-chmod a-w $(hurd)/errnos.h-tmp
+	./$(..)move-if-change $(hurd)/errnos.h-tmp $(hurd)/errnos.h
+	test -d CVS && cvs commit -m'Regenerated from $^' $@
+	touch $@
+
+$(hurd)/errlist.c: $(hurd)/errlist.awk $(errno.texinfo)
+	gawk -f $^ > $@-tmp
+# Make it unwritable so noone will edit it by mistake.
+	-chmod a-w $@-tmp
+	mv -f $@-tmp $@
+	test -d CVS && cvs commit -m'Regenerated from $^' $@
+
+# We install the real libc.a as libcrt.a and as libc.a we install a linker
+# script which does -( -lcrt -lmachuser -lhurduser -).
+
+libc-name = crt
+
+ifeq (,$(subdir))
+install-others += $(libdir)/libc.a
+$(libdir)/libc.a: $(hurd)/libc-ldscript; $(do-install)
+endif
+
+
+endif	# in-Makerules
diff --git a/sysdeps/mach/hurd/Subdirs b/sysdeps/mach/hurd/Subdirs
new file mode 100644
index 0000000000..16b8348437
--- /dev/null
+++ b/sysdeps/mach/hurd/Subdirs
@@ -0,0 +1 @@
+hurd
diff --git a/sysdeps/mach/hurd/_exit.c b/sysdeps/mach/hurd/_exit.c
new file mode 100644
index 0000000000..fd56791ee8
--- /dev/null
+++ b/sysdeps/mach/hurd/_exit.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <sysdep.h>
+#include <sys/wait.h>
+
+void
+_hurd_exit (int status)
+{
+  /* Give the proc server our exit status.  */
+  __USEPORT (PROC, __proc_mark_exit (port, status));
+
+  /* Commit suicide.  */
+  __task_terminate (__mach_task_self ());
+
+  /* Perhaps the cached mach_task_self was bogus.  */
+  __task_terminate ((__mach_task_self) ());
+  
+  /* This sucker really doesn't want to die.  */
+  while (1)
+    {
+#ifdef LOSE
+      LOSE;
+#else
+      volatile const int zero = 0, one = 1;
+      volatile int lossage = one / zero;
+#endif
+    }
+}
+
+void
+DEFUN(_exit, (status), int status)
+{
+  _hurd_exit (W_EXITCODE (status, 0));
+}
diff --git a/sysdeps/mach/hurd/accept.c b/sysdeps/mach/hurd/accept.c
new file mode 100644
index 0000000000..48402b1227
--- /dev/null
+++ b/sysdeps/mach/hurd/accept.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/socket.h>
+#include <hurd/socket.h>
+#include <fcntl.h>
+#include <string.h>
+
+/* Await a connection on socket FD.
+   When a connection arrives, open a new socket to communicate with it,
+   set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
+   peer and *ADDR_LEN to the address's actual length, and return the
+   new socket's descriptor, or -1 for errors.  */
+int
+DEFUN(accept, (fd, addr, addr_len),
+      int fd AND struct sockaddr *addr AND size_t *addr_len)
+{
+  error_t err;
+  socket_t new;
+  addr_port_t aport;
+  char *buf = (char *) addr;
+  mach_msg_type_number_t buflen = *addr_len;
+  int type;
+
+  if (err = HURD_DPORT_USE (fd, __socket_accept (port, &new, &aport)))
+    return __hurd_dfail (fd, err);
+
+  if (addr != NULL)
+    err = __socket_whatis_address (aport, &type, &buf, &buflen);
+  __mach_port_deallocate (__mach_task_self (), aport);
+
+  if (err)
+    {
+      __mach_port_deallocate (__mach_task_self (), new);
+      return __hurd_dfail (fd, err);
+    }
+
+  if (addr != NULL)
+    {
+      if (buf != (char *) addr)
+	{
+	  if (*addr_len < buflen)
+	    *addr_len = buflen;
+	  memcpy (addr, buf, *addr_len);
+	  __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+	}
+
+      addr->sa_family = type;
+    }
+
+  return _hurd_intern_fd (new, O_IGNORE_CTTY, 1);
+}
diff --git a/sysdeps/mach/hurd/access.c b/sysdeps/mach/hurd/access.c
new file mode 100644
index 0000000000..90938060e0
--- /dev/null
+++ b/sysdeps/mach/hurd/access.c
@@ -0,0 +1,138 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/id.h>
+#include <fcntl.h>
+
+/* Test for access to FILE by our real user and group IDs.  */
+int
+DEFUN(__access, (file, type), CONST char *file AND int type)
+{
+  error_t err;
+  file_t crdir, cwdir, rcrdir, rcwdir, io;
+  struct hurd_userlink crdir_ulink, cwdir_ulink;
+  int flags, allowed;
+  mach_port_t ref;
+
+  HURD_CRITICAL_BEGIN;
+
+  __mutex_lock (&_hurd_id.lock);
+  /* Get _hurd_id up to date.  */
+  if (err = _hurd_check_ids ())
+    goto lose;
+
+  if (_hurd_id.rid_auth == MACH_PORT_NULL)
+    {
+      /* Set up _hurd_id.rid_auth.  This is a special auth server port
+	 which uses the real uid and gid (the first aux uid and gid) as
+	 the only effective uid and gid.  */
+
+      if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
+	{
+	  /* We do not have a real UID and GID.  Lose, lose, lose!  */
+	  err = EGRATUITOUS;
+	  goto lose;
+	}
+
+      /* Create a new auth port using our real UID and GID (the first
+	 auxiliary UID and GID) as the only effective IDs.  */
+      if (err = __USEPORT (AUTH,
+			   __auth_makeauth (port,
+					    NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+					    _hurd_id.aux.uids, 1,
+					    _hurd_id.aux.gids, 1,
+					    _hurd_id.aux.uids,
+					    _hurd_id.aux.nuids,
+					    _hurd_id.aux.gids,
+					    _hurd_id.aux.ngids,
+					    &_hurd_id.rid_auth)))
+	goto lose;
+    }
+
+  /* Get a port to our root directory, authenticated with the real IDs.  */
+  crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink);
+  ref = __mach_reply_port ();
+  err = __io_reauthenticate (crdir, ref, MACH_MSG_TYPE_MAKE_SEND);
+  if (!err)
+    err = __auth_user_authenticate (_hurd_id.rid_auth,
+				    crdir,
+				    ref, MACH_MSG_TYPE_MAKE_SEND,
+				    &rcrdir);
+  _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir);
+  __mach_port_destroy (__mach_task_self (), ref);
+
+  if (!err)
+    {
+      /* Get a port to our current working directory, authenticated with
+         the real IDs.  */
+      cwdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink);
+      ref = __mach_reply_port ();
+      err = __io_reauthenticate (cwdir, ref, MACH_MSG_TYPE_MAKE_SEND);
+      if (!err)
+	err = __auth_user_authenticate (_hurd_id.rid_auth,
+					cwdir,
+					ref, MACH_MSG_TYPE_MAKE_SEND,
+					&rcwdir);
+      _hurd_port_free (&_hurd_ports[INIT_PORT_CWDIR], &cwdir_ulink, cwdir);
+      __mach_port_destroy (__mach_task_self (), ref);
+    }
+
+  /* We are done with _hurd_id.rid_auth now.  */
+ lose:
+  __mutex_unlock (&_hurd_id.lock);
+
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Now do a path lookup on FILE, using the crdir and cwdir
+     reauthenticated with _hurd_id.rid_auth.  */
+
+  err = __hurd_file_name_lookup (rcrdir, rcwdir, file, 0, 0, &io);
+  __mach_port_deallocate (__mach_task_self (), rcrdir);
+  __mach_port_deallocate (__mach_task_self (), rcwdir);
+  if (err)
+    return __hurd_fail (err);
+
+  /* Find out what types of access we are allowed to this file.  */
+  err = __file_check_access (io, &allowed);
+  __mach_port_deallocate (__mach_task_self (), io);
+  if (err)
+    return __hurd_fail (err);
+
+  flags = 0;
+  if (type & R_OK)
+    flags |= O_READ;
+  if (type & W_OK)
+    flags |= O_WRITE;
+  if (type & X_OK)
+    flags |= O_EXEC;
+
+  if (flags & ~allowed)
+    /* We are not allowed all the requested types of access.  */
+    return __hurd_fail (EACCES);
+
+  return 0;
+}
+
+weak_alias (__access, access)
diff --git a/sysdeps/mach/hurd/adjtime.c b/sysdeps/mach/hurd/adjtime.c
new file mode 100644
index 0000000000..d88f404ce4
--- /dev/null
+++ b/sysdeps/mach/hurd/adjtime.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1991, 1993, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+
+/* Adjust the current time of day by the amount in DELTA.
+   If OLDDELTA is not NULL, it is filled in with the amount
+   of time adjustment remaining to be done from the last `__adjtime' call.
+   This call is restricted to the super-user.  */
+int
+DEFUN(__adjtime, (delta, olddelta),
+      CONST struct timeval *delta AND
+      struct timeval *olddelta)
+{
+  error_t err;
+  mach_port_t hostpriv, devmaster;
+
+  if (err = __USEPORT (PROC, __proc_getprivports (port,
+						  &hostpriv, &devmaster)))
+    return __hurd_fail (err);
+  __mach_port_deallocate (__mach_task_self (), devmaster);
+
+  err = __host_adjust_time (hostpriv,
+			    /* `time_value_t' and `struct timeval' are in
+                               fact identical with the names changed.  */
+			    *(time_value_t *) delta,
+			    (time_value_t *) olddelta);
+  __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__adjtime, adjtime)
diff --git a/sysdeps/mach/hurd/alpha/exc2signal.c b/sysdeps/mach/hurd/alpha/exc2signal.c
new file mode 100644
index 0000000000..edac0aaa67
--- /dev/null
+++ b/sysdeps/mach/hurd/alpha/exc2signal.c
@@ -0,0 +1,76 @@
+/* Translate Mach exception codes into signal numbers.  Alpha version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <mach/exception.h>
+
+/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
+   into a signal number and signal subcode.  */
+
+void
+_hurd_exception2signal (int exception, int code, int subcode,
+			int *signo, long int *sigcode, int *error)
+{
+  *error = 0;
+
+  switch (exception)
+    {
+    default:
+      *signo = SIGIOT;
+      *sigcode = exception;
+      break;
+      
+    case EXC_BAD_ACCESS:
+      if (code == KERN_PROTECTION_FAILURE)
+	*signo = SIGSEGV;
+      else
+	*signo = SIGBUS;
+      *sigcode = subcode;
+      *error = code;
+      break;
+
+    case EXC_BAD_INSTRUCTION:
+      *signo = SIGILL;
+      *sigcode = code;
+      break;
+      
+    case EXC_ARITHMETIC:
+      *signo = SIGFPE;
+      *sigcode = code;
+      break;
+      break;
+
+    case EXC_EMULATION:		
+      /* 3.0 doesn't give this one, why, I don't know.  */
+      *signo = SIGEMT;
+      *sigcode = code;
+      break;
+
+    case EXC_SOFTWARE:
+      *signo = SIGEMT;
+      *sigcode = code;
+      break;
+      
+    case EXC_BREAKPOINT:
+      *signo = SIGTRAP;
+      *sigcode = code;
+      break;
+    }
+}
diff --git a/sysdeps/mach/hurd/alpha/longjmp-ctx.c b/sysdeps/mach/hurd/alpha/longjmp-ctx.c
new file mode 100644
index 0000000000..dfc16fdfe4
--- /dev/null
+++ b/sysdeps/mach/hurd/alpha/longjmp-ctx.c
@@ -0,0 +1,38 @@
+/* Perform a `longjmp' on a `struct sigcontext'.  Alpha version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <setjmp.h>
+#include <hurd/signal.h>
+#include <string.h>
+
+void
+_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval)
+{
+  memset (scp, 0, sizeof (*scp));
+  scp->sc_regs[9] = env[0].__9;
+  scp->sc_regs[11] = env[0].__11;
+  scp->sc_regs[12] = env[0].__12;
+  scp->sc_regs[13] = env[0].__13;
+  scp->sc_regs[14] = env[0].__14;
+  scp->sc_regs[15] = (long int) env[0].__fp;
+  scp->sc_regs[30] = (long int) env[0].__sp;
+  scp->sc_pc = (long int) env[0].__pc;
+
+  memcpy (&scp->sc_fpregs[2], &env[0].__f2, sizeof (double));
+}
diff --git a/sysdeps/mach/hurd/alpha/longjmp-ts.c b/sysdeps/mach/hurd/alpha/longjmp-ts.c
new file mode 100644
index 0000000000..ad6f80cdb0
--- /dev/null
+++ b/sysdeps/mach/hurd/alpha/longjmp-ts.c
@@ -0,0 +1,41 @@
+/* Perform a `longjmp' on a Mach thread_state.  Alpha version.
+Copyright (C) 1991, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <mach/thread_status.h>
+
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'.  */
+
+void
+_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
+{
+  struct alpha_thread_state *ts = state;
+
+  ts->r9 = env[0].__jmpbuf[0].__9;
+  ts->r11 = env[0].__jmpbuf[0].__11;
+  ts->r12 = env[0].__jmpbuf[0].__12;
+  ts->r13 = env[0].__jmpbuf[0].__13;
+  ts->r14 = env[0].__jmpbuf[0].__14;
+  ts->r15 = (long int) env[0].__jmpbuf[0].__fp;
+  ts->r30 = (long int) env[0].__jmpbuf[0].__sp;
+  ts->pc = (long int) env[0].__jmpbuf[0].__pc;
+  ts->r0 = val ?: 1;
+}
diff --git a/sysdeps/mach/hurd/alpha/sigcontext.h b/sysdeps/mach/hurd/alpha/sigcontext.h
new file mode 100644
index 0000000000..32e0c94f98
--- /dev/null
+++ b/sysdeps/mach/hurd/alpha/sigcontext.h
@@ -0,0 +1,65 @@
+/* Machine-dependent signal context structure for GNU Hurd.  Alpha version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* Signal handlers are actually called:
+   void handler (int sig, int code, struct sigcontext *scp);  */
+
+/* State of this thread when the signal was taken.  */
+struct sigcontext
+  {
+    /* These first members are machine-independent.  */
+
+    long int sc_onstack;	/* Nonzero if running on sigstack.  */
+    __sigset_t sc_mask;		/* Blocked signals to restore.  */
+
+    /* MiG reply port this thread is using.  */
+    unsigned long int sc_reply_port;
+
+    /* Port this thread is doing an interruptible RPC on.  */
+    unsigned long int sc_intr_port;
+
+    /* Error code associated with this signal (interpreted as `error_t').  */
+    int sc_error;
+
+    /* All following members are machine-dependent.  The rest of this
+       structure is written to be laid out identically to:
+       {
+         struct alpha_thread_state basic;
+         struct alpha_exc_state exc;
+         struct alpha_float_state fpu;
+       }
+       trampoline.c knows this, so it must be changed if this changes.  */
+
+#define sc_alpha_thread_state sc_regs /* Beginning of correspondence.  */
+    long int sc_regs[31];	/* General registers $0..$30.  */
+    long int sc_pc;		/* Program counter.  */
+
+    /* struct alpha_exc_state */
+#define sc_alpha_exc_state sc_badvaddr
+    unsigned long int sc_badvaddr;
+    unsigned int sc_cause;	/* Machine-level trap code.  */
+#define SC_CAUSE_SET_SSTEP	1
+    int sc_used_fpa;		/* Nonzero if FPU was used.  */
+
+    /* struct alpha_float_state
+       This is only filled in if sc_used_fpa is nonzero.  */
+#define sc_alpha_float_state sc_fpregs
+    double sc_fpregs[31];	/* Floating point registers $f0..$f30.  */
+    long int sc_fpcsr;		/* Floating point control/status register.  */
+  };
diff --git a/sysdeps/mach/hurd/alpha/sigreturn.c b/sysdeps/mach/hurd/alpha/sigreturn.c
new file mode 100644
index 0000000000..e5dc383a3a
--- /dev/null
+++ b/sysdeps/mach/hurd/alpha/sigreturn.c
@@ -0,0 +1,212 @@
+/* Return from signal handler in GNU C library for Hurd.  Alpha version.
+Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/threadvar.h>
+#include <hurd/msg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mach/machine/alpha_instruction.h>
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+  struct hurd_sigstate *ss;
+  mach_port_t *reply_port;
+
+  if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  ss = _hurd_self_sigstate ();
+  __spin_lock (&ss->lock);
+
+  /* Restore the set of blocked signals, and the intr_port slot.  */
+  ss->blocked = scp->sc_mask;
+  ss->intr_port = scp->sc_intr_port;
+
+  /* Check for pending signals that were blocked by the old set.  */
+  if (ss->pending & ~ss->blocked)
+    {
+      /* There are pending signals that just became unblocked.  Wake up the
+	 signal thread to deliver them.  But first, squirrel away SCP where
+	 the signal thread will notice it if it runs another handler, and
+	 arrange to have us called over again in the new reality.  */
+      ss->context = scp;
+      /* Clear the intr_port slot, since we are not in fact doing
+	 an interruptible RPC right now.  If SS->intr_port is not null,
+	 the SCP context is doing an interruptible RPC, but the signal
+	 thread will examine us while we are blocked in the sig_post RPC.  */
+      ss->intr_port = MACH_PORT_NULL;
+      __spin_unlock (&ss->lock);
+      __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+      /* If a pending signal was handled, sig_post never returned.  */
+      __spin_lock (&ss->lock);
+    }
+
+  if (scp->sc_onstack)
+    {
+      ss->sigaltstack.ss_flags &= ~SA_ONSTACK; /* XXX threadvars */
+      /* XXX cannot unlock until off sigstack */
+      abort ();
+    }
+  else
+    __spin_unlock (&ss->lock);
+
+  /* Destroy the MiG reply port used by the signal handler, and restore the
+     reply port in use by the thread when interrupted.  */
+  reply_port =
+    (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+  if (*reply_port)
+    __mach_port_destroy (__mach_task_self (), *reply_port);
+  *reply_port = scp->sc_reply_port;
+
+  if (scp->sc_used_fpa)
+    {
+      /* Restore FPU state.  */
+
+      /* Restore the floating-point control/status register.
+	 We must do this first because the compiler will need
+	 a temporary FP register for the load.  */
+      asm volatile ("mt_fpcr %0" : : "f" (scp->sc_fpcsr));
+
+      /* Restore floating-point registers. */
+#define restore_fpr(n) \
+  asm volatile ("ldt $f" #n ",%0" : : "m" (scp->sc_fpregs[n]))
+      restore_fpr (0);
+      restore_fpr (1);
+      restore_fpr (2);
+      restore_fpr (3);
+      restore_fpr (4);
+      restore_fpr (5);
+      restore_fpr (6);
+      restore_fpr (7);
+      restore_fpr (8);
+      restore_fpr (9);
+      restore_fpr (10);
+      restore_fpr (11);
+      restore_fpr (12);
+      restore_fpr (13);
+      restore_fpr (14);
+      restore_fpr (15);
+      restore_fpr (16);
+      restore_fpr (17);
+      restore_fpr (18);
+      restore_fpr (19);
+      restore_fpr (20);
+      restore_fpr (21);
+      restore_fpr (22);
+      restore_fpr (23);
+      restore_fpr (24);
+      restore_fpr (25);
+      restore_fpr (26);
+      restore_fpr (27);
+      restore_fpr (28);
+      restore_fpr (29);
+      restore_fpr (30);
+    }
+
+  /* Load all the registers from the sigcontext.  */
+#define restore_gpr(n) \
+  asm volatile ("ldq $" #n ",%0" : : "m" (scpreg->sc_regs[n]))
+
+  {
+    /* The `rei' PAL pseudo-instruction restores registers $2..$7, the PC
+       and processor status.  So we can use these few registers for our
+       working variables.  Unfortunately, it finds its data on the stack
+       and merely pops the SP ($30) over the words of state restored,
+       allowing no other option for the new SP value.  So we must push the
+       registers and PSW it will to restore, onto the user's stack and let
+       it pop them from there.  */
+    register const struct sigcontext *const scpreg asm ("$2") = scp;
+    register integer_t *usp asm ("$3") = (integer_t *) scpreg->sc_regs[30];
+    register integer_t usp_align asm ("$4");
+
+    /* Push an 8-word "trap frame" onto the user stack for `rei':
+       registers $2..$7, the PC, and the PSW.  */
+
+    register struct rei_frame
+      {
+	integer_t regs[5], pc, ps;
+      } *rei_frame asm ("$5");
+
+    usp -= 8;
+    /* `rei' demands that the stack be aligned to a 64 byte (8 word)
+       boundary; bits 61..56 of the PSW are OR'd back into the SP value
+       after popping the 8-word trap frame, so we store (sp % 64)
+       there and this restores the original user SP.  */
+    usp_align = (integer_t) usp & 63L;
+    rei_frame = (void *) ((integer_t) usp & ~63L);
+
+    /* Copy the registers and PC from the sigcontext.  */
+    memcpy (rei_frame->regs, &scpreg->sc_regs[2], sizeof rei_frame->regs);
+    rei_frame->pc = scpreg->sc_pc;
+
+    /* Compute the new PS value to be restored.  `rei' adds the value at
+       bits 61..56 to the SP to compensate for the alignment above that
+       cleared the low 6 bits; bits 5..3 are the new mode/privilege level
+       (must be >= current mode; 3 == user mode); bits 2..0 are "software",
+       unused by the processor or kernel (XXX should trampoline save these?
+       How?); in user mode, `rei' demands that all other bits be zero.  */
+    rei_frame->ps = (usp_align << 56) | (3 << 3); /* XXX low 3 bits??? */
+
+    /* Restore the other general registers: everything except $2..$7, which
+       are in the `rei' trap frame we set up above, and $30, which is the
+       SP which is popped by `rei'.  */
+    restore_gpr (1);
+    restore_gpr (8);
+    restore_gpr (9);
+    restore_gpr (10);
+    restore_gpr (11);
+    restore_gpr (12);
+    restore_gpr (13);
+    restore_gpr (14);
+    restore_gpr (15);
+    restore_gpr (16);
+    restore_gpr (17);
+    restore_gpr (18);
+    restore_gpr (19);
+    restore_gpr (20);
+    restore_gpr (21);
+    restore_gpr (22);
+    restore_gpr (23);
+    restore_gpr (24);
+    restore_gpr (25);
+    restore_gpr (26);
+    restore_gpr (27);
+    restore_gpr (28);
+    restore_gpr (29);
+
+    /* Switch the stack pointer to the trap frame set up on
+       the user stack and do the magical `rei' PAL call.  */
+    asm volatile ("mov %0, $30\n"
+		  "call_pal %1"
+		  : : "r" (rei_frame), "i" (op_rei));
+    /* Firewall.  */
+    asm volatile ("call_pal %0" : : "i" (op_halt));
+  }
+
+  /* NOTREACHED */
+  return -1;
+}
+
+weak_alias (__sigreturn, sigreturn)
diff --git a/sysdeps/mach/hurd/alpha/trampoline.c b/sysdeps/mach/hurd/alpha/trampoline.c
new file mode 100644
index 0000000000..85f4964e14
--- /dev/null
+++ b/sysdeps/mach/hurd/alpha/trampoline.c
@@ -0,0 +1,286 @@
+/* Set thread_state for sighandler, and sigcontext to recover.  Alpha version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include "thread_state.h"
+#include <mach/machine/alpha_instruction.h>
+#include "hurdfault.h"
+#include <assert.h>
+
+struct mach_msg_trap_args
+  {
+    /* This is the order of arguments to mach_msg_trap.  */
+    mach_msg_header_t *msg;
+    mach_msg_option_t option;
+    mach_msg_size_t send_size;
+    mach_msg_size_t rcv_size;
+    mach_port_t rcv_name;
+    mach_msg_timeout_t timeout;
+    mach_port_t notify;
+  };
+
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+			int signo, long int sigcode,
+			int rpc_wait,
+			struct machine_thread_all_state *state)
+{
+  __label__ trampoline, rpc_wait_trampoline;
+  void *sigsp;
+  struct sigcontext *scp;
+
+  if (ss->context)
+    {
+      /* We have a previous sigcontext that sigreturn was about
+	 to restore when another signal arrived.  We will just base
+	 our setup on that.  */
+      if (_hurdsig_catch_fault (SIGSEGV))
+	assert (_hurdsig_fault_sigcode >= (long int) ss->context &&
+		_hurdsig_fault_sigcode < (long int) (ss->context + 1));
+      else
+	{
+	  memcpy (&state->basic, &ss->context->sc_alpha_thread_state,
+		  sizeof (state->basic));
+	  memcpy (&state->exc, &ss->context->sc_alpha_exc_state,
+		  sizeof (state->exc));
+	  state->set = (1 << ALPHA_THREAD_STATE) | (1 << ALPHA_EXC_STATE);
+	  if (state->exc.used_fpa)
+	    {
+	      memcpy (&state->fpu, &ss->context->sc_alpha_float_state,
+		      sizeof (state->fpu));
+	      state->set |= (1 << ALPHA_FLOAT_STATE);
+	    }
+	  assert (! rpc_wait);
+	  /* The intr_port slot was cleared before sigreturn sent us the
+	     sig_post that made us notice this pending signal, so
+	     _hurd_internal_post_signal wouldn't do interrupt_operation.
+	     After we return, our caller will set SCP->sc_intr_port (in the
+	     new context) from SS->intr_port and clear SS->intr_port.  Now
+	     that we are restoring this old context recorded by sigreturn,
+	     we want to restore its intr_port too; so store it in
+	     SS->intr_port now, so it will end up in SCP->sc_intr_port
+	     later.  */
+	  ss->intr_port = ss->context->sc_intr_port;
+	}
+      /* If the sigreturn context was bogus, just ignore it.  */
+      ss->context = NULL;
+    }
+  else if (! machine_get_basic_state (ss->thread, state))
+    return NULL;
+
+  if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+      !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK)))
+    {
+      sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+      ss->sigaltstack.ss_flags |= SA_ONSTACK;
+      /* XXX need to set up base of new stack for
+	 per-thread variables, cthreads.  */
+    }
+  else
+    sigsp = (char *) state->basic.SP;
+
+  /* Set up the sigcontext structure on the stack.  This is all the stack
+     needs, since the args are passed in registers (below).  */
+  sigsp -= sizeof (*scp);
+  scp = sigsp;
+
+  if (_hurdsig_catch_fault (SIGSEGV))
+    {
+      assert (_hurdsig_fault_sigcode >= (long int) scp &&
+	      _hurdsig_fault_sigcode < (long int) (scp + 1));
+      /* We got a fault trying to write the stack frame.
+	 We cannot set up the signal handler.
+	 Returning NULL tells our caller, who will nuke us with a SIGILL.  */
+      return NULL;
+    }
+  else
+    {
+      /* Set up the sigcontext from the current state of the thread.  */
+
+      scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0;
+
+      /* struct sigcontext is laid out so that starting at sc_regs
+	 mimics a struct alpha_thread_state.  */
+      memcpy (&scp->sc_alpha_thread_state,
+	      &state->basic, sizeof (state->basic));
+
+      /* struct sigcontext is laid out so that starting at sc_badvaddr
+	 mimics a struct mips_exc_state.  */
+      if (! machine_get_state (ss->thread, state, ALPHA_EXC_STATE,
+			       &state->exc, &scp->sc_alpha_exc_state,
+			       sizeof (state->exc)))
+	return NULL;
+
+      if (state->exc.used_fpa &&
+	  /* struct sigcontext is laid out so that starting at sc_fpregs
+	     mimics a struct alpha_float_state.  This state
+	     is only meaningful if the coprocessor was used.  */
+	  ! machine_get_state (ss->thread, state, ALPHA_FLOAT_STATE,
+			       &state->fpu,
+			       &scp->sc_alpha_float_state,
+			       sizeof (state->fpu)))
+	return NULL;
+    }
+
+  /* Modify the thread state to call the trampoline code on the new stack.  */
+  if (rpc_wait)
+    {
+      /* The signalee thread was blocked in a mach_msg_trap system call,
+	 still waiting for a reply.  We will have it run the special
+	 trampoline code which retries the message receive before running
+	 the signal handler.
+	 
+	 To do this we change the OPTION argument in its registers to
+	 enable only message reception, since the request message has
+	 already been sent.  */
+
+      /* The system call arguments are stored in consecutive registers
+	 starting with a0 ($16).  */
+      struct mach_msg_trap_args *args = (void *) &state->basic.r16;
+
+      assert (args->option & MACH_RCV_MSG);
+      /* Disable the message-send, since it has already completed.  The
+	 calls we retry need only wait to receive the reply message.  */
+      args->option &= ~MACH_SEND_MSG;
+
+      state->basic.pc = (long int) &&rpc_wait_trampoline;
+      /* After doing the message receive, the trampoline code will need to
+	 update the v0 ($0) value to be restored by sigreturn.  To simplify
+	 the assembly code, we pass the address of its slot in SCP to the
+	 trampoline code in at ($28).  */
+      state->basic.r28 = (long int) &scp->sc_regs[0];
+      /* We must preserve the mach_msg_trap args in a0..a5 and t0
+	 ($16..$21, $1).  Pass the handler args to the trampoline code in
+	 t8..t10 ($22.$24).  */
+      state->basic.r22 = signo;
+      state->basic.r23 = sigcode;
+      state->basic.r24 = (long int) scp;
+    }
+  else
+    {
+      state->basic.pc = (long int) &&trampoline;
+      state->basic.r16 = signo;
+      state->basic.r17 = sigcode;
+      state->basic.r18 = (long int) scp;
+    }
+
+  state->basic.r30 = (long int) sigsp; /* $30 is the stack pointer.  */
+
+  /* We pass the handler function to the trampoline code in ra ($26).  */
+  state->basic.r26 = (long int) handler;
+  /* In the callee-saved register t12/pv ($27), we store the
+     address of __sigreturn itself, for the trampoline code to use.  */
+  state->basic.r27 = (long int) &__sigreturn;
+  /* In the callee-saved register t11/ai ($25), we save the SCP value to pass
+     to __sigreturn after the handler returns.  */
+  state->basic.r25 = (long int) scp;
+
+  return scp;
+
+  /* The trampoline code follows.  This is not actually executed as part of
+     this function, it is just convenient to write it that way.  */
+
+ rpc_wait_trampoline:
+  /* This is the entry point when we have an RPC reply message to receive
+     before running the handler.  The MACH_MSG_SEND bit has already been
+     cleared in the OPTION argument in our registers.  For our convenience,
+     at ($28) points to the sc_regs[0] member of the sigcontext (saved v0
+     ($0)).  */
+  asm volatile
+    (/* Retry the interrupted mach_msg system call.  */
+     "lda $0, -25($31)\n"	/* mach_msg_trap */
+     "call_pal %0\n"		/* Magic system call instruction.  */
+     /* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED.  But
+	now the message receive has completed and the original caller of
+	the RPC (i.e. the code running when the signal arrived) needs to
+	see the final return value of the message receive in v0.  So
+	store the new v0 value into the sc_regs[0] member of the sigcontext
+	(whose address is in at to make this code simpler).  */
+     "stq $0, 0($28)\n"
+     /* Since the argument registers needed to have the mach_msg_trap
+	arguments, we've stored the arguments to the handler function
+	in registers t8..t10 ($22..$24).  */
+     "mov $22, $16\n"
+     "mov $23, $17\n"
+     "mov $24, $18\n"
+     : : "i" (op_chmk));
+
+ trampoline:
+  /* Entry point for running the handler normally.  The arguments to the
+     handler function are already in the standard registers:
+
+       a0	SIGNO
+       a1	SIGCODE
+       a2	SCP
+
+     t12 also contains SCP; this value is callee-saved (and so should not get
+     clobbered by running the handler).  We use this saved value to pass to
+     __sigreturn, so the handler can clobber the argument registers if it
+     likes.  */
+  /* Call the handler function, saving return address in ra ($26).  */
+  asm volatile ("jsr $26, ($26)");
+  /* Reset gp ($29) from the return address (here) in ra ($26).  */
+  asm volatile ("ldgp $29, 0($26)");
+  asm volatile ("mov $25, $16"); /* Move saved SCP to argument register.  */
+  /* Call __sigreturn (SCP); this cannot return.  */
+  asm volatile ("jmp $31, ($27)");
+
+  /* NOTREACHED */
+  return NULL;
+}
+
+/* STATE describes a thread that had intr_port set (meaning it was inside
+   HURD_EINTR_RPC), after it has been thread_abort'd.  If it looks to have
+   just completed a mach_msg_trap system call that returned
+   MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right
+   being waited on.  */
+int
+_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state,
+			    mach_port_t *port)
+{
+  if (state->basic.r0 == MACH_RCV_INTERRUPTED)
+    {
+      const unsigned int *pc = (void *) state->basic.pc;
+      struct mach_msg_trap_args *args = (void *) &state->basic.r16;
+
+      if (_hurdsig_catch_fault (SIGSEGV))
+	{
+	  assert (_hurdsig_fault_sigcode == (long int) (pc - 1) ||
+		  _hurdsig_fault_sigcode == (long int) &args->rcv_name);
+	  /* We got a fault trying to read the PC or stack.  */
+	  return 0;
+	}
+      else
+	{
+	  if (pc[-1] == ((alpha_instruction) { pal_format:
+						 { opcode: op_pal,
+						   function: op_chmk } }).bits)
+	    {
+	      /* We did just return from a mach_msg_trap system call
+		 doing a message receive that was interrupted.
+		 Examine the parameters to find the receive right.  */
+	      *port = args->rcv_name;
+	      return 1;
+	    }
+	}
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/bind.c b/sysdeps/mach/hurd/bind.c
new file mode 100644
index 0000000000..e9e54ec8dc
--- /dev/null
+++ b/sysdeps/mach/hurd/bind.c
@@ -0,0 +1,102 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <hurd/ifsock.h>
+#include <sys/un.h>
+#include <string.h>
+
+/* Give the socket FD the local address ADDR (which is LEN bytes long).  */
+int
+DEFUN(bind, (fd, addr, len),
+      int fd AND struct sockaddr *addr AND size_t len)
+{
+  addr_port_t aport;
+  error_t err;
+
+  if (addr->sa_family == AF_LOCAL)
+    {
+      /* For the local domain, we must create a node in the filesystem
+	 using the ifsock translator and then fetch the address from it.  */
+      struct sockaddr_un *unaddr = (struct sockaddr_un *) addr;
+      file_t dir, node;
+      char name[len - offsetof (struct sockaddr_un, sun_path)], *n;
+      strncpy (name, unaddr->sun_path, sizeof name);
+      dir = __file_name_split (name, &n);
+      if (dir == MACH_PORT_NULL)
+	return -1;
+      
+      /* Create a new, unlinked node in the target directory.  */
+      err = __dir_mkfile (dir, O_CREAT, 0666 & ~_hurd_umask, &node);
+
+      if (! err)
+	{
+	  file_t ifsock;
+	  /* Set the node's translator to make it a local-domain socket.  */
+	  err = __file_set_translator (node, 
+				       FS_TRANS_EXCL | FS_TRANS_SET,
+				       FS_TRANS_EXCL | FS_TRANS_SET, 0,
+				       _HURD_IFSOCK, sizeof _HURD_IFSOCK,
+				       MACH_PORT_NULL,
+				       MACH_MSG_TYPE_COPY_SEND);
+	  if (! err)
+	    /* Get a port to the ifsock translator.  */
+	    err = __hurd_invoke_translator (node, 0, &ifsock);
+	  if (! err)
+	    /* Get the address port.  */
+	    err = __ifsock_getsockaddr (ifsock, &aport);
+	  __mach_port_deallocate (__mach_task_self (), ifsock);
+	  if (! err)
+	    /* Link the node, now a socket, into the target directory.  */
+	    err = __dir_link (node, dir, name);
+	  __mach_port_deallocate (__mach_task_self (), node);
+	}
+      __mach_port_deallocate (__mach_task_self (), dir);
+
+      if (err)
+	return __hurd_fail (err);
+    }
+  else
+    err = EIEIO;
+
+  err = HURD_DPORT_USE (fd,
+			({
+			  if (err)
+			    err = __socket_create_address (port,
+							   addr->sa_family,
+							   (char *) addr, len,
+							   &aport, 1);
+			  if (! err)
+			    {
+			      err = __socket_bind (port, aport);
+			      __mach_port_deallocate (__mach_task_self (),
+						      aport);
+			    }
+			  err;
+			}));
+
+  return err ? __hurd_dfail (fd, err) : 0;
+}
diff --git a/sysdeps/mach/hurd/brk.c b/sysdeps/mach/hurd/brk.c
new file mode 100644
index 0000000000..a96286b2d9
--- /dev/null
+++ b/sysdeps/mach/hurd/brk.c
@@ -0,0 +1,130 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+#include <cthreads.h>		/* For `struct mutex'.  */
+
+
+/* Initial maximum size of the data segment (32MB, which is arbitrary).  */
+#define	DATA_SIZE	(32 * 1024 * 1024)
+
+
+/* Up to the page including this address is allocated from the kernel.
+   This address is the data resource limit.  */
+vm_address_t _hurd_data_end;
+
+/* Up to this address is actually available to the user.
+   Pages beyond the one containing this address allow no access.  */
+vm_address_t _hurd_brk;
+
+struct mutex _hurd_brk_lock;
+
+extern int __data_start, _end;
+
+
+/* Set the end of the process's data space to INADDR.
+   Return 0 if successful, -1 if not.  */
+int
+DEFUN(__brk, (inaddr), PTR inaddr)
+{
+  int ret;
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_brk_lock);
+  ret = _hurd_set_brk ((vm_address_t) inaddr);
+  __mutex_unlock (&_hurd_brk_lock);
+  HURD_CRITICAL_END;
+  return ret;
+}
+weak_alias (__brk, brk)
+
+
+int
+_hurd_set_brk (vm_address_t addr)
+{
+  error_t err;
+  vm_address_t pagend = round_page (addr);
+  vm_address_t pagebrk = round_page (_hurd_brk);
+  long int rlimit;
+
+  if (pagend <= pagebrk)
+    {
+      if (pagend < pagebrk)
+	/* Make that memory inaccessible.  */
+	__vm_protect (__mach_task_self (), pagend, pagebrk - pagend,
+		      0, VM_PROT_NONE);
+      _hurd_brk = addr;
+      return 0;
+    }
+
+  __mutex_lock (&_hurd_rlimit_lock);
+  rlimit = _hurd_rlimits[RLIMIT_DATA].rlim_cur;
+  __mutex_unlock (&_hurd_rlimit_lock);
+
+  if (addr - (vm_address_t) &__data_start > rlimit)
+    {
+      /* Need to increase the resource limit.  */
+      errno = ENOMEM;
+      return -1;
+    }
+
+  /* Make the memory accessible.  */
+  if (err = __vm_protect (__mach_task_self (), pagebrk, pagend - pagebrk,
+			  0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE))
+    {
+      errno = err;
+      return -1;
+    }
+
+  _hurd_brk = addr;
+  return 0;
+}
+
+static void
+init_brk (void)
+{
+  vm_address_t pagend;
+
+  __mutex_init (&_hurd_brk_lock);
+
+  /* If _hurd_brk is already set, don't change it.  The assumption is that
+     it was set in a previous run before something like Emacs's unexec was
+     called and dumped all the data up to the break at that point.  */
+  if (_hurd_brk == 0)
+    _hurd_brk = (vm_address_t) &_end;
+
+  pagend = round_page (_hurd_brk);
+
+  _hurd_data_end = (vm_address_t) &__data_start + DATA_SIZE;
+
+  if (pagend < _hurd_data_end)
+    {
+      /* We use vm_map to allocate and change permissions atomically.  */
+      if (__vm_map (__mach_task_self (), &pagend, _hurd_data_end - pagend,
+		    0, 0, MACH_PORT_NULL, 0, 0,
+		    0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
+		    VM_INHERIT_COPY))
+	/* Couldn't allocate the memory.  The break will be very short.  */
+	_hurd_data_end = pagend;
+    }
+
+  (void) &init_brk;		/* Avoid ``defined but not used'' warning.  */
+}
+text_set_element (_hurd_preinit_hook, init_brk);
diff --git a/sysdeps/mach/hurd/chdir.c b/sysdeps/mach/hurd/chdir.c
new file mode 100644
index 0000000000..912ca08683
--- /dev/null
+++ b/sysdeps/mach/hurd/chdir.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+#include <hurd/port.h>
+
+/* Change the current directory to FILE_NAME.  */
+int
+DEFUN(__chdir, (file_name), CONST char *file_name)
+{
+  file_t file, dir;
+  error_t err;
+
+  file = __file_name_lookup (file_name, O_EXEC, 0);
+  if (file == MACH_PORT_NULL)
+    return -1;
+  err = __USEPORT (CRDIR, __hurd_file_name_lookup (port, file, "",
+						   O_EXEC, 0, &dir));
+  __mach_port_deallocate (__mach_task_self (), file);
+  if (err)
+    return __hurd_fail (err);
+
+  _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], dir);
+  return 0;
+}
+
+weak_alias (__chdir, chdir)
diff --git a/sysdeps/mach/hurd/chflags.c b/sysdeps/mach/hurd/chflags.c
new file mode 100644
index 0000000000..157940d19b
--- /dev/null
+++ b/sysdeps/mach/hurd/chflags.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Change the flags of FILE to FLAGS.  */
+int
+DEFUN(chflags, (file, flags), CONST char *file AND int flags)
+{
+  error_t err;
+  file_t port = __file_name_lookup (file, 0, 0);
+  if (port == MACH_PORT_NULL)
+    return -1;
+  err = __file_chflags (port, flags);
+  __mach_port_deallocate (__mach_task_self (), port);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/chmod.c b/sysdeps/mach/hurd/chmod.c
new file mode 100644
index 0000000000..00a81ef0cf
--- /dev/null
+++ b/sysdeps/mach/hurd/chmod.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991, 1992, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Change the protections of FILE to MODE.  */
+int
+DEFUN(__chmod, (file, mode), CONST char *file AND mode_t mode)
+{
+  error_t err;
+  file_t port = __file_name_lookup (file, 0, 0);
+  if (port == MACH_PORT_NULL)
+    return -1;
+  err = __file_chmod (port, mode);
+  __mach_port_deallocate (__mach_task_self (), port);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__chmod, chmod)
diff --git a/sysdeps/mach/hurd/chown.c b/sysdeps/mach/hurd/chown.c
new file mode 100644
index 0000000000..a1ed9d5e14
--- /dev/null
+++ b/sysdeps/mach/hurd/chown.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991, 1992, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Change the owner and group of FILE.  */
+int
+DEFUN(__chown, (file, owner, group),
+      CONST char *file AND uid_t owner AND gid_t group)
+{
+  error_t err;
+  file_t port = __file_name_lookup (file, 0, 0);
+  if (port == MACH_PORT_NULL)
+    return -1;
+  err = __file_chown (port, owner, group);
+  __mach_port_deallocate (__mach_task_self (), port);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__chown, chown)
diff --git a/sysdeps/mach/hurd/chroot.c b/sysdeps/mach/hurd/chroot.c
new file mode 100644
index 0000000000..415a068004
--- /dev/null
+++ b/sysdeps/mach/hurd/chroot.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+#include <hurd/port.h>
+
+/* Change the current root to FILE_NAME.  */
+int
+DEFUN(chroot, (file_name), CONST char *file_name)
+{
+  file_t file, dir;
+  error_t err;
+
+  file = __file_name_lookup (file_name, O_EXEC, 0);
+  if (file == MACH_PORT_NULL)
+    return -1;
+  err = __USEPORT (CRDIR, __hurd_file_name_lookup (port, file, "",
+						   O_EXEC, 0, &dir));
+  __mach_port_deallocate (__mach_task_self (), file);
+  if (err)
+    return __hurd_fail (err);
+
+  _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/close.c b/sysdeps/mach/hurd/close.c
new file mode 100644
index 0000000000..259687e1fb
--- /dev/null
+++ b/sysdeps/mach/hurd/close.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Close the file descriptor FD.  */
+int
+DEFUN(__close, (fd), int fd)
+{
+  error_t err;
+
+  err = HURD_FD_USE (fd, _hurd_fd_close (descriptor));
+
+  return err ? __hurd_fail (err) : 0;
+}
+
+weak_alias (__close, close)
diff --git a/sysdeps/mach/hurd/closedir.c b/sysdeps/mach/hurd/closedir.c
new file mode 100644
index 0000000000..9d20621747
--- /dev/null
+++ b/sysdeps/mach/hurd/closedir.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 1993 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Close the directory stream DIRP.
+   Return 0 if successful, -1 if not.  */
+int
+DEFUN(closedir, (dirp), DIR *dirp)
+{
+  error_t err;
+
+  if (dirp == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  if ((err = __vm_deallocate (__mach_task_self (),
+			      (vm_address_t) dirp->__data, dirp->__allocation))
+      || (err = __mach_port_deallocate (__mach_task_self (), dirp->__port)))
+    {
+      errno = err;
+      return -1;
+    }
+
+  free (dirp);
+
+  return 0;
+}
+
diff --git a/sysdeps/mach/hurd/configure b/sysdeps/mach/hurd/configure
new file mode 100755
index 0000000000..a396cd0024
--- /dev/null
+++ b/sysdeps/mach/hurd/configure
@@ -0,0 +1,21 @@
+ 
+# If configure is passed `--with-hurd=DIR', set `hurd-srcdir' to DIR in
+# config.make.
+
+ac_help="$ac_help
+  --with-hurd=DIRECTORY   find Hurd source code in DIRECTORY [../hurd]"
+# Check whether --with-hurd or --without-hurd was given.
+withval="$with_hurd"
+if test -n "$withval"; then
+  case z"$with_hurd" in
+z | zno | zyes) ;; # Not specified, or specified with no value.
+z*) config_vars="$config_vars
+hurd-srcdir = $with_hurd" ;;
+esac
+
+fi
+
+
+# Don't bother trying to generate any glue code to be compatible with the
+# existing system library, because we are the only system library.
+inhibit_glue=yes
diff --git a/sysdeps/mach/hurd/configure.in b/sysdeps/mach/hurd/configure.in
new file mode 100644
index 0000000000..39e1002d6e
--- /dev/null
+++ b/sysdeps/mach/hurd/configure.in
@@ -0,0 +1,19 @@
+sinclude(./aclocal.m4)dnl Autoconf lossage.
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+
+# If configure is passed `--with-hurd=DIR', set `hurd-srcdir' to DIR in
+# config.make.
+
+AC_ARG_WITH(hurd, dnl
+[  --with-hurd=DIRECTORY   find Hurd source code in DIRECTORY [../hurd]],
+            [dnl
+case z"$with_hurd" in
+z | zno | zyes) ;; # Not specified, or specified with no value.
+z*) config_vars="$config_vars
+hurd-srcdir = $with_hurd" ;;
+esac
+])
+
+# Don't bother trying to generate any glue code to be compatible with the
+# existing system library, because we are the only system library.
+inhibit_glue=yes
diff --git a/sysdeps/mach/hurd/connect.c b/sysdeps/mach/hurd/connect.c
new file mode 100644
index 0000000000..e015a14c50
--- /dev/null
+++ b/sysdeps/mach/hurd/connect.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/socket.h>
+#include <hurd/socket.h>
+#include <sys/un.h>
+#include <hurd/ifsock.h>
+
+/* Open a connection on socket FD to peer at ADDR (which LEN bytes long).
+   For connectionless socket types, just set the default address to send to
+   and the only address from which to accept transmissions.
+   Return 0 on success, -1 for errors.  */
+int
+DEFUN(connect, (fd, addr, len),
+      int fd AND struct sockaddr *addr AND size_t len)
+{
+  error_t err;
+  addr_port_t aport;
+  
+  if (addr->sa_family == AF_LOCAL)
+    {
+      /* For the local domain, we must look up the name as a file and talk
+	 to it with the ifsock protocol.  */
+      struct sockaddr_un *unaddr = (struct sockaddr_un *) addr;
+      file_t file = __file_name_lookup (unaddr->sun_path, 0, 0);
+      if (file == MACH_PORT_NULL)
+	return -1;
+      err = __ifsock_getsockaddr (file, &aport);
+      __mach_port_deallocate (__mach_task_self (), file);
+      if (err == MIG_BAD_ID || err == EOPNOTSUPP)
+	/* The file did not grok the ifsock protocol.  */
+	err = ENOTSOCK;
+      if (err)
+	return __hurd_fail (err);
+    }
+  else
+    err = EIEIO;
+    
+  err = HURD_DPORT_USE (fd,
+			({
+			  if (err)
+			    err = __socket_create_address (port,
+							   addr->sa_family,
+							   (char *) addr, len,
+							   &aport, 0);
+			  if (! err)
+			    {
+			      err = __socket_connect (port, aport);
+			      __mach_port_deallocate (__mach_task_self (),
+						      aport);
+			    }
+			  err;
+			}));
+
+  return err ? __hurd_dfail (fd, err) : 0;
+}
diff --git a/sysdeps/mach/hurd/defs.c b/sysdeps/mach/hurd/defs.c
new file mode 100644
index 0000000000..b2cfe7c4ff
--- /dev/null
+++ b/sysdeps/mach/hurd/defs.c
@@ -0,0 +1,85 @@
+/* Definitions of global stdio data structures.
+
+Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stdio.h>
+#include <hurd/fd.h>
+#include <unistd.h>
+
+FILE *stdin, *stdout, *stderr;
+
+/* Pointer to the first stream in the list.  */
+FILE *__stdio_head = NULL;
+
+static void
+init_stdio (void)
+{
+  inline void init (FILE **streamptr, int fd)
+    {
+      /* We want to use the existing FILE object if one has been allocated.
+	 (This will only be the case if our image came from something like
+	 Emacs's unexec, where we were called in the first run.)  */
+      FILE *s = *streamptr ?: __newstream ();
+      struct hurd_fd *d = _hurd_fd_get (fd);
+      if (d == NULL)
+	{
+	  /* There is no file descriptor allocated.  We want the standard
+	     streams to always refer to their standard file descriptors, even
+	     if those descriptors are not set up until later.  So allocate
+	     the descriptor structure with no ports and store it in the
+	     stream.  Operations will fail until ports are installed in the
+	     file descriptor.  */
+	  if (d = _hurd_alloc_fd (NULL, fd))
+	    __spin_unlock (&d->port.lock);
+	}
+      if (s)
+	s->__cookie = d;
+      *streamptr = s;
+    }
+#define S(NAME, FD, MODE) \
+  init (&NAME, FD); if (NAME) NAME->__mode.__##MODE = 1;
+
+  S (stdin, STDIN_FILENO, read);
+  S (stdout, STDOUT_FILENO, write);
+  S (stderr, STDERR_FILENO, write);
+
+#undef S
+
+  if (stderr)
+    stderr->__userbuf = 1;	/* stderr is always unbuffered.  */
+
+  (void) &init_stdio;		/* Avoid "defined but not used" warning.  */
+}
+text_set_element (_hurd_fd_subinit, init_stdio);
+
+/* This function MUST be in this file!
+   This is because we want _cleanup to go into the __libc_atexit set
+   when any stdio code is used (and to use any stdio code, one must reference
+   something defined in this file), and since only local symbols can be made
+   set elements, having the set element stab entry here and _cleanup elsewhere
+   loses; and having them both elsewhere loses because there is no reference
+   to cause _cleanup to be linked in.  */
+
+void
+DEFUN_VOID(_cleanup)
+{
+  (void) fclose ((FILE *) NULL);
+}
+text_set_element (__libc_atexit, _cleanup);
diff --git a/sysdeps/mach/hurd/dirstream.h b/sysdeps/mach/hurd/dirstream.h
new file mode 100644
index 0000000000..0bcec36f0f
--- /dev/null
+++ b/sysdeps/mach/hurd/dirstream.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef	_DIRSTREAM_H
+
+#define	_DIRSTREAM_H	1
+
+/* Directory stream type.
+
+   The Hurd directory format is the same as `struct dirent', so `readdir'
+   returns a pointer into the buffer we read directory data into.  */
+
+typedef struct
+  {
+    /* XXX we need a namespace-clean name for mach_port_t! */
+    unsigned int __port;	/* Port to the directory.  */
+    char *__data;		/* Directory block.  */
+    int __entry_data;		/* Entry number `__data' corresponds to.  */
+    char *__ptr;		/* Current pointer into the block.  */
+    int __entry_ptr;		/* Entry number `__ptr' corresponds to.  */
+    unsigned long int __allocation; /* Space allocated for the block.  */
+    unsigned long int __size;	/* Total valid data in the block.  */
+  } DIR;
+
+#endif	/* dirstream.h */
diff --git a/sysdeps/mach/hurd/dup2.c b/sysdeps/mach/hurd/dup2.c
new file mode 100644
index 0000000000..f4ec623b05
--- /dev/null
+++ b/sysdeps/mach/hurd/dup2.c
@@ -0,0 +1,114 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+
+/* Duplicate FD to FD2, closing the old FD2 and making FD2 be
+   open on the same file as FD is.  Return FD2 or -1.  */
+int
+DEFUN(__dup2, (fd, fd2), int fd AND int fd2)
+{
+  struct hurd_fd *d;
+
+  /* Extract the ports and flags from FD.  */
+  d = _hurd_fd_get (fd);
+  if (d == NULL)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  HURD_CRITICAL_BEGIN;
+
+  __spin_lock (&d->port.lock);
+  if (d->port.port == MACH_PORT_NULL)
+    {
+      __spin_unlock (&d->port.lock);
+      errno = EBADF;
+      fd2 = -1;
+    }
+  else if (fd2 == fd)
+    /* FD is valid and FD2 is already the same; just return it.  */
+    __spin_unlock (&d->port.lock);
+  else
+    {
+      struct hurd_userlink ulink, ctty_ulink;
+      int flags = d->flags;
+      io_t ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
+      io_t port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D.  */
+
+      __mutex_lock (&_hurd_dtable_lock);
+      if (fd2 < 0 || fd2 >= _hurd_dtablesize)
+	{
+	  errno = EBADF;
+	  fd2 = -1;
+	}
+      else
+	{
+	  /* Get a hold of the destination descriptor.  */
+	  struct hurd_fd *d2 = _hurd_dtable[fd2];
+	  if (d2 == NULL)
+	    {
+	      /* Must allocate a new one.  We don't initialize the port cells
+		 with this call so that if it fails (out of memory), we will
+		 not have already added user references for the ports, which we
+		 would then have to deallocate.  */
+	      d2 = _hurd_dtable[fd2] = _hurd_new_fd (MACH_PORT_NULL,
+						     MACH_PORT_NULL);
+	    }
+	  if (d2 == NULL)
+	    {
+	      fd2 = -1;
+	      if (errno == EINVAL)
+		errno = EBADF;	/* POSIX.1-1990 6.2.1.2 ll 54-55.  */
+	    }
+	  else
+	    {
+	      /* Give the ports each a user ref for the new descriptor.  */
+	      __mach_port_mod_refs (__mach_task_self (), port,
+				    MACH_PORT_RIGHT_SEND, 1);
+	      if (ctty != MACH_PORT_NULL)
+		__mach_port_mod_refs (__mach_task_self (), ctty,
+				      MACH_PORT_RIGHT_SEND, 1);
+
+	      /* Install the ports and flags in the new descriptor slot.  */
+	      __spin_lock (&d2->port.lock);
+	      d2->flags = flags & ~FD_CLOEXEC; /* Dup clears FD_CLOEXEC. */
+	      _hurd_port_set (&d2->ctty, ctty);
+	      _hurd_port_locked_set (&d2->port, port); /* Unlocks D2.  */
+	    }
+	}
+      __mutex_unlock (&_hurd_dtable_lock);
+
+      _hurd_port_free (&d->port, &ulink, port);
+      if (ctty != MACH_PORT_NULL)
+	_hurd_port_free (&d->ctty, &ctty_ulink, port);
+    }
+
+  HURD_CRITICAL_END;
+
+  return fd2;
+}
+
+weak_alias (__dup2, dup2)
diff --git a/sysdeps/mach/hurd/err_hurd.sub b/sysdeps/mach/hurd/err_hurd.sub
new file mode 100644
index 0000000000..b077d24786
--- /dev/null
+++ b/sysdeps/mach/hurd/err_hurd.sub
@@ -0,0 +1,11 @@
+/* This file defines the Mach error system for Hurd server errors.  */
+
+#include <stdio.h>
+#include <errno.h>
+
+/* Omit `const' because we are included with `static'
+   defined to `static const'.  */
+static struct error_subsystem err_hurd_sub[] =
+  {
+    { "(os/hurd)", _HURD_ERRNOS, (const char *const *) _sys_errlist },
+  };
diff --git a/sysdeps/mach/hurd/errlist.awk b/sysdeps/mach/hurd/errlist.awk
new file mode 100644
index 0000000000..a06ec88af7
--- /dev/null
+++ b/sysdeps/mach/hurd/errlist.awk
@@ -0,0 +1,77 @@
+# Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License
+# as published by the Free Software Foundation; either version 2 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
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB.  If
+# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+# Cambridge, MA 02139, USA.
+
+# errno.texinfo contains lines like:
+# @comment errno.h
+# @comment POSIX.1: Function not implemented
+# @deftypevr Macro int ENOSYS
+# @comment errno 78
+
+BEGIN {
+    print "/* This file is generated from errno.texi by errlist.awk.  */"
+    print "";
+    print "#ifndef HAVE_GNU_LD"
+    print "#define _sys_nerr sys_nerr"
+    print "#define _sys_errlist sys_errlist"
+    print "#endif"
+    print ""
+    print "const char *_sys_errlist[] =";
+    print "  {";
+    maxerrno = 0;
+    print "    \"Success\","
+  }
+$1 == "@comment" && $2 == "errno.h" { errnoh=1; next }
+errnoh == 1 && $1 == "@comment" \
+  {
+    ++errnoh;
+    etext = $3;
+    for (i = 4; i <= NF; ++i)
+      etext = etext " " $i;
+    next;
+  }
+errnoh == 2 && $1 == "@deftypevr" && $2 == "Macro" && $3 == "int" \
+  {
+    e = $4; errnoh++; next;
+  }
+errnoh == 3 && $1 == "@comment" && $2 == "errno" \
+  {
+    errno = $3 + 0;
+    msgs[errno] = etext;
+    names[errno] = e;
+    if (errno > maxerrno) maxerrno = errno;
+    next;
+  }
+{ errnoh=0 }
+END {
+  for (i = 1; i <= maxerrno; ++i)
+    {
+      if (names[i] == "")
+	print "    \"Reserved error " i "\",";
+      else
+	printf "%-40s/* %d = %s */\n", "    \"" msgs[i] "\",", i, names[i];
+    }
+  print "  };";
+  print "";
+  print "#include <errno.h>";
+  printf "#if _HURD_ERRNOS != %d\n", maxerrno+1;
+  print "#error errlist/errnos generation bug";
+  print "#endif"
+  printf "const int _sys_nerr = %d;\n", maxerrno+1;
+  print "weak_alias (_sys_errlist, sys_errlist)"
+  print "weak_alias (_sys_nerr, sys_nerr)"
+  }
diff --git a/sysdeps/mach/hurd/errlist.c b/sysdeps/mach/hurd/errlist.c
new file mode 100644
index 0000000000..b72cd7379a
--- /dev/null
+++ b/sysdeps/mach/hurd/errlist.c
@@ -0,0 +1,93 @@
+/* This file is generated from errno.texi by errlist.awk.  */
+
+#ifndef HAVE_GNU_LD
+#define _sys_nerr sys_nerr
+#define _sys_errlist sys_errlist
+#endif
+
+const char *_sys_errlist[] =
+  {
+    "Success",
+    "Operation not permitted",          /* 1 = EPERM */
+    "No such file or directory",        /* 2 = ENOENT */
+    "No such process",                  /* 3 = ESRCH */
+    "Interrupted system call",          /* 4 = EINTR */
+    "Input/output error",               /* 5 = EIO */
+    "Device not configured",            /* 6 = ENXIO */
+    "Argument list too long",           /* 7 = E2BIG */
+    "Exec format error",                /* 8 = ENOEXEC */
+    "Bad file descriptor",              /* 9 = EBADF */
+    "No child processes",               /* 10 = ECHILD */
+    "Resource deadlock avoided",        /* 11 = EDEADLK */
+    "Cannot allocate memory",           /* 12 = ENOMEM */
+    "Permission denied",                /* 13 = EACCES */
+    "Bad address",                      /* 14 = EFAULT */
+    "Block device required",            /* 15 = ENOTBLK */
+    "Device busy",                      /* 16 = EBUSY */
+    "File exists",                      /* 17 = EEXIST */
+    "Invalid cross-device link",        /* 18 = EXDEV */
+    "Operation not supported by device",/* 19 = ENODEV */
+    "Not a directory",                  /* 20 = ENOTDIR */
+    "Is a directory",                   /* 21 = EISDIR */
+    "Invalid argument",                 /* 22 = EINVAL */
+    "Too many open files",              /* 23 = EMFILE */
+    "Too many open files in system",    /* 24 = ENFILE */
+    "Inappropriate ioctl for device",   /* 25 = ENOTTY */
+    "Text file busy",                   /* 26 = ETXTBSY */
+    "File too large",                   /* 27 = EFBIG */
+    "No space left on device",          /* 28 = ENOSPC */
+    "Illegal seek",                     /* 29 = ESPIPE */
+    "Read-only file system",            /* 30 = EROFS */
+    "Too many links",                   /* 31 = EMLINK */
+    "Broken pipe",                      /* 32 = EPIPE */
+    "Numerical argument out of domain", /* 33 = EDOM */
+    "Numerical result out of range",    /* 34 = ERANGE */
+    "Operation would block",            /* 35 = EWOULDBLOCK */
+    "Operation now in progress",        /* 36 = EINPROGRESS */
+    "Operation already in progress",    /* 37 = EALREADY */
+    "Socket operation on non-socket",   /* 38 = ENOTSOCK */
+    "Destination address required",     /* 39 = EDESTADDRREQ */
+    "Message too long",                 /* 40 = EMSGSIZE */
+    "Protocol wrong type for socket",   /* 41 = EPROTOTYPE */
+    "Protocol not available",           /* 42 = ENOPROTOOPT */
+    "Protocol not supported",           /* 43 = EPROTONOSUPPORT */
+    "Socket type not supported",        /* 44 = ESOCKTNOSUPPORT */
+    "Operation not supported",          /* 45 = EOPNOTSUPP */
+    "Protocol family not supported",    /* 46 = EPFNOSUPPORT */
+    "Address family not supported by protocol family",/* 47 = EAFNOSUPPORT */
+    "Address already in use",           /* 48 = EADDRINUSE */
+    "Can't assign requested address",   /* 49 = EADDRNOTAVAIL */
+    "Network is down",                  /* 50 = ENETDOWN */
+    "Network is unreachable",           /* 51 = ENETUNREACH */
+    "Network dropped connection on reset",/* 52 = ENETRESET */
+    "Software caused connection abort", /* 53 = ECONNABORTED */
+    "Connection reset by peer",         /* 54 = ECONNRESET */
+    "No buffer space available",        /* 55 = ENOBUFS */
+    "Socket is already connected",      /* 56 = EISCONN */
+    "Socket is not connected",          /* 57 = ENOTCONN */
+    "Can't send after socket shutdown", /* 58 = ESHUTDOWN */
+    "Connection timed out",             /* 59 = ETIMEDOUT */
+    "Connection refused",               /* 60 = ECONNREFUSED */
+    "Too many levels of symbolic links",/* 61 = ELOOP */
+    "File name too long",               /* 62 = ENAMETOOLONG */
+    "Host is down",                     /* 63 = EHOSTDOWN */
+    "No route to host",                 /* 64 = EHOSTUNREACH */
+    "Directory not empty",              /* 65 = ENOTEMPTY */
+    "Too many users",                   /* 66 = EUSERS */
+    "Disc quota exceeded",              /* 67 = EDQUOT */
+    "Stale NFS file handle",            /* 68 = ESTALE */
+    "Too many levels of remote in path",/* 69 = EREMOTE */
+    "No locks available",               /* 70 = ENOLCK */
+    "Function not implemented",         /* 71 = ENOSYS */
+    "Inappropriate operation for background process",/* 72 = EBACKGROUND */
+    "?",                                /* 73 = ED */
+    "You really blew it this time",     /* 74 = EGREGIOUS */
+    "Computer bought the farm",         /* 75 = EIEIO */
+    "Gratuitous error",                 /* 76 = EGRATUITOUS */
+  };
+
+#include <errno.h>
+#if _HURD_ERRNOS != 77
+#error errlist/errnos generation bug
+#endif
+const int _sys_nerr = 77;
diff --git a/sysdeps/mach/hurd/errnos.awk b/sysdeps/mach/hurd/errnos.awk
new file mode 100644
index 0000000000..a6b251f211
--- /dev/null
+++ b/sysdeps/mach/hurd/errnos.awk
@@ -0,0 +1,157 @@
+# Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License
+# as published by the Free Software Foundation; either version 2 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
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB.  If
+# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+# Cambridge, MA 02139, USA.
+
+# errno.texinfo contains lines like:
+# @comment errno.h
+# @comment POSIX.1: Function not implemented
+# @deftypevr Macro int ENOSYS
+
+BEGIN {
+    printf "/* This file generated by";
+    for (i = 0; i < ARGC; ++i)
+      printf " %s", ARGV[i];
+    printf ".  */\n";
+    print "";
+    print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */";
+    print "#ifndef _HURD_ERRNO";
+    print "#define _HURD_ERRNO(n)\t((0x10 << 26) | ((n) & 0x3fff))";
+    print "#endif";
+    print "";
+    print "#ifdef _ERRNO_H\n";
+    print "enum __error_t_codes\n{";
+    errnoh = 0;
+    maxerrno = 0;
+    in_mach_errors = 0;
+    in_math = 0;
+    edom = erange = "";
+    print "#undef EDOM\n#undef ERANGE";
+  }
+
+$1 == "@comment" && $2 == "errno.h" { errnoh=1; next }
+$1 == "@comment" && errnoh == 1 \
+  {
+    ++errnoh;
+    etext = "";
+    for (i = 3; i <= NF; ++i)
+      etext = etext " " $i;
+    next;
+  }
+
+errnoh == 2 && $1 == "@deftypevr"  && $2 == "Macro" && $3 == "int" \
+  { ++errnoh; e = $4; next; }
+
+errnoh == 3 && $1 == "@comment" && $2 == "errno" {
+    errno = $3 + 0;
+    if (errno > maxerrno) maxerrno = errno;
+    if (e == "EWOULDBLOCK")
+      {
+	print "#define EWOULDBLOCK EAGAIN /* Operation would block */";
+	next;
+      }
+    x = sprintf ("%-40s/*%s */", sprintf ("%-24s%s", "#define\t" e,
+					  "_HURD_ERRNO (" errno ")"),
+		 etext);
+    if (e == "EDOM")
+      edom = x;
+    else if (e == "ERANGE")
+      erange = x;
+    printf "\t%-16s= _HURD_ERRNO (%d),\n", e, errno;
+    print x;
+    next;
+  }
+{ errnoh=0 }
+
+NF == 3 && $1 == "#define" && $2 == "MACH_SEND_IN_PROGRESS" \
+  {
+    in_mach_errors = 1;
+    print "\n\t/* Errors from <mach/message.h>.  */";
+  }
+NF == 3 && $1 == "#define" && $2 == "KERN_SUCCESS" \
+  {
+    in_mach_errors = 1;
+    print "\n\t/* Errors from <mach/kern_return.h>.  */";
+    next;
+  }
+
+in_mach_errors && $2 == "MACH_IPC_COMPAT" \
+  {
+    in_mach_errors = 0;
+  }
+
+in_mach_errors == 1 && NF == 3 && $1 == "#define" \
+  {
+    printf "\t%-32s= %s,\n", "E" $2, $3;
+  }
+
+$1 == "#define" && $2 == "_MACH_MIG_ERRORS_H_" \
+  {
+    in_mig_errors = 1;
+    print "\n\t/* Errors from <mach/mig_errors.h>.  */";
+    next;
+  }
+in_mig_errors && $1 == "#endif" && $3 == "_MACH_MIG_ERRORS_H_" \
+  {
+    in_mig_errors = 0;
+  }
+
+(in_mig_errors && $1 == "#define" && $3 <= -300) || \
+(in_device_errors && $1 == "#define") \
+  {
+    printf "%-32s", sprintf ("\t%-24s= %s,", "E" $2, $3);
+    for (i = 4; i <= NF; ++i)
+      printf " %s", $i;
+    printf "\n";
+  }
+
+$1 == "#define" && $2 == "D_SUCCESS" \
+  {
+    in_device_errors = 1;
+    print "\n\t/* Errors from <device/device_types.h>.  */";
+    next;
+  }
+in_device_errors && $1 == "#endif" \
+  {
+    in_device_errors = 0;
+  }
+
+
+END \
+  {
+    print "";
+    print "};";
+    print "";
+    printf "#define\t_HURD_ERRNOS\t%d\n", maxerrno+1;
+    print "";
+    print "\
+/* User-visible type of error codes.  It is ok to use `int' or\n\
+   `kern_return_t' for these, but with `error_t' the debugger prints\n\
+   symbolic values.  */";
+    print "#ifdef __USE_GNU";
+    print "typedef enum __error_t_codes error_t;"
+    print "#endif";
+    print "";
+    print "/* errno is a per-thread variable.  */";
+    print "#include <hurd/threadvar.h>";
+    print "#define errno	(*__hurd_errno_location ())";
+    print "";
+    print "#endif /* <errno.h> included.  */";
+    print "";
+    print "#if !defined (_ERRNO_H) && defined (__need_Emath)";
+    print edom; print erange;
+    print "#endif /* <errno.h> not included and need math error codes.  */";
+  }
diff --git a/sysdeps/mach/hurd/errnos.h b/sysdeps/mach/hurd/errnos.h
new file mode 100644
index 0000000000..911af3c5c8
--- /dev/null
+++ b/sysdeps/mach/hurd/errnos.h
@@ -0,0 +1,266 @@
+/* This file generated by gawk manual/errno.texi ../mach/mach/message.h ../mach/mach/kern_return.h ../mach/mach/mig_errors.h ../mach/device/device_types.h.  */
+
+/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */
+#ifndef _HURD_ERRNO
+#define _HURD_ERRNO(n)	((0x10 << 26) | ((n) & 0x3fff))
+#endif
+
+#ifdef _ERRNO_H
+
+enum __error_t_codes
+{
+#undef EDOM
+#undef ERANGE
+	EPERM           = _HURD_ERRNO (1),
+#define	EPERM           _HURD_ERRNO (1) /* Operation not permitted */
+	ENOENT          = _HURD_ERRNO (2),
+#define	ENOENT          _HURD_ERRNO (2) /* No such file or directory */
+	ESRCH           = _HURD_ERRNO (3),
+#define	ESRCH           _HURD_ERRNO (3) /* No such process */
+	EINTR           = _HURD_ERRNO (4),
+#define	EINTR           _HURD_ERRNO (4) /* Interrupted system call */
+	EIO             = _HURD_ERRNO (5),
+#define	EIO             _HURD_ERRNO (5) /* Input/output error */
+	ENXIO           = _HURD_ERRNO (6),
+#define	ENXIO           _HURD_ERRNO (6) /* Device not configured */
+	E2BIG           = _HURD_ERRNO (7),
+#define	E2BIG           _HURD_ERRNO (7) /* Argument list too long */
+	ENOEXEC         = _HURD_ERRNO (8),
+#define	ENOEXEC         _HURD_ERRNO (8) /* Exec format error */
+	EBADF           = _HURD_ERRNO (9),
+#define	EBADF           _HURD_ERRNO (9) /* Bad file descriptor */
+	ECHILD          = _HURD_ERRNO (10),
+#define	ECHILD          _HURD_ERRNO (10)/* No child processes */
+	EDEADLK         = _HURD_ERRNO (11),
+#define	EDEADLK         _HURD_ERRNO (11)/* Resource deadlock avoided */
+	ENOMEM          = _HURD_ERRNO (12),
+#define	ENOMEM          _HURD_ERRNO (12)/* Cannot allocate memory */
+	EACCES          = _HURD_ERRNO (13),
+#define	EACCES          _HURD_ERRNO (13)/* Permission denied */
+	EFAULT          = _HURD_ERRNO (14),
+#define	EFAULT          _HURD_ERRNO (14)/* Bad address */
+	ENOTBLK         = _HURD_ERRNO (15),
+#define	ENOTBLK         _HURD_ERRNO (15)/* Block device required */
+	EBUSY           = _HURD_ERRNO (16),
+#define	EBUSY           _HURD_ERRNO (16)/* Device busy */
+	EEXIST          = _HURD_ERRNO (17),
+#define	EEXIST          _HURD_ERRNO (17)/* File exists */
+	EXDEV           = _HURD_ERRNO (18),
+#define	EXDEV           _HURD_ERRNO (18)/* Invalid cross-device link */
+	ENODEV          = _HURD_ERRNO (19),
+#define	ENODEV          _HURD_ERRNO (19)/* Operation not supported by device */
+	ENOTDIR         = _HURD_ERRNO (20),
+#define	ENOTDIR         _HURD_ERRNO (20)/* Not a directory */
+	EISDIR          = _HURD_ERRNO (21),
+#define	EISDIR          _HURD_ERRNO (21)/* Is a directory */
+	EINVAL          = _HURD_ERRNO (22),
+#define	EINVAL          _HURD_ERRNO (22)/* Invalid argument */
+	EMFILE          = _HURD_ERRNO (23),
+#define	EMFILE          _HURD_ERRNO (23)/* Too many open files */
+	ENFILE          = _HURD_ERRNO (24),
+#define	ENFILE          _HURD_ERRNO (24)/* Too many open files in system */
+	ENOTTY          = _HURD_ERRNO (25),
+#define	ENOTTY          _HURD_ERRNO (25)/* Inappropriate ioctl for device */
+	ETXTBSY         = _HURD_ERRNO (26),
+#define	ETXTBSY         _HURD_ERRNO (26)/* Text file busy */
+	EFBIG           = _HURD_ERRNO (27),
+#define	EFBIG           _HURD_ERRNO (27)/* File too large */
+	ENOSPC          = _HURD_ERRNO (28),
+#define	ENOSPC          _HURD_ERRNO (28)/* No space left on device */
+	ESPIPE          = _HURD_ERRNO (29),
+#define	ESPIPE          _HURD_ERRNO (29)/* Illegal seek */
+	EROFS           = _HURD_ERRNO (30),
+#define	EROFS           _HURD_ERRNO (30)/* Read-only file system */
+	EMLINK          = _HURD_ERRNO (31),
+#define	EMLINK          _HURD_ERRNO (31)/* Too many links */
+	EPIPE           = _HURD_ERRNO (32),
+#define	EPIPE           _HURD_ERRNO (32)/* Broken pipe */
+	EDOM            = _HURD_ERRNO (33),
+#define	EDOM            _HURD_ERRNO (33)/* Numerical argument out of domain */
+	ERANGE          = _HURD_ERRNO (34),
+#define	ERANGE          _HURD_ERRNO (34)/* Numerical result out of range */
+	EAGAIN          = _HURD_ERRNO (35),
+#define	EAGAIN          _HURD_ERRNO (35)/* Resource temporarily unavailable */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+	EINPROGRESS     = _HURD_ERRNO (36),
+#define	EINPROGRESS     _HURD_ERRNO (36)/* Operation now in progress */
+	EALREADY        = _HURD_ERRNO (37),
+#define	EALREADY        _HURD_ERRNO (37)/* Operation already in progress */
+	ENOTSOCK        = _HURD_ERRNO (38),
+#define	ENOTSOCK        _HURD_ERRNO (38)/* Socket operation on non-socket */
+	EDESTADDRREQ    = _HURD_ERRNO (39),
+#define	EDESTADDRREQ    _HURD_ERRNO (39)/* Destination address required */
+	EMSGSIZE        = _HURD_ERRNO (40),
+#define	EMSGSIZE        _HURD_ERRNO (40)/* Message too long */
+	EPROTOTYPE      = _HURD_ERRNO (41),
+#define	EPROTOTYPE      _HURD_ERRNO (41)/* Protocol wrong type for socket */
+	ENOPROTOOPT     = _HURD_ERRNO (42),
+#define	ENOPROTOOPT     _HURD_ERRNO (42)/* Protocol not available */
+	EPROTONOSUPPORT = _HURD_ERRNO (43),
+#define	EPROTONOSUPPORT _HURD_ERRNO (43)/* Protocol not supported */
+	ESOCKTNOSUPPORT = _HURD_ERRNO (44),
+#define	ESOCKTNOSUPPORT _HURD_ERRNO (44)/* Socket type not supported */
+	EOPNOTSUPP      = _HURD_ERRNO (45),
+#define	EOPNOTSUPP      _HURD_ERRNO (45)/* Operation not supported */
+	EPFNOSUPPORT    = _HURD_ERRNO (46),
+#define	EPFNOSUPPORT    _HURD_ERRNO (46)/* Protocol family not supported */
+	EAFNOSUPPORT    = _HURD_ERRNO (47),
+#define	EAFNOSUPPORT    _HURD_ERRNO (47)/* Address family not supported by protocol family */
+	EADDRINUSE      = _HURD_ERRNO (48),
+#define	EADDRINUSE      _HURD_ERRNO (48)/* Address already in use */
+	EADDRNOTAVAIL   = _HURD_ERRNO (49),
+#define	EADDRNOTAVAIL   _HURD_ERRNO (49)/* Can't assign requested address */
+	ENETDOWN        = _HURD_ERRNO (50),
+#define	ENETDOWN        _HURD_ERRNO (50)/* Network is down */
+	ENETUNREACH     = _HURD_ERRNO (51),
+#define	ENETUNREACH     _HURD_ERRNO (51)/* Network is unreachable */
+	ENETRESET       = _HURD_ERRNO (52),
+#define	ENETRESET       _HURD_ERRNO (52)/* Network dropped connection on reset */
+	ECONNABORTED    = _HURD_ERRNO (53),
+#define	ECONNABORTED    _HURD_ERRNO (53)/* Software caused connection abort */
+	ECONNRESET      = _HURD_ERRNO (54),
+#define	ECONNRESET      _HURD_ERRNO (54)/* Connection reset by peer */
+	ENOBUFS         = _HURD_ERRNO (55),
+#define	ENOBUFS         _HURD_ERRNO (55)/* No buffer space available */
+	EISCONN         = _HURD_ERRNO (56),
+#define	EISCONN         _HURD_ERRNO (56)/* Socket is already connected */
+	ENOTCONN        = _HURD_ERRNO (57),
+#define	ENOTCONN        _HURD_ERRNO (57)/* Socket is not connected */
+	ESHUTDOWN       = _HURD_ERRNO (58),
+#define	ESHUTDOWN       _HURD_ERRNO (58)/* Can't send after socket shutdown */
+	ETIMEDOUT       = _HURD_ERRNO (59),
+#define	ETIMEDOUT       _HURD_ERRNO (59)/* Connection timed out */
+	ECONNREFUSED    = _HURD_ERRNO (60),
+#define	ECONNREFUSED    _HURD_ERRNO (60)/* Connection refused */
+	ELOOP           = _HURD_ERRNO (61),
+#define	ELOOP           _HURD_ERRNO (61)/* Too many levels of symbolic links */
+	ENAMETOOLONG    = _HURD_ERRNO (62),
+#define	ENAMETOOLONG    _HURD_ERRNO (62)/* File name too long */
+	EHOSTDOWN       = _HURD_ERRNO (63),
+#define	EHOSTDOWN       _HURD_ERRNO (63)/* Host is down */
+	EHOSTUNREACH    = _HURD_ERRNO (64),
+#define	EHOSTUNREACH    _HURD_ERRNO (64)/* No route to host */
+	ENOTEMPTY       = _HURD_ERRNO (65),
+#define	ENOTEMPTY       _HURD_ERRNO (65)/* Directory not empty */
+	EUSERS          = _HURD_ERRNO (66),
+#define	EUSERS          _HURD_ERRNO (66)/* Too many users */
+	EDQUOT          = _HURD_ERRNO (67),
+#define	EDQUOT          _HURD_ERRNO (67)/* Disc quota exceeded */
+	ESTALE          = _HURD_ERRNO (68),
+#define	ESTALE          _HURD_ERRNO (68)/* Stale NFS file handle */
+	EREMOTE         = _HURD_ERRNO (69),
+#define	EREMOTE         _HURD_ERRNO (69)/* Too many levels of remote in path */
+	ENOLCK          = _HURD_ERRNO (70),
+#define	ENOLCK          _HURD_ERRNO (70)/* No locks available */
+	ENOSYS          = _HURD_ERRNO (71),
+#define	ENOSYS          _HURD_ERRNO (71)/* Function not implemented */
+	EBACKGROUND     = _HURD_ERRNO (72),
+#define	EBACKGROUND     _HURD_ERRNO (72)/* Inappropriate operation for background process */
+	ED              = _HURD_ERRNO (73),
+#define	ED              _HURD_ERRNO (73)/* ? */
+	EGREGIOUS       = _HURD_ERRNO (74),
+#define	EGREGIOUS       _HURD_ERRNO (74)/* You really blew it this time */
+	EIEIO           = _HURD_ERRNO (75),
+#define	EIEIO           _HURD_ERRNO (75)/* Computer bought the farm */
+	EGRATUITOUS     = _HURD_ERRNO (76),
+#define	EGRATUITOUS     _HURD_ERRNO (76)/* Gratuitous error */
+
+	/* 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,
+
+	/* 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 */
+
+};
+
+#define	_HURD_ERRNOS	77
+
+/* 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.  */
+#ifdef __USE_GNU
+typedef enum __error_t_codes error_t;
+#endif
+
+/* errno is a per-thread variable.  */
+#include <hurd/threadvar.h>
+#define errno	(*__hurd_errno_location ())
+
+#endif /* <errno.h> included.  */
+
+#if !defined (_ERRNO_H) && defined (__need_Emath)
+#define	EDOM            _HURD_ERRNO (33)/* Numerical argument out of domain */
+#define	ERANGE          _HURD_ERRNO (34)/* Numerical result out of range */
+#endif /* <errno.h> not included and need math error codes.  */
diff --git a/sysdeps/mach/hurd/execve.c b/sysdeps/mach/hurd/execve.c
new file mode 100644
index 0000000000..5a45f5f42e
--- /dev/null
+++ b/sysdeps/mach/hurd/execve.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <fcntl.h>
+
+/* Replace the current process, executing FILE_NAME with arguments ARGV and
+   environment ENVP.  ARGV and ENVP are terminated by NULL pointers.  */
+int
+DEFUN(__execve, (file_name, argv, envp),
+      CONST char *file_name AND char *CONST argv[] AND char *CONST envp[])
+{
+  error_t err;
+  file_t file = __file_name_lookup (file_name, O_EXEC, 0);
+
+  if (file == MACH_PORT_NULL)
+    return -1;
+
+  /* Hopefully this will not return.  */
+  err = _hurd_exec (__mach_task_self (), file, argv, envp);
+
+  /* Oh well.  Might as well be tidy.  */
+  __mach_port_deallocate (__mach_task_self (), file);
+
+  return __hurd_fail (err);
+}
+
+weak_alias (__execve, execve)
diff --git a/sysdeps/mach/hurd/fchdir.c b/sysdeps/mach/hurd/fchdir.c
new file mode 100644
index 0000000000..088bba9d16
--- /dev/null
+++ b/sysdeps/mach/hurd/fchdir.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/fd.h>
+
+/* Change the current directory to FD.  */
+int
+DEFUN(fchdir, (fd), int fd)
+{
+  error_t err;
+  file_t cwdir;
+
+  err = __USEPORT (CRDIR,
+		   ({ file_t crdir = port;
+		      HURD_DPORT_USE (fd,
+				      __hurd_file_name_lookup (crdir, port, "",
+							       0, 0, &cwdir));
+		    }));
+
+  if (err)
+    return __hurd_fail (err);
+
+  _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], cwdir);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/fchflags.c b/sysdeps/mach/hurd/fchflags.c
new file mode 100644
index 0000000000..aa1e32696d
--- /dev/null
+++ b/sysdeps/mach/hurd/fchflags.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the flags of the file FD refers to to FLAGS.  */
+int
+DEFUN(fchflags, (fd, flags), int fd AND int flags)
+{
+  error_t err;
+
+  if (err = HURD_DPORT_USE (fd, __file_chflags (port, flags)))
+    return __hurd_dfail (fd, err);
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/fchmod.c b/sysdeps/mach/hurd/fchmod.c
new file mode 100644
index 0000000000..3dc84ff11a
--- /dev/null
+++ b/sysdeps/mach/hurd/fchmod.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991, 1992, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the protections of the file FD refers to to MODE.  */
+int
+DEFUN(__fchmod, (fd, mode), int fd AND mode_t mode)
+{
+  error_t err;
+
+  if (err = HURD_DPORT_USE (fd, __file_chmod (port, mode)))
+    return __hurd_dfail (fd, err);
+
+  return 0;
+}
+
+weak_alias (__fchmod, fchmod)
diff --git a/sysdeps/mach/hurd/fchown.c b/sysdeps/mach/hurd/fchown.c
new file mode 100644
index 0000000000..c2f873c78d
--- /dev/null
+++ b/sysdeps/mach/hurd/fchown.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Change the owner and group of the file referred to by FD.  */
+int
+DEFUN(__fchown, (fd, owner, group),
+      int fd AND uid_t owner AND gid_t group)
+{
+  error_t err;
+
+  if (err = HURD_DPORT_USE (fd, __file_chown (port, owner, group)))
+    return __hurd_dfail (fd, err);
+
+  return 0;
+}
+
+weak_alias (__fchown, fchown)
diff --git a/sysdeps/mach/hurd/fcntl.c b/sysdeps/mach/hurd/fcntl.c
new file mode 100644
index 0000000000..4b7207f7ee
--- /dev/null
+++ b/sysdeps/mach/hurd/fcntl.c
@@ -0,0 +1,159 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <stdarg.h>
+
+
+/* Perform file control operations on FD.  */
+int
+DEFUN(__fcntl, (fd, cmd), int fd AND int cmd DOTS)
+{
+  va_list ap;
+  struct hurd_fd *d;
+  int result;
+
+  d = _hurd_fd_get (fd);
+
+  if (d == NULL)
+    return __hurd_fail (EBADF);
+
+  va_start (ap, cmd);
+
+  switch (cmd)
+    {
+      error_t err;
+
+    default:			/* Bad command.  */
+      errno = EINVAL;
+      result = -1;
+      break;
+
+      /* First the descriptor-based commands, which do no RPCs.  */
+
+    case F_DUPFD:		/* Duplicate the file descriptor.  */
+      {
+	struct hurd_fd *new;
+	io_t port, ctty;
+	struct hurd_userlink ulink, ctty_ulink;
+	int flags;
+
+	HURD_CRITICAL_BEGIN;
+
+	/* Extract the ports and flags from the file descriptor.  */
+	__spin_lock (&d->port.lock);
+	flags = d->flags;
+	ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
+	port = _hurd_port_locked_get (&d->port, &ulink); /* Unlocks D.  */
+
+	/* Get a new file descriptor.  The third argument to __fcntl is the
+	   minimum file descriptor number for it.  */
+	new = _hurd_alloc_fd (&result, va_arg (ap, int));
+	if (new == NULL)
+	  /* _hurd_alloc_fd has set errno.  */
+	  result = -1;
+	else
+	  {
+	    /* Give the ports each a user ref for the new descriptor.  */
+	    __mach_port_mod_refs (__mach_task_self (), port,
+				  MACH_PORT_RIGHT_SEND, 1);
+	    if (ctty != MACH_PORT_NULL)
+	      __mach_port_mod_refs (__mach_task_self (), ctty,
+				    MACH_PORT_RIGHT_SEND, 1);
+
+	    /* Install the ports and flags in the new descriptor.  */
+	    if (ctty != MACH_PORT_NULL)
+	      _hurd_port_set (&new->ctty, ctty);
+	    /* Duplication clears the FD_CLOEXEC flag.  */
+	    new->flags = flags & ~FD_CLOEXEC;
+	    _hurd_port_locked_set (&new->port, port); /* Unlocks NEW.  */
+	  }
+
+	HURD_CRITICAL_END;
+
+	_hurd_port_free (&d->port, &ulink, port);
+	if (ctty != MACH_PORT_NULL)
+	  _hurd_port_free (&d->ctty, &ctty_ulink, port);
+
+	break;
+      }
+
+      /* Set RESULT by evaluating EXPR with the descriptor locked.
+	 Check for an empty descriptor and return EBADF.  */
+#define LOCKED(expr)							      \
+      HURD_CRITICAL_BEGIN;						      \
+      __spin_lock (&d->port.lock);					      \
+      if (d->port.port == MACH_PORT_NULL)				      \
+	result = __hurd_fail (EBADF);					      \
+      else								      \
+	result = (expr);						      \
+      __spin_unlock (&d->port.lock);					      \
+      HURD_CRITICAL_END;
+
+    case F_GETFD:		/* Get descriptor flags.  */
+      LOCKED (d->flags);
+      break;
+
+    case F_SETFD:		/* Set descriptor flags.  */
+      LOCKED ((d->flags = va_arg (ap, int), 0));
+      break;
+
+
+      /* Now the real io operations, done by RPCs to io servers.  */
+
+    case F_GETLK:
+    case F_SETLK:
+    case F_SETLKW:
+      {
+	struct flock *fl = va_arg (ap, struct flock *);
+	errno = fl?ENOSYS:EINVAL; /* XXX mib needs to implement io rpcs.  */
+	result = -1;
+	break;
+      }
+
+    case F_GETFL:		/* Get per-open flags.  */
+      if (err = HURD_FD_PORT_USE (d, __io_get_openmodes (port, &result)))
+	result = __hurd_dfail (fd, err);
+      break;
+
+    case F_SETFL:		/* Set per-open flags.  */
+      err = HURD_FD_PORT_USE (d, __io_set_all_openmodes (port,
+							 va_arg (ap, int)));
+      result = err ? __hurd_dfail (fd, err) : 0;
+
+    case F_GETOWN:		/* Get owner.  */
+      if (err = HURD_FD_PORT_USE (d, __io_get_owner (port, &result)))
+	result = __hurd_dfail (fd, err);
+      break;
+
+    case F_SETOWN:		/* Set owner.  */
+      err = HURD_FD_PORT_USE (d, __io_mod_owner (port, va_arg (ap, pid_t)));
+      result = err ? __hurd_dfail (fd, err) : 0;
+      break;
+    }
+
+  va_end (ap);
+
+  return result;
+}
+
+weak_alias (__fcntl, fcntl)
diff --git a/sysdeps/mach/hurd/fcntlbits.h b/sysdeps/mach/hurd/fcntlbits.h
new file mode 100644
index 0000000000..8a5e4cd52a
--- /dev/null
+++ b/sysdeps/mach/hurd/fcntlbits.h
@@ -0,0 +1,178 @@
+/* O_*, F_*, FD_* bit values for GNU.
+Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef	_FCNTLBITS_H
+
+#define	_FCNTLBITS_H	1
+
+
+/* File access modes.  These are understood by io servers; they can be
+   passed in `dir_lookup', and are returned by `io_get_openmodes'.
+   Consequently they can be passed to `open', `hurd_file_name_lookup', and
+   `file_name_lookup'; and are returned by `fcntl' with the F_GETFL
+   command.  */
+
+/* In GNU, read and write are bits (unlike BSD).  */
+#ifdef __USE_GNU
+#define	O_READ		O_RDONLY /* Open for reading.  */
+#define O_WRITE		O_WRONLY /* Open for writing.  */
+#define	O_EXEC		0x0004	/* Open for execution.  */
+#endif
+/* POSIX.1 standard names.  */
+#define	O_RDONLY	0x0001	/* Open read-only.  */
+#define	O_WRONLY	0x0002	/* Open write-only.  */
+#define	O_RDWR		(O_RDONLY|O_WRONLY) /* Open for reading and writing. */
+#define	O_ACCMODE	O_RDWR	/* Mask for file access modes.  */
+
+
+
+/* File name translation flags.  These are understood by io servers;
+   they can be passed in `dir_lookup', and consequently to `open',
+   `hurd_file_name_lookup', and `file_name_lookup'.  */
+
+#define	O_CREAT		0x0010	/* Create file if it doesn't exist.  */
+#define	O_EXCL		0x0020	/* Fail if file already exists.  */
+#ifdef __USE_GNU
+#define	O_NOLINK	0x0040	/* No name mappings on final component.  */
+#define	O_NOTRANS	0x0080	/* No translator on final component. */
+#endif
+
+
+/* I/O operating modes.  These are understood by io servers; they can be
+   passed in `dir_lookup' and set or fetched with `io_*_openmodes'.
+   Consequently they can be passed to `open', `hurd_file_name_lookup',
+   `file_name_lookup', and `fcntl' with the F_SETFL command; and are
+   returned by `fcntl' with the F_GETFL command.  */
+
+#define	O_APPEND	0x0100	/* Writes always append to the file.  */
+#ifdef __USE_BSD
+#define	O_ASYNC		0x0200	/* Send SIGIO to owner when data is ready.  */
+#define	O_FSYNC		0x0400	/* Synchronous writes.  */
+#define	O_SYNC		O_FSYNC
+#endif
+#ifdef __USE_GNU
+#define	O_NOATIME	0x0800	/* Don't set access time on read (owner).  */
+#endif
+
+
+/* The name O_NONBLOCK is unfortunately overloaded; it is both a file name
+   translation flag and an I/O operating mode.  O_NDELAY is the deprecated
+   BSD name for the same flag, overloaded in the same way.
+
+   When used in `dir_lookup' (and consequently `open', `hurd_file_name_lookup',
+   or `file_name_lookup'), O_NONBLOCK says the open should return immediately
+   instead of blocking for any significant length of time (e.g., to wait
+   for carrier detect on a serial line).  It is also saved as an I/O
+   operating mode, and after open has the following meaning.
+
+   When used in `io_*_openmodes' (and consequently `fcntl' with the F_SETFL
+   command), the O_NONBLOCK flag means to do nonblocking i/o: any i/o
+   operation that would block for any significant length of time will instead
+   fail with EAGAIN.  */
+
+#define	O_NONBLOCK	0x0008	/* Non-blocking open or non-blocking I/O.  */
+#ifdef __USE_BSD
+#define	O_NDELAY	O_NONBLOCK /* Deprecated.  */
+#endif
+
+
+#ifdef __USE_GNU
+/* Mask of bits which are understood by io servers.  */
+#define O_HURD		0xffff	/* XXX name? want this? */
+#endif
+
+
+/* Open-time action flags.  These are understood by `hurd_file_name_lookup'
+   and consequently by `open' and `file_name_lookup'.  They are not preserved
+   once the file has been opened.  */
+
+#define	O_TRUNC		0x00010000 /* Truncate file to zero length.  */
+#ifdef	__USE_MISC
+#define	O_SHLOCK	0x00020000 /* Open with shared file lock.  */
+#define	O_EXLOCK	0x00040000 /* Open with exclusive file lock.  */
+#endif
+
+
+/* Controlling terminal flags.  These are understood only by `open',
+   and are not preserved once the file has been opened.  */
+
+#ifdef __USE_GNU
+#define	O_IGNORE_CTTY	0x00080000 /* Don't do any ctty magic at all.  */
+#endif
+/* `open' never assigns a controlling terminal in GNU.  */
+#define	O_NOCTTY	0	/* Don't assign a controlling terminal.  */
+
+
+#ifdef __USE_BSD
+/* Bits in the file status flags returned by F_GETFL.  */
+#define FREAD		O_RDONLY
+#define	FWRITE		O_WRONLY
+
+/* Traditional BSD names the O_* bits.  */
+#define FASYNC		O_ASYNC
+#define FCREAT		O_CREAT
+#define FEXCL		O_EXCL
+#define FTRUNC		O_TRUNC
+#define FNOCTTY		O_NOCTTY
+#define FFSYNC		O_FSYNC
+#define FSYNC		O_SYNC
+#define FAPPEND		O_APPEND
+#define FNONBLOCK	O_NONBLOCK
+#define FNDELAY		O_NDELAY
+#endif
+
+
+/* Values for the second argument to `fcntl'.  */
+#define	F_DUPFD	  	0	/* Duplicate file descriptor.  */
+#define	F_GETFD		1	/* Get file descriptor flags.  */
+#define	F_SETFD		2	/* Set file descriptor flags.  */
+#define	F_GETFL		3	/* Get file status flags.  */
+#define	F_SETFL		4	/* Set file status flags.  */
+#ifdef __USE_BSD
+#define	F_GETOWN	5	/* Get owner (receiver of SIGIO).  */
+#define	F_SETOWN	6	/* Set owner (receiver of SIGIO).  */
+#endif
+#define	F_GETLK		7	/* Get record locking info.  */
+#define	F_SETLK		8	/* Set record locking info (non-blocking).  */
+#define	F_SETLKW	9	/* Set record locking info (blocking).  */
+
+/* File descriptor flags used with F_GETFD and F_SETFD.  */
+#define	FD_CLOEXEC	1	/* Close on exec.  */
+
+
+#include <gnu/types.h>
+
+/* The structure describing an advisory lock.  This is the type of the third
+   argument to `fcntl' for the F_GETLK, F_SETLK, and F_SETLKW requests.  */
+struct flock
+  {
+    int l_type;		/* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    int l_whence;	/* Where `l_start' is relative to (like `lseek').  */
+    __off_t l_start;	/* Offset where the lock begins.  */
+    __off_t l_len;	/* Size of the locked area; zero means until EOF.  */
+    __pid_t l_pid;	/* Process holding the lock.  */
+  };
+
+/* Values for the `l_type' field of a `struct flock'.  */
+#define	F_RDLCK	1	/* Read lock.  */
+#define	F_WRLCK	2	/* Write lock.  */
+#define	F_UNLCK	3	/* Remove lock.  */
+
+
+#endif	/* fcntlbits.h */
diff --git a/sysdeps/mach/hurd/fdopen.c b/sysdeps/mach/hurd/fdopen.c
new file mode 100644
index 0000000000..3fdd742a59
--- /dev/null
+++ b/sysdeps/mach/hurd/fdopen.c
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+#include <hurd/io.h>
+
+/* Defined in fopen.c.  */
+extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr));
+
+/* Open a new stream on a given system file descriptor.  */
+FILE *
+DEFUN(fdopen, (fd, mode), int fd AND CONST char *mode)
+{
+  FILE *stream;
+  __io_mode m;
+  struct hurd_fd *d;
+  error_t err;
+  int openmodes;
+
+  if (!__getmode (mode, &m))
+    return NULL;
+
+  HURD_CRITICAL_BEGIN;
+  d = _hurd_fd_get (fd);
+  if (d == NULL)
+    err = EBADF;
+  else
+    err = HURD_FD_PORT_USE (d, __io_get_openmodes (port, &openmodes));
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_dfail (fd, err), NULL;
+
+  /* Check the access mode.  */
+  if ((m.__read && !(openmodes & O_READ)) ||
+      (m.__write && !(openmodes & O_WRITE)))
+    {
+      errno = EBADF;
+      return NULL;
+    }
+
+  stream = __newstream ();
+  if (stream == NULL)
+    return NULL;
+
+  stream->__cookie = d;
+  stream->__mode = m;
+
+  return stream;
+}
diff --git a/sysdeps/mach/hurd/fexecve.c b/sysdeps/mach/hurd/fexecve.c
new file mode 100644
index 0000000000..e4f2cda1a2
--- /dev/null
+++ b/sysdeps/mach/hurd/fexecve.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <errno.h>
+
+/* Execute the file FD refers to, overlaying the running program image.  */
+
+int
+fexecve (int fd, char *const argv[], char *const envp[])
+{
+  error_t err = HURD_DPORT_USE (fd, _hurd_exec (__mach_task_self (), port,
+						argv, envp));
+  if (! err)
+    err = EGRATUITOUS;
+  return __hurd_fail (err);
+}
diff --git a/sysdeps/mach/hurd/flock.c b/sysdeps/mach/hurd/flock.c
new file mode 100644
index 0000000000..6154fd2292
--- /dev/null
+++ b/sysdeps/mach/hurd/flock.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1992, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/file.h>
+#include <hurd/fd.h>
+#include <hurd/fs.h>
+
+/* Apply or remove an advisory lock, according to OPERATION,
+   on the file FD refers to.  */
+int
+DEFUN(__flock, (fd, operation),
+      int fd AND int operation)
+{
+  error_t err;
+
+  if (err = HURD_DPORT_USE (fd, __file_lock (port, operation)))
+    return __hurd_dfail (fd, err);
+
+  return 0;
+}
+
+weak_alias (__flock, flock)
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
new file mode 100644
index 0000000000..b9170f155e
--- /dev/null
+++ b/sysdeps/mach/hurd/fork.c
@@ -0,0 +1,574 @@
+/* Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include "thread_state.h"
+#include <sysdep.h>		/* For stack growth direction.  */
+#include "set-hooks.h"
+#include <assert.h>
+#include "hurdmalloc.h"		/* XXX */
+
+extern void _hurd_longjmp_thread_state (struct machine_thread_state *,
+					jmp_buf env, int value);
+
+
+/* Things that want to be locked while forking.  */
+struct
+  {
+    size_t n;
+    struct mutex *locks[0];
+  } _hurd_fork_locks;
+
+
+/* Things that want to be called before we fork, to prepare the parent for
+   task_create, when the new child task will inherit our address space.  */
+DEFINE_HOOK (_hurd_fork_prepare_hook, (void));
+
+/* Things that want to be called when we are forking, with the above all
+   locked.  They are passed the task port of the child.  The child process
+   is all set up except for doing proc_child, and has no threads yet.  */
+DEFINE_HOOK (_hurd_fork_setup_hook, (void));
+
+/* Things to be run in the child fork.  */
+DEFINE_HOOK (_hurd_fork_child_hook, (void));
+
+/* Things to be run in the parent fork.  */
+DEFINE_HOOK (_hurd_fork_parent_hook, (void));
+
+
+/* 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.  */
+pid_t
+__fork (void)
+{
+  jmp_buf env;
+  pid_t pid;
+  size_t i;
+  error_t err;
+  thread_t thread_self = __mach_thread_self ();
+  struct hurd_sigstate *volatile ss;
+  sigset_t pending;
+
+  void unlockss (void)
+    {
+      __spin_lock (&ss->lock);
+      ss->critical_section = 0;
+      pending = ss->pending & ~ss->blocked;
+      __spin_unlock (&ss->lock);
+      /* XXX Copying mutex into child and calling mutex_unlock lossy.  */
+      __mutex_unlock (&_hurd_siglock);
+      ss = NULL;		/* Make sure we crash if we use it again.  */
+    }
+
+  ss = _hurd_self_sigstate ();
+  __spin_lock (&ss->lock);
+  ss->critical_section = 1;
+  __spin_unlock (&ss->lock);
+  __mutex_lock (&_hurd_siglock);
+
+  if (! setjmp (env))
+    {
+      process_t newproc;
+      task_t newtask;
+      thread_t thread, sigthread;
+      mach_port_urefs_t thread_refs, sigthread_refs;
+      struct machine_thread_state state;
+      mach_msg_type_number_t statecount;
+      mach_port_t *portnames = NULL;
+      mach_msg_type_number_t nportnames = 0;
+      mach_port_type_t *porttypes = NULL;
+      mach_msg_type_number_t nporttypes = 0;
+      thread_t *threads = NULL;
+      mach_msg_type_number_t nthreads = 0;
+      int ports_locked = 0;
+
+      /* Run things that prepare for forking before we create the task.  */
+      RUN_HOOK (_hurd_fork_prepare_hook, ());
+
+      /* Lock things that want to be locked before we fork.  */
+      for (i = 0; i < _hurd_fork_locks.n; ++i)
+	__mutex_lock (_hurd_fork_locks.locks[i]);
+      
+      newtask = MACH_PORT_NULL;
+      thread = sigthread = MACH_PORT_NULL;
+      newproc = MACH_PORT_NULL;
+
+      /* Lock all the port cells for the standard ports while we copy the
+	 address space.  We want to insert all the send rights into the
+	 child with the same names.  */
+      for (i = 0; i < _hurd_nports; ++i)
+	__spin_lock (&_hurd_ports[i].lock);
+      ports_locked = 1;
+
+      /* Create the child task.  It will inherit a copy of our memory.  */
+      if (err = __task_create (__mach_task_self (), 1, &newtask))
+	goto lose;
+
+      /* Fetch the names of all ports used in this task.  */
+      if (err = __mach_port_names (__mach_task_self (),
+				   &portnames, &nportnames,
+				   &porttypes, &nporttypes))
+	goto lose;
+      if (nportnames != nporttypes)
+	{
+	  err = EGRATUITOUS;
+	  goto lose;
+	}
+
+      /* Get send rights for all the threads in this task.
+	 We want to avoid giving these rights to the child.  */
+      if (err = __task_threads (__mach_task_self (), &threads, &nthreads))
+	goto lose;
+
+      /* Get the child process's proc server port.  We will insert it into
+	 the child with the same name as we use for our own proc server
+	 port; and we will need it to set the child's message port.  */
+      if (err = __proc_task2proc (_hurd_ports[INIT_PORT_PROC].port,
+				  newtask, &newproc))
+	goto lose;
+
+      /* Insert all our port rights into the child task.  */
+      thread_refs = sigthread_refs = 0;
+      for (i = 0; i < nportnames; ++i)
+	{
+	  if (porttypes[i] & MACH_PORT_TYPE_RECEIVE)
+	    {
+	      /* This is a receive right.  We want to give the child task
+		 its own new receive right under the same name.  */
+	      err = __mach_port_allocate_name (newtask,
+					       MACH_PORT_RIGHT_RECEIVE,
+					       portnames[i]);
+	      if (err == KERN_NAME_EXISTS)
+		{
+		  /* It already has a right under this name (?!).  Well,
+		     there is this bizarre old Mach IPC feature (in #ifdef
+		     MACH_IPC_COMPAT in the ukernel) which results in new
+		     tasks getting a new receive right for task special
+		     port number 2.  What else might be going on I'm not
+		     sure.  So let's check.  */
+#if !MACH_IPC_COMPAT
+#define TASK_NOTIFY_PORT 2
+#endif
+		  assert (({ mach_port_t thisport, notify_port;
+			     mach_msg_type_name_t poly;
+			     (__task_get_special_port (newtask,
+						       TASK_NOTIFY_PORT,
+						       &notify_port) == 0 &&
+			      __mach_port_extract_right 
+			      (newtask,
+			       portnames[i],
+			       MACH_MSG_TYPE_MAKE_SEND,
+			       &thisport, &poly) == 0 &&
+			      (thisport == notify_port) &&
+			      __mach_port_deallocate (__mach_task_self (),
+						      thisport) == 0 &&
+			      __mach_port_deallocate (__mach_task_self (),
+						      notify_port) == 0);
+			   }));
+		}
+	      else if (err)
+		goto lose;
+	      if (porttypes[i] & MACH_PORT_TYPE_SEND)
+		{
+		  /* Give the child as many send rights for its receive
+		     right as we have for ours.  */
+		  mach_port_urefs_t refs;
+		  mach_port_t port;
+		  mach_msg_type_name_t poly;
+		  if (err = __mach_port_get_refs (__mach_task_self (),
+						  portnames[i],
+						  MACH_PORT_RIGHT_SEND,
+						  &refs))
+		    goto lose;
+		  if (err = __mach_port_extract_right (newtask,
+						       portnames[i],
+						       MACH_MSG_TYPE_MAKE_SEND,
+						       &port, &poly))
+		    goto lose;
+		  if (portnames[i] == _hurd_msgport)
+		    {
+		      /* We just created a receive right for the child's
+			 message port and are about to insert send rights
+			 for it.  Now, while we happen to have a send right
+			 for it, give it to the proc server.  */
+		      mach_port_t old;
+		      if (err = __proc_setmsgport (newproc, port, &old))
+			goto lose;
+		      if (old != MACH_PORT_NULL)
+			/* XXX what to do here? */
+			__mach_port_deallocate (__mach_task_self (), old);
+		    }
+		  if (err = __mach_port_insert_right (newtask,
+						      portnames[i],
+						      port,
+						      MACH_MSG_TYPE_MOVE_SEND))
+		    goto lose;
+		  if (refs > 1 &&
+		      (err = __mach_port_mod_refs (newtask,
+						   portnames[i],
+						   MACH_PORT_RIGHT_SEND,
+						   refs - 1)))
+		    goto lose;
+		}
+	      if (porttypes[i] & MACH_PORT_TYPE_SEND_ONCE)
+		{
+		  /* Give the child a send-once right for its receive right,
+		     since we have one for ours.  */
+		  mach_port_t port;
+		  mach_msg_type_name_t poly;
+		  if (err = __mach_port_extract_right
+		      (newtask,
+		       portnames[i],
+		       MACH_MSG_TYPE_MAKE_SEND_ONCE,
+		       &port, &poly))
+		    goto lose;
+		  if (err = __mach_port_insert_right
+		      (newtask,
+		       portnames[i], port,
+		       MACH_MSG_TYPE_MOVE_SEND_ONCE))
+		    goto lose;
+		}
+	    }
+	  else if (porttypes[i] & MACH_PORT_TYPE_SEND)
+	    {
+	      /* This is a send right or a dead name.
+		 Give the child as many references for it as we have.  */
+	      mach_port_urefs_t refs, *record_refs = NULL;
+	      mach_port_t insert;
+	      if (portnames[i] == newtask)
+		/* Skip the name we use for the child's task port.  */
+		continue;
+	      if (portnames[i] == __mach_task_self ())
+		/* For the name we use for our own task port,
+		   insert the child's task port instead.  */
+		insert = newtask;
+	      else if (portnames[i] == _hurd_ports[INIT_PORT_PROC].port)
+		{
+		  /* Get the proc server port for the new task.  */
+		  if (err = __proc_task2proc (portnames[i], newtask, &insert))
+		    goto lose;
+		}
+	      else if (portnames[i] == thread_self)
+		{
+		  /* For the name we use for our own thread port, we will
+		     insert the thread port for the child main user thread
+		     after we create it.  */
+		  insert = MACH_PORT_NULL;
+		  record_refs = &thread_refs;
+		  /* Allocate a dead name right for this name as a
+                     placeholder, so the kernel will not chose this name
+                     for any other new port (it might use it for one of the
+                     rights created when a thread is created).  */
+		  if (err = __mach_port_allocate_name
+		      (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
+		    goto lose;
+		}
+	      else if (portnames[i] == _hurd_msgport_thread)
+		/* For the name we use for our signal thread's thread port,
+		   we will insert the thread port for the child's signal
+		   thread after we create it.  */
+		{
+		  insert = MACH_PORT_NULL;
+		  record_refs = &sigthread_refs;
+		  /* Allocate a dead name right as a placeholder.  */
+		  if (err = __mach_port_allocate_name
+		      (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
+		    goto lose;
+		}
+	      else
+		{
+		  /* Skip the name we use for any of our own thread ports.  */
+		  mach_msg_type_number_t j;
+		  for (j = 0; j < nthreads; ++j)
+		    if (portnames[i] == threads[j])
+		      break;
+		  if (j < nthreads)
+		    continue;
+
+		  insert = portnames[i];
+		}
+	      /* Find out how many user references we have for
+		 the send right with this name.  */
+	      if (err = __mach_port_get_refs (__mach_task_self (),
+					      portnames[i],
+					      MACH_PORT_RIGHT_SEND,
+					      record_refs ?: &refs))
+		goto lose;
+	      if (insert == MACH_PORT_NULL)
+		continue;
+	      /* Insert the chosen send right into the child.  */
+	      err = __mach_port_insert_right (newtask,
+					      portnames[i],
+					      insert,
+					      MACH_MSG_TYPE_COPY_SEND);
+	      if (err == KERN_NAME_EXISTS)
+		{
+		  /* It already has a send right under this name (?!).
+		     Well, it starts out with a send right for its task
+		     port, and inherits the bootstrap and exception ports
+		     from us.  */
+		  mach_port_t childport;
+		  mach_msg_type_name_t poly;
+		  assert (__mach_port_extract_right (newtask, portnames[i],
+						     MACH_MSG_TYPE_COPY_SEND,
+						     &childport, &poly) == 0 &&
+			  childport == insert &&
+			  __mach_port_deallocate (__mach_task_self (),
+						  childport) == 0);
+		}
+	      else if (err)
+		goto lose;
+	      /* Give the child as many user references as we have.  */
+	      if (refs > 1 &&
+		  (err = __mach_port_mod_refs (newtask,
+					       portnames[i],
+					       MACH_PORT_RIGHT_SEND,
+					       refs - 1)))
+		goto lose;
+	    }
+	}
+
+      /* Unlock the standard port cells.  The child must unlock its own
+	 copies too.  */
+      for (i = 0; i < _hurd_nports; ++i)
+	__spin_unlock (&_hurd_ports[i].lock);
+      ports_locked = 0;
+
+      /* Unlock the signal state.  The child must unlock its own copy too.  */
+      unlockss ();
+
+      /* Create the child main user thread and signal thread.  */
+      if ((err = __thread_create (newtask, &thread)) ||
+	  (err = __thread_create (newtask, &sigthread)))
+	goto lose;
+
+      /* Insert send rights for those threads.  We previously allocated
+         dead name rights with the names we want to give the thread ports
+         in the child as placeholders.  Now deallocate them so we can use
+         the names.  */
+      if ((err = __mach_port_deallocate (newtask, thread_self)) ||
+	  (err = __mach_port_insert_right (newtask, thread_self,
+					   thread, MACH_MSG_TYPE_COPY_SEND)))
+	goto lose;
+      /* We have one extra user reference created at the beginning of this
+	 function, accounted for by mach_port_names (and which will thus be
+	 accounted for in the child below).  This extra right gets consumed
+	 in the child by the store into _hurd_sigthread in the child fork.  */
+      if (thread_refs > 1 &&
+	  (err = __mach_port_mod_refs (newtask, thread_self,
+				       MACH_PORT_RIGHT_SEND,
+				       thread_refs - 1)))
+	goto lose;
+      if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none.  */
+	  && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread)) ||
+	      (err = __mach_port_insert_right (newtask, _hurd_msgport_thread,
+					       sigthread,
+					       MACH_MSG_TYPE_COPY_SEND))))
+	goto lose;
+      if (sigthread_refs > 1 &&
+	  (err = __mach_port_mod_refs (newtask, _hurd_msgport_thread,
+				       MACH_PORT_RIGHT_SEND,
+				       sigthread_refs - 1)))
+	goto lose;
+
+      /* This seems like a convenient juncture to copy the proc server's
+	 idea of what addresses our argv and envp are found at from the
+	 parent into the child.  Since we happen to know that the child
+	 shares our memory image, it is we who should do this copying.  */
+      {
+	vm_address_t argv, envp;
+	err = (__USEPORT (PROC, __proc_get_arg_locations (port, &argv, &envp))
+	       ?: __proc_set_arg_locations (newproc, argv, envp));
+	if (err)
+	  goto lose;
+      }
+	    
+      /* Set the child signal thread up to run the msgport server function
+	 using the same signal thread stack copied from our address space.
+	 We fetch the state before longjmp'ing it so that miscellaneous
+	 registers not affected by longjmp (such as i386 segment registers)
+	 are in their normal default state.  */
+      statecount = MACHINE_THREAD_STATE_COUNT;
+      if (err = __thread_get_state (_hurd_msgport_thread,
+				    MACHINE_THREAD_STATE_FLAVOR,
+				    (natural_t *) &state, &statecount))
+	goto lose;
+#if STACK_GROWTH_UP
+      state.SP = __hurd_sigthread_stack_base;
+#else
+      state.SP = __hurd_sigthread_stack_end;
+#endif      
+      MACHINE_THREAD_STATE_SET_PC (&state,
+				   (unsigned long int) _hurd_msgport_receive);
+      if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
+				    (natural_t *) &state, statecount))
+	goto lose;
+      /* We do not thread_resume SIGTHREAD here because the child
+	 fork needs to do more setup before it can take signals.  */
+
+      /* Set the child user thread up to return 1 from the setjmp above.  */
+      _hurd_longjmp_thread_state (&state, env, 1);
+      if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
+				    (natural_t *) &state, statecount))
+	goto lose;
+
+      /* Get the PID of the child from the proc server.  We must do this
+	 before calling proc_child below, because at that point any
+	 authorized POSIX.1 process may kill the child task with SIGKILL.  */
+      if (err = __USEPORT (PROC, __proc_task2pid (port, newtask, &pid)))
+	goto lose;
+
+      /* Register the child with the proc server.  It is important that
+	 this be that last thing we do before starting the child thread
+	 running.  Once proc_child has been done for the task, it appears
+	 as a POSIX.1 process.  Any errors we get must be detected before
+	 this point, and the child must have a message port so it responds
+	 to POSIX.1 signals.  */
+      if (err = __USEPORT (PROC, __proc_child (port, newtask)))
+	goto lose;
+
+      /* This must be the absolutely last thing we do; we can't assume that
+	 the child will remain alive for even a moment once we do this.  We
+	 ignore errors because we have committed to the fork and are not
+	 allowed to return them after the process becomes visible to
+	 POSIX.1 (which happened right above when we called proc_child).  */
+      (void) __thread_resume (thread);
+
+    lose:
+      if (ports_locked)
+	for (i = 0; i < _hurd_nports; ++i)
+	  __spin_unlock (&_hurd_ports[i].lock);
+
+      if (newtask != MACH_PORT_NULL)
+	{
+	  if (err)
+	    __task_terminate (newtask);
+	  __mach_port_deallocate (__mach_task_self (), newtask);
+	}
+      if (thread != MACH_PORT_NULL)
+	__mach_port_deallocate (__mach_task_self (), thread);
+      if (sigthread != MACH_PORT_NULL)
+	__mach_port_deallocate (__mach_task_self (), sigthread);
+      if (newproc != MACH_PORT_NULL)
+	__mach_port_deallocate (__mach_task_self (), newproc);
+      if (thread_self != MACH_PORT_NULL)
+	__mach_port_deallocate (__mach_task_self (), thread_self);
+
+      if (portnames)
+	__vm_deallocate (__mach_task_self (),
+			 (vm_address_t) portnames,
+			 nportnames * sizeof (*portnames));
+      if (porttypes)
+	__vm_deallocate (__mach_task_self (),
+			 (vm_address_t) porttypes,
+			 nporttypes * sizeof (*porttypes));
+      if (threads)
+	{
+	  for (i = 0; i < nthreads; ++i)
+	    __mach_port_deallocate (__mach_task_self (), threads[i]);
+	  __vm_deallocate (__mach_task_self (),
+			   (vm_address_t) threads,
+			   nthreads * sizeof (*threads));
+	}
+
+      /* Run things that want to run in the parent to restore it to
+	 normality.  Usually prepare hooks and parent hooks are
+	 symmetrical: the prepare hook arrests state in some way for the
+	 fork, and the parent hook restores the state for the parent to
+	 continue executing normally.  */
+      RUN_HOOK (_hurd_fork_parent_hook, ());
+    }
+  else
+    {
+      struct hurd_sigstate *oldstates;
+
+      /* We are the child task.  Unlock the standard port cells, which were
+         locked in the parent when we copied its memory.  The parent has
+         inserted send rights with the names that were in the cells then.  */
+      for (i = 0; i < _hurd_nports; ++i)
+	__spin_unlock (&_hurd_ports[i].lock);
+
+      /* We are the only thread in this new task, so we will
+	 take the task-global signals.  */
+      _hurd_sigthread = thread_self;
+
+      /* Unchain the sigstate structures for threads that existed in the
+	 parent task but don't exist in this task (the child process).
+	 Delay freeing them until later because some of the further setup
+	 and unlocking might be required for free to work.  */
+      oldstates = _hurd_sigstates;
+      if (oldstates == ss)
+	oldstates = ss->next;
+      else
+	{
+	  while (_hurd_sigstates->next != ss)
+	    _hurd_sigstates = _hurd_sigstates->next;
+	  _hurd_sigstates->next = ss->next;
+	}
+      ss->next = NULL;
+      _hurd_sigstates = ss;
+
+      /* Unlock our copies of the signal state locks.  */
+      unlockss ();
+
+      /* Fetch our new process IDs from the proc server.  No need to
+	 refetch our pgrp; it is always inherited from the parent (so
+	 _hurd_pgrp is already correct), and the proc server will send us a
+	 proc_newids notification when it changes.  */
+      err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
+					     &_hurd_orphaned));
+
+      /* Run things that want to run in the child task to set up.  */
+      RUN_HOOK (_hurd_fork_child_hook, ());
+
+      /* Set up proc server-assisted fault recovery for the signal thread.  */
+      _hurdsig_fault_init ();
+
+      /* Start the signal thread listening on the message port.  */
+      if (!err)
+	err = __thread_resume (_hurd_msgport_thread);
+
+      /* Free the old sigstate structures.  */
+      while (oldstates != NULL)
+	{
+	  struct hurd_sigstate *next = oldstates->next;
+	  free (oldstates);
+	  oldstates = next;
+	}
+      /* XXX what to do if we have any errors here? */
+
+      pid = 0;
+    }
+
+  /* Unlock things we locked before creating the child task.
+     They are locked in both the parent and child tasks.  */
+  for (i = 0; i < _hurd_fork_locks.n; ++i)
+    __mutex_unlock (_hurd_fork_locks.locks[i]);
+
+  if (pending)
+    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+
+  return err ? __hurd_fail (err) : pid;
+}
+
+weak_alias (__fork, fork)
diff --git a/sysdeps/mach/hurd/fstat.c b/sysdeps/mach/hurd/fstat.c
new file mode 100644
index 0000000000..5341e3e4a4
--- /dev/null
+++ b/sysdeps/mach/hurd/fstat.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Get information about the file descriptor FD in BUF.  */
+int
+DEFUN(__fstat, (fd, buf), int fd AND struct stat *buf)
+{
+  error_t err;
+
+  if (err = HURD_DPORT_USE (fd, __io_stat (port, buf)))
+    return __hurd_dfail (fd, err);
+
+  return 0;
+}
+
+weak_alias (__fstat, fstat)
diff --git a/sysdeps/mach/hurd/fsync.c b/sysdeps/mach/hurd/fsync.c
new file mode 100644
index 0000000000..adfe9800d3
--- /dev/null
+++ b/sysdeps/mach/hurd/fsync.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Make all changes done to FD actually appear on disk.  */
+int
+DEFUN(fsync, (fd), int fd)
+{
+  error_t err = HURD_DPORT_USE (fd, __file_sync (port, 1));
+  if (err)
+    return __hurd_dfail (fd, err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/ftruncate.c b/sysdeps/mach/hurd/ftruncate.c
new file mode 100644
index 0000000000..23a5e796cc
--- /dev/null
+++ b/sysdeps/mach/hurd/ftruncate.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Truncate the file FD refers to to LENGTH bytes.  */
+int
+DEFUN(ftruncate, (fd, length),
+      int fd AND off_t length)
+{
+  error_t err;
+  if (err = HURD_DPORT_USE (fd, __file_truncate (port, length)))
+    return __hurd_dfail (fd, err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/getcwd.c b/sysdeps/mach/hurd/getcwd.c
new file mode 100644
index 0000000000..c0d9bcd567
--- /dev/null
+++ b/sysdeps/mach/hurd/getcwd.c
@@ -0,0 +1,250 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+
+/* 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.  */
+
+char *
+getcwd (char *buf, size_t size)
+{
+  error_t err;
+  dev_t rootdev, thisdev;
+  ino_t rootino, thisino;
+  char *file_name;
+  register char *file_namep;
+  struct stat st;
+  file_t parent;
+  char *dirbuf = NULL;
+  unsigned int dirbufsize = 0;
+  file_t crdir;
+  struct hurd_userlink crdir_ulink;
+
+  inline void cleanup (void)
+    {
+      _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir);
+      __mach_port_deallocate (__mach_task_self (), parent);
+
+      if (dirbuf != NULL)
+	__vm_deallocate (__mach_task_self (),
+			 (vm_address_t) dirbuf, dirbufsize);
+    }
+
+      
+  if (size == 0)
+    {
+      if (buf != NULL)
+	{
+	  errno = EINVAL;
+	  return NULL;
+	}
+
+      size = FILENAME_MAX * 4 + 1;	/* Good starting guess.  */
+    }
+
+  if (buf != NULL)
+    file_name = buf;
+  else
+    {
+      file_name = malloc (size);
+      if (file_name == NULL)
+	return NULL;
+    }
+
+  file_namep = file_name + size;
+  *--file_namep = '\0';
+
+  /* Get a port to our root directory and stat it.  */
+
+  crdir = _hurd_port_get (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink);
+  if (err = __io_stat (crdir, &st))
+    {
+      _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir);
+      return __hurd_fail (err), NULL;
+    }
+  rootdev = st.st_dev;
+  rootino = st.st_ino;
+
+  /* Get a port to our current working directory and stat it.  */
+
+  if (err = __USEPORT (CWDIR, __mach_port_mod_refs (__mach_task_self (),
+						    (parent = port),
+						    MACH_PORT_RIGHT_SEND,
+						    1)))
+    {
+      _hurd_port_free (&_hurd_ports[INIT_PORT_CRDIR], &crdir_ulink, crdir);
+      return __hurd_fail (err), NULL;
+    }
+  if (err = __io_stat (parent, &st))
+    {
+      cleanup ();
+      return __hurd_fail (err), NULL;
+    }
+
+  thisdev = st.st_dev;
+  thisino = st.st_ino;
+
+  while (!(thisdev == rootdev && thisino == rootino))
+    {
+      /* PARENT is a port to the directory we are currently on;
+	 THISDEV and THISINO are its device and node numbers.
+	 Look in its parent (..) for a file with the same numbers.  */
+
+      struct dirent *d;
+      dev_t dotdev;
+      ino_t dotino;
+      int mount_point;
+      file_t newp;
+      char *dirdata;
+      unsigned int dirdatasize;
+      int direntry, nentries;
+
+      /* Look at the parent directory.  */
+      if (err = __hurd_file_name_lookup (crdir, parent, "..", O_READ, 0, &newp))
+	goto lose;
+      __mach_port_deallocate (__mach_task_self (), parent);
+      parent = newp;
+
+      /* Figure out if this directory is a mount point.  */
+      if (err = __io_stat (parent, &st))
+	goto lose;
+      dotdev = st.st_dev;
+      dotino = st.st_ino;
+      mount_point = dotdev != thisdev;
+
+      /* Search for the last directory.  */
+      direntry = 0;
+      dirdata = dirbuf;
+      dirdatasize = dirbufsize;
+      while (!(err = __dir_readdir (parent, &dirdata, &dirdatasize,
+				    direntry, -1, 0, &nentries)) &&
+	     nentries != 0)	     
+	{
+	  /* We have a block of directory entries.  */
+
+	  unsigned int offset;
+
+	  direntry += nentries;
+
+	  if (dirdata != dirbuf)
+	    {
+	      /* The data was passed out of line, so our old buffer is no
+		 longer useful.  Deallocate the old buffer and reset our
+		 information for the new buffer.  */
+	      __vm_deallocate (__mach_task_self (),
+			       (vm_address_t) dirbuf, dirbufsize);
+	      dirbuf = dirdata;
+	      dirbufsize = round_page (dirdatasize);
+	    }
+
+	  /* Iterate over the returned directory entries, looking for one
+	     whose file number is THISINO.  */
+
+	  offset = 0;
+	  while (offset < dirdatasize)
+	    {
+	      d = (struct dirent *) &dirdata[offset];
+	      offset += d->d_reclen;
+
+	      /* Ignore `.' and `..'.  */	
+	      if (d->d_name[0] == '.' &&
+		  (d->d_namlen == 1 ||
+		   (d->d_namlen == 2 && d->d_name[1] == '.')))
+		continue;
+
+	      if (mount_point || d->d_ino == thisino)
+		{
+		  file_t try;
+		  if (err = __hurd_file_name_lookup (crdir, parent, d->d_name,
+						     O_NOLINK, 0, &try))
+		    goto lose;
+		  err = __io_stat (try, &st);
+		  __mach_port_deallocate (__mach_task_self (), try);
+		  if (err)
+		    goto lose;
+		  if (st.st_dev == thisdev && st.st_ino == thisino)
+		    break;
+		}
+	    }
+	}
+
+      if (err)
+	goto lose;
+      else
+	{
+	  /* Prepend the directory name just discovered.  */
+
+	  if (file_namep - file_name < d->d_namlen + 1)
+	    {
+	      if (buf != NULL)
+		{
+		  errno = ERANGE;
+		  return NULL;
+		}
+	      else
+		{
+		  size *= 2;
+		  buf = realloc (file_name, size);
+		  if (buf == NULL)
+		    {
+		      free (file_name);
+		      return NULL;
+		    }
+		  file_namep = &buf[file_namep - file_name];
+		  file_name = buf;
+		}
+	    }
+	  file_namep -= d->d_namlen;
+	  (void) memcpy (file_namep, d->d_name, d->d_namlen);
+	  *--file_namep = '/';
+	}
+
+      /* The next iteration will find the name of the directory we
+	 just searched through.  */
+      thisdev = dotdev;
+      thisino = dotino;
+    }
+
+  if (file_namep == &file_name[size - 1])
+    /* We found nothing and got all the way to the root.
+       So the root is our current directory.  */
+    *--file_namep = '/';
+
+  memmove (file_name, file_namep, file_name + size - file_namep);
+  cleanup ();
+  return file_name;
+
+ lose:
+  cleanup ();
+  return NULL;
+}
diff --git a/sysdeps/mach/hurd/getdents.c b/sysdeps/mach/hurd/getdents.c
new file mode 100644
index 0000000000..4de2eb351d
--- /dev/null
+++ b/sysdeps/mach/hurd/getdents.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Ince	
+
+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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stddef.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <string.h>
+
+ssize_t
+DEFUN(__getdirentries, (fd, buf, nbytes, basep),
+      int fd AND PTR buf AND size_t nbytes AND off_t *basep)
+{
+  error_t err;
+  int entriesread;
+  char *data = buf;
+  mach_msg_type_number_t bytesread = nbytes;
+
+  /* Fault before taking any locks.  */
+  *(volatile off_t *) basep = *basep;
+
+  err = HURD_DPORT_USE (fd, __dir_readdir (port, &data, &bytesread,
+					   *basep, -1, nbytes, &entriesread));
+  if (err)
+    return __hurd_dfail (fd, err);
+
+  if (data != buf)
+    {
+      size_t copy = bytesread;
+      if (copy > nbytes)
+	/* The server has a violated the dir_readdir protocol.  */
+	copy = nbytes;
+      memcpy (buf, data, copy);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) data, bytesread);
+      bytesread = copy;
+    }
+
+  *basep += entriesread;
+
+  return bytesread;
+}
+
+weak_alias (__getdirentries, getdirentries)
+
diff --git a/sysdeps/mach/hurd/getdtsz.c b/sysdeps/mach/hurd/getdtsz.c
new file mode 100644
index 0000000000..e506963ac3
--- /dev/null
+++ b/sysdeps/mach/hurd/getdtsz.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Return the maximum number of file descriptors the current process
+   could possibly have (until it raises the resource limit).  */
+int
+DEFUN_VOID(__getdtablesize)
+{
+  int size;
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_dtable_lock);
+  size = _hurd_dtablesize;
+  __mutex_unlock (&_hurd_dtable_lock);
+  HURD_CRITICAL_END;
+  return size;
+}
+
+weak_alias (__getdtablesize, getdtablesize)
diff --git a/sysdeps/mach/hurd/getegid.c b/sysdeps/mach/hurd/getegid.c
new file mode 100644
index 0000000000..88f6ea00e2
--- /dev/null
+++ b/sysdeps/mach/hurd/getegid.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the effective group ID of the calling process.  */
+gid_t
+DEFUN_VOID(__getegid)
+{
+  error_t err;
+  gid_t egid;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+
+  if (err = _hurd_check_ids ())
+    {
+      errno = err;
+      egid = -1;
+    }
+  else if (_hurd_id.gen.ngids >= 1)
+    egid = _hurd_id.gen.gids[0];
+  else if (_hurd_id.aux.ngids >= 1)
+    /* We have no effective gids.  Return the real gid.  */
+    egid = _hurd_id.aux.gids[0];
+  else
+    {
+      /* We do not even have a real gid.  */
+      errno = EGRATUITOUS;
+      egid = -1;
+    }
+
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  return egid;
+}
+
+weak_alias (__getegid, getegid)
diff --git a/sysdeps/mach/hurd/geteuid.c b/sysdeps/mach/hurd/geteuid.c
new file mode 100644
index 0000000000..416cd31f82
--- /dev/null
+++ b/sysdeps/mach/hurd/geteuid.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the effective user ID of the calling process.  */
+uid_t
+DEFUN_VOID(__geteuid)
+{
+  error_t err;
+  uid_t euid;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+
+  if (err = _hurd_check_ids ())
+    {
+      errno = err;
+      euid = -1;
+    }
+  else if (_hurd_id.gen.nuids >= 1)
+    euid = _hurd_id.gen.uids[0];
+  else if (_hurd_id.aux.nuids >= 1)
+    /* We have no effective uids.  Return the real uid.  */
+    euid = _hurd_id.aux.uids[0];
+  else
+    {
+      /* We do not even have a real uid.  */
+      errno = EGRATUITOUS;
+      euid = -1;
+    }
+
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  return euid;
+}
+
+weak_alias (__geteuid, geteuid)
diff --git a/sysdeps/mach/hurd/getgid.c b/sysdeps/mach/hurd/getgid.c
new file mode 100644
index 0000000000..0d1b27f8e6
--- /dev/null
+++ b/sysdeps/mach/hurd/getgid.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the real group ID of the calling process.  */
+gid_t
+DEFUN_VOID(__getgid)
+{
+  error_t err;
+  gid_t gid;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+
+  if (err = _hurd_check_ids ())
+    {
+      errno = err;
+      gid = -1;
+    }
+  else if (_hurd_id.aux.ngids >= 1)
+    gid = _hurd_id.aux.gids[0];
+  else
+    {
+      /* We do not even have a real gid.  */
+      errno = EGRATUITOUS;
+      gid = -1;
+    }
+
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  return gid;
+}
+
+weak_alias (__getgid, getgid)
diff --git a/sysdeps/mach/hurd/getgroups.c b/sysdeps/mach/hurd/getgroups.c
new file mode 100644
index 0000000000..d985d29317
--- /dev/null
+++ b/sysdeps/mach/hurd/getgroups.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+int
+__getgroups (int n, gid_t *gidset)
+{
+  error_t err;
+  int ngids;
+  void *crit;
+
+  crit = _hurd_critical_section_lock ();
+  __mutex_lock (&_hurd_id.lock);
+
+  if (err = _hurd_check_ids ())
+    {
+      __mutex_unlock (&_hurd_id.lock);
+      _hurd_critical_section_unlock (crit);
+      return __hurd_fail (err);
+    }
+
+  ngids = _hurd_id.gen.ngids;
+
+  if (n != 0)
+    {
+      /* Copy the gids onto stack storage and then release the idlock.  */
+      gid_t gids[ngids];
+      memcpy (gids, _hurd_id.gen.gids, sizeof (gids));
+      __mutex_unlock (&_hurd_id.lock);
+      _hurd_critical_section_unlock (crit);
+
+      /* Now that the lock is released, we can safely copy the
+	 group set into the user's array, which might fault.  */
+      if (ngids > n)
+	ngids = n;
+      memcpy (gidset, gids, ngids * sizeof (gid_t));
+    }
+  else
+    {
+      __mutex_unlock (&_hurd_id.lock);
+      _hurd_critical_section_unlock (crit);
+    }
+
+  return ngids;
+}
+
+weak_alias (__getgroups, getgroups)
diff --git a/sysdeps/mach/hurd/gethostid.c b/sysdeps/mach/hurd/gethostid.c
new file mode 100644
index 0000000000..5a3309266e
--- /dev/null
+++ b/sysdeps/mach/hurd/gethostid.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Return the current machine's Internet number.  */
+long int
+DEFUN_VOID(gethostid)
+{
+  int hostid;
+  error_t err;
+  if (err = __USEPORT (PROC, __proc_gethostid (port, &hostid)))
+    return __hurd_fail (err);
+  return hostid;
+}
diff --git a/sysdeps/mach/hurd/gethostname.c b/sysdeps/mach/hurd/gethostname.c
new file mode 100644
index 0000000000..94a0537d91
--- /dev/null
+++ b/sysdeps/mach/hurd/gethostname.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <string.h>
+
+/* 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.  */
+int
+DEFUN(__gethostname, (name, len),
+      char *name AND size_t len)
+{
+  error_t err;
+  char *buf = name;
+  mach_msg_type_number_t buflen = len;
+  if (err = __USEPORT (PROC, __proc_gethostname (port, &buf, &buflen)))
+    return __hurd_fail (err);
+  if (buf != name)
+    {
+      memcpy (name, buf, len < buflen ? len : buflen);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+    }
+  if (buflen > len)
+    return __hurd_fail (ENAMETOOLONG);
+  return 0;
+}
+
+weak_alias (__gethostname, gethostname)
diff --git a/sysdeps/mach/hurd/getitimer.c b/sysdeps/mach/hurd/getitimer.c
new file mode 100644
index 0000000000..15c46cae68
--- /dev/null
+++ b/sysdeps/mach/hurd/getitimer.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stddef.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+
+/* XXX Temporary cheezoid implementation; see __setitmr.c.  */
+
+/* These are defined in __setitmr.c.  */
+extern spin_lock_t _hurd_itimer_lock;
+extern struct itimerval _hurd_itimerval;
+extern struct timeval _hurd_itimer_started;
+
+static inline void
+subtract_timeval (struct timeval *from, const struct timeval *subtract)
+{
+  from->tv_usec -= subtract->tv_usec;
+  from->tv_sec -= subtract->tv_sec;
+  while (from->tv_usec < 0)
+    {
+      --from->tv_sec;
+      from->tv_usec += 1000000;
+    }
+}
+
+/* Set *VALUE to the current setting of timer WHICH.
+   Return 0 on success, -1 on errors.  */
+int
+DEFUN(__getitimer, (which, value),
+      enum __itimer_which which AND struct itimerval *value)
+{
+  struct itimerval val;
+  struct timeval elapsed;
+
+  switch (which)
+    {
+    default:
+      return __hurd_fail (EINVAL);
+
+    case ITIMER_VIRTUAL:
+    case ITIMER_PROF:
+      return __hurd_fail (ENOSYS);
+
+    case ITIMER_REAL:
+      break;
+    }
+
+  /* Get the time now.  */
+  if (__gettimeofday (&elapsed, NULL) < 0)
+    return -1;
+
+  /* Extract the current timer setting; and the time it was set, so we can
+     calculate the time elapsed so far.  */
+  HURD_CRITICAL_BEGIN;
+  __spin_lock (&_hurd_itimer_lock);
+  val = _hurd_itimerval;
+  subtract_timeval (&elapsed, &_hurd_itimer_started);
+  __spin_unlock (&_hurd_itimer_lock);
+  HURD_CRITICAL_END;
+
+  if ((val.it_value.tv_sec | val.it_value.tv_usec) != 0)
+    {
+      /* There is a pending alarm set.  VAL indicates the interval it was
+	 set for, relative to the time recorded in _hurd_itimer_started.
+	 Now compensate for the time elapsed since to get the user's
+	 conception of the current value of the timer (as if the value
+	 stored decreased every microsecond).  */
+      if (timercmp (&val.it_value, &elapsed, <))
+	{
+	  /* Hmm.  The timer should have just gone off, but has not been
+	     reset.  This is a possible timing glitch.  The alarm will signal
+	     soon, so fabricate a value for how soon.  */
+	  val.it_value.tv_sec = 0;
+	  val.it_value.tv_usec = 10; /* Random.  */
+	}
+      else
+	/* Subtract the time elapsed since the timer was set
+	   from the current timer value the user sees.  */
+	subtract_timeval (&val.it_value, &elapsed);
+    }
+
+  *value = val;
+  return 0;
+}
+
+weak_alias (__getitimer, getitimer)
diff --git a/sysdeps/mach/hurd/getlogin.c b/sysdeps/mach/hurd/getlogin.c
new file mode 100644
index 0000000000..523db3f2d7
--- /dev/null
+++ b/sysdeps/mach/hurd/getlogin.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stddef.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Return the login name of the user, or NULL if it can't be determined.
+   The returned pointer, if not NULL, is good only until the next call.  */
+char *
+DEFUN_VOID(getlogin)
+{
+  static char login[1024];	/* XXX */
+  error_t err;
+
+  if (err = __USEPORT (PROC, __proc_getlogin (port, login)))
+    {
+      errno = err;
+      return NULL;
+    }
+
+  return login;
+}
diff --git a/sysdeps/mach/hurd/getpeername.c b/sysdeps/mach/hurd/getpeername.c
new file mode 100644
index 0000000000..a9ea32c2ae
--- /dev/null
+++ b/sysdeps/mach/hurd/getpeername.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <string.h>
+
+/* Put the address of the peer connected to socket FD into *ADDR
+   (which is *LEN bytes long), and its actual length into *LEN.  */
+int
+DEFUN(getpeername, (fd, addr, len),
+      int fd AND struct sockaddr *addr AND size_t *len)
+{
+  error_t err;
+  char *buf = (char *) addr;
+  mach_msg_type_number_t buflen = *len;
+  int type;
+  addr_port_t aport;
+
+  if (err = HURD_DPORT_USE (fd, __socket_peername (port, &aport)))
+    return __hurd_dfail (fd, err);
+
+  err = __socket_whatis_address (aport, &type, &buf, &buflen);
+  __mach_port_deallocate (__mach_task_self (), aport);
+
+  if (err)
+    return __hurd_dfail (fd, err);
+
+  if (buf != (char *) addr)
+    {
+      if (*len < buflen)
+	*len = buflen;
+      memcpy (addr, buf, *len);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+    }
+
+  addr->sa_family = type;
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/getpgid.c b/sysdeps/mach/hurd/getpgid.c
new file mode 100644
index 0000000000..b9a3634fed
--- /dev/null
+++ b/sysdeps/mach/hurd/getpgid.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Get the process group ID of process PID.  */
+int
+DEFUN(__getpgid, (pid), pid_t pid)
+{
+  error_t err;
+  pid_t pgrp;
+
+  if (pid == 0)
+    {
+      /* Assume atomic word fetch and store, so don't lock _hurd_pid_lock.  */
+      pgrp = _hurd_pgrp;
+      err = 0;
+    }
+  else
+    err = __USEPORT (PROC, __proc_getpgrp (port, pid, &pgrp));
+
+  return err ? __hurd_fail (err) : pgrp;
+}
+
+weak_alias (__getpgid, getpgid)
diff --git a/sysdeps/mach/hurd/getpid.c b/sysdeps/mach/hurd/getpid.c
new file mode 100644
index 0000000000..bbff6a3ca0
--- /dev/null
+++ b/sysdeps/mach/hurd/getpid.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 1993, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Get the process ID of the calling process.  */
+pid_t
+DEFUN_VOID(__getpid)
+{
+  /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock.  */
+  return _hurd_pid;
+}
+
+weak_alias (__getpid, getpid)
diff --git a/sysdeps/mach/hurd/getppid.c b/sysdeps/mach/hurd/getppid.c
new file mode 100644
index 0000000000..6a5ac1dd1b
--- /dev/null
+++ b/sysdeps/mach/hurd/getppid.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991, 1993, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+
+
+/* Get the parent process ID of the calling process.  */
+pid_t
+DEFUN_VOID(__getppid)
+{
+  /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock.  */
+  return _hurd_ppid;
+}
+
+weak_alias (__getppid, getppid)
diff --git a/sysdeps/mach/hurd/getpriority.c b/sysdeps/mach/hurd/getpriority.c
new file mode 100644
index 0000000000..5b24ce23f8
--- /dev/null
+++ b/sysdeps/mach/hurd/getpriority.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <limits.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+
+/* Return the highest priority of any process specified by WHICH and WHO
+   (see <sys/resource.h>); if WHO is zero, the current process, process group,
+   or user (as specified by WHO) is used.  A lower priority number means higher
+   priority.  Priorities range from PRIO_MIN to PRIO_MAX.  */
+int
+getpriority (enum __priority_which which, int who)
+{
+  error_t err, onerr;
+  int maxpri = INT_MIN;
+  struct procinfo *pip;		/* Just for sizeof.  */
+  int pibuf[sizeof *pip + 2 * sizeof (pip->threadinfos[0])], *pi = pibuf;
+  unsigned int pisize = sizeof pibuf / sizeof pibuf[0];
+
+  error_t getonepriority (pid_t pid, struct procinfo *pip)
+    {
+      if (pip)
+	onerr = 0;
+      else
+	{
+	  int *oldpi = pi;
+	  unsigned int oldpisize = pisize;
+	  onerr = __USEPORT (PROC, __proc_getprocinfo (port,
+						       pid,
+						       &pi, &pisize));
+	  if (pi != oldpi && oldpi != pibuf)
+	    /* Old buffer from last call was not reused; free it.  */
+	    __vm_deallocate (__mach_task_self (),
+			     (vm_address_t) oldpi, oldpisize * sizeof pi[0]);
+	  pip = (struct procinfo *) pi;
+	}
+      if (!onerr && pip->taskinfo.base_priority > maxpri)
+	maxpri = pip->taskinfo.base_priority;
+      return 0;
+    }
+
+  onerr = 0;
+  err = _hurd_priority_which_map (which, who, getonepriority);
+
+  if (pi != pibuf)
+    __vm_deallocate (__mach_task_self (),
+		     (vm_address_t) pi, pisize * sizeof pi[0]);
+
+  if (!err && maxpri == INT_MIN)
+    /* No error, but no pids found.  */
+    err = onerr ?: ESRCH;
+
+  if (err)
+    return __hurd_fail (err);
+
+  return MACH_PRIORITY_TO_NICE (maxpri);
+}
diff --git a/sysdeps/mach/hurd/getrlimit.c b/sysdeps/mach/hurd/getrlimit.c
new file mode 100644
index 0000000000..a05d32277d
--- /dev/null
+++ b/sysdeps/mach/hurd/getrlimit.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <sys/resource.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+
+/* Put the soft and hard limits for RESOURCE in *RLIMITS.
+   Returns 0 if successful, -1 if not (and sets errno).  */
+int
+DEFUN(getrlimit, (resource, rlimits),
+      enum __rlimit_resource resource AND struct rlimit *rlimits)
+{
+  struct rlimit lim;
+
+  if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  __mutex_lock (&_hurd_rlimit_lock);
+  lim = _hurd_rlimits[resource];
+  __mutex_unlock (&_hurd_rlimit_lock);
+
+  *rlimits = lim;
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/getsockname.c b/sysdeps/mach/hurd/getsockname.c
new file mode 100644
index 0000000000..5a9182b4fc
--- /dev/null
+++ b/sysdeps/mach/hurd/getsockname.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <string.h>
+
+/* Put the local address of FD into *ADDR and its length in *LEN.  */
+int
+DEFUN(getsockname, (fd, addr, len),
+      int fd AND struct sockaddr *addr AND size_t *len)
+{
+  error_t err;
+  char *buf = (char *) addr;
+  mach_msg_type_number_t buflen = *len;
+  int type;
+  addr_port_t aport;
+
+  if (err = HURD_DPORT_USE (fd, __socket_name (port, &aport)))
+    return __hurd_dfail (fd, err);
+
+  err = __socket_whatis_address (aport, &type, &buf, &buflen);
+  __mach_port_deallocate (__mach_task_self (), aport);
+
+  if (err)
+    return __hurd_dfail (fd, err);
+
+  if (buf != (char *) addr)
+    {
+      if (*len < buflen)
+	*len = buflen;
+      memcpy (addr, buf, *len);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+    }
+
+  addr->sa_family = type;
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/getsockopt.c b/sysdeps/mach/hurd/getsockopt.c
new file mode 100644
index 0000000000..a9c91ea0f1
--- /dev/null
+++ b/sysdeps/mach/hurd/getsockopt.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <string.h>
+
+/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL
+   into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's
+   actual length.  Returns 0 on success, -1 for errors.  */
+int
+DEFUN(getsockopt, (fd, level, optname, optval, optlen),
+      int fd AND int level AND int optname AND
+      PTR optval AND size_t *optlen)
+{
+  error_t err;
+  char *buf = optval;
+  mach_msg_type_number_t buflen = *optlen;
+
+  if (err = HURD_DPORT_USE (fd, __socket_getopt (port,
+						 level, optname,
+						 &buf, &buflen)))
+    return __hurd_dfail (fd, err);
+
+  if (buf != optval)
+    {
+      if (*optlen < buflen)
+	*optlen = buflen;
+      memcpy (optval, buf, *optlen);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/getuid.c b/sysdeps/mach/hurd/getuid.c
new file mode 100644
index 0000000000..9381c6e8ec
--- /dev/null
+++ b/sysdeps/mach/hurd/getuid.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Get the real user ID of the calling process.  */
+uid_t
+DEFUN_VOID(__getuid)
+{
+  error_t err;
+  uid_t uid;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+
+  if (err = _hurd_check_ids ())
+    {
+      errno = err;
+      uid = -1;
+    }
+  else if (_hurd_id.aux.nuids >= 1)
+    uid = _hurd_id.aux.uids[0];
+  else
+    {
+      /* We do not even have a real uid.  */
+      errno = EGRATUITOUS;
+      uid = -1;
+    }
+
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  return uid;
+}
+
+weak_alias (__getuid, getuid)
diff --git a/sysdeps/mach/hurd/hppa/sigcontext.h b/sysdeps/mach/hurd/hppa/sigcontext.h
new file mode 100644
index 0000000000..b616469f21
--- /dev/null
+++ b/sysdeps/mach/hurd/hppa/sigcontext.h
@@ -0,0 +1,86 @@
+/* Machine-dependent signal context structure for GNU Hurd.  HPPA version.
+Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* Signal handlers are actually called:
+   void handler (int sig, int code, struct sigcontext *scp);  */
+
+/* State of this thread when the signal was taken.  */
+struct sigcontext
+  {
+    /* These first members are machine-independent.  */
+
+    int sc_onstack;		/* Nonzero if running on sigstack.  */
+    __sigset_t sc_mask;		/* Blocked signals to restore.  */
+
+    /* MiG reply port this thread is using.  */
+    unsigned int sc_reply_port;
+
+    /* Port this thread is doing an interruptible RPC on.  */
+    unsigned int sc_intr_port;
+
+    /* Error code associated with this signal (interpreted as `error_t').  */
+    int sc_error;
+
+    /* All following members are machine-dependent.  The rest of this
+       structure is written to be laid out identically to a `struct
+       parisc_thread_state'.  trampoline.c knows this, so it must be
+       changed if this changes.  */
+
+#define sc_parisc_thread_state sc_flags /* Beginning of correspondence.  */
+    /* "General" registers $1..$31.  */
+    unsigned int sc_regs[31];
+
+    /* Control registers.  */
+    unsigned int sc_cr11;	/* sar */
+    /* These four registers make up the PC.  */
+    unsigned int iioq_head;
+    unsigned int iisq_head;
+    unsigned int iioq_tail;
+    unsigned int iisq_tail;
+    unsigned int sc_cr15;
+    unsigned int sc_cr19;
+    unsigned int sc_cr20;
+    unsigned int sc_cr21;
+    unsigned int sc_cr22;	/* ipsw */
+    unsigned int sc_bsd_goto;	/* unused */
+    unsigned int sc_sr4;
+    unsigned int sc_sr0;
+    unsigned int sc_sr1;
+    unsigned int sc_sr2;
+    unsigned int sc_sr3;
+    unsigned int sc_sr5;
+    unsigned int sc_sr6;
+    unsigned int sc_sr7;
+    unsigned int sc_cr0;
+    unsigned int sc_cr8;
+    unsigned int sc_cr9;
+    unsigned int sc_cr10;	/* unused */
+    unsigned int sc_cr12;
+    unsigned int sc_cr13;
+    unsigned int sc_cr24;	/* unused */
+    unsigned int sc_cr25;	/* unused */
+    unsigned int sc_cr26;	/* unused */
+    unsigned sc_mpsfu_high;	/* unused */
+    unsigned sc_mpsfu_low;	/* unused */
+    unsigned sc_mpsfu_ovflo;	/* unused */
+    int sc_pad;
+
+    /* Floating point registers $f0..$f31.  */
+    double sc_fpregs[32];
+  };
diff --git a/sysdeps/mach/hurd/hppa/trampoline.c b/sysdeps/mach/hurd/hppa/trampoline.c
new file mode 100644
index 0000000000..09ab71e88d
--- /dev/null
+++ b/sysdeps/mach/hurd/hppa/trampoline.c
@@ -0,0 +1,258 @@
+/* Set thread_state for sighandler, and sigcontext to recover.  HPPA version.
+Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include "thread_state.h"
+#include <assert.h>
+#include <errno.h>
+#include "hurdfault.h"
+
+     
+struct mach_msg_trap_regargs
+  {
+    /* These first four arguments are in registers 26..23.  */
+    mach_msg_size_t rcv_size;	/* arg3 */
+    mach_msg_size_t send_size;	/* arg2 */
+    mach_msg_option_t option;	/* arg1 */
+    mach_msg_header_t *msg;	/* arg0 */
+  };
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+			int signo, long int sigcode,
+			volatile int rpc_wait,
+			struct machine_thread_all_state *state)
+{
+  __label__ trampoline, rpc_wait_trampoline;
+  void *volatile sigsp;
+  struct sigcontext *scp;
+
+  if (ss->context)
+    {
+      /* We have a previous sigcontext that sigreturn was about
+	 to restore when another signal arrived.  We will just base
+	 our setup on that.  */
+      if (_hurdsig_catch_fault (SIGSEGV))
+	assert (_hurdsig_fault_sigcode >= (long int) ss->context &&
+		_hurdsig_fault_sigcode < (long int) (ss->context + 1));
+      else
+	{
+	  memcpy (&state->basic, &ss->context->sc_parisc_thread_state,
+		  sizeof (state->basic));
+	  state->set = (1 << PARISC_THREAD_STATE);
+	  assert (! rpc_wait);
+	  /* The intr_port slot was cleared before sigreturn sent us the
+	     sig_post that made us notice this pending signal, so
+	     _hurd_internal_post_signal wouldn't do interrupt_operation.
+	     After we return, our caller will set SCP->sc_intr_port (in the
+	     new context) from SS->intr_port and clear SS->intr_port.  Now
+	     that we are restoring this old context recorded by sigreturn,
+	     we want to restore its intr_port too; so store it in
+	     SS->intr_port now, so it will end up in SCP->sc_intr_port
+	     later.  */
+	  ss->intr_port = ss->context->sc_intr_port;
+	}
+      /* If the sigreturn context was bogus, just ignore it.  */
+      ss->context = NULL;
+    }
+  else if (! machine_get_basic_state (ss->thread, state))
+    return NULL;
+
+  if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+      !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK)))
+    {
+      sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+      ss->sigaltstack.ss_flags |= SA_ONSTACK;
+      /* XXX need to set up base of new stack for
+	 per-thread variables, cthreads.  */
+    }
+  else
+    sigsp = (char *) state->basic.uesp;
+
+  /* Push the signal context on the stack.  */
+  sigsp -= sizeof (*scp);
+  scp = sigsp;
+
+  if (_hurdsig_catch_fault (SIGSEGV))
+    {
+      assert (_hurdsig_fault_sigcode >= (long int) scp &&
+	      _hurdsig_fault_sigcode <= (long int) (scp + 1));
+      /* We got a fault trying to write the stack frame.
+	 We cannot set up the signal handler.
+	 Returning NULL tells our caller, who will nuke us with a SIGILL.  */
+      return NULL;
+    }
+  else
+    {
+      int ok;
+
+      /* Set up the sigcontext from the current state of the thread.  */
+
+      scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0;
+
+      /* struct sigcontext is laid out so that starting at sc_regs mimics a
+	 struct parisc_thread_state.  */
+      memcpy (&scp->sc_parisc_thread_state,
+	      &state->basic, sizeof (state->basic));
+
+      _hurdsig_end_catch_fault ();
+
+      if (! ok)
+	return NULL;
+    }
+
+  /* Modify the thread state to call the trampoline code on the new stack.  */
+  if (rpc_wait)
+    {
+      /* The signalee thread was blocked in a mach_msg_trap system call,
+	 still waiting for a reply.  We will have it run the special
+	 trampoline code which retries the message receive before running
+	 the signal handler.
+	 
+	 To do this we change the OPTION argument on its stack to enable only
+	 message reception, since the request message has already been
+	 sent.  */
+
+      struct mach_msg_trap_regargs *args = (void *) &state->basic.r23;
+
+      if (_hurdsig_catch_fault (SIGSEGV))
+	{
+	  assert (_hurdsig_fault_sigcode >= (long int) args &&
+		  _hurdsig_fault_sigcode < (long int) (args + 1));
+	  /* Faulted accessing ARGS.  Bomb.  */
+	  return NULL;
+	}
+
+      assert (args->option & MACH_RCV_MSG);
+      /* Disable the message-send, since it has already completed.  The
+	 calls we retry need only wait to receive the reply message.  */
+      args->option &= ~MACH_SEND_MSG;
+
+      _hurdsig_end_catch_fault ();
+
+      MACHINE_THREAD_STATE_SET_PC (&state->basic, &&rpc_wait_trampoline);
+      /* The reply-receiving trampoline code runs initially on the original
+	 user stack.  We pass it the signal stack pointer in %r5.  */
+      state->basic.r5 = (int) sigsp;
+      /* After doing the message receive, the trampoline code will need to
+	 update the %r28 value to be restored by sigreturn.  To simplify
+	 the assembly code, we pass the address of its slot in SCP to the
+	 trampoline code in %r4.  */
+      state->basic.r4 = (unsigned int) &scp->sc_regs[27];
+      /* Set up the arguments for the handler function in callee-saved
+	 registers that we will move to the argument registers after
+	 mach_msg_trap returns.  */
+      state->basic.r6 = signo;
+      state->basic.r7 = sigcode;
+      state->basic.r8 = (unsigned int) scp;
+    }
+  else
+    {
+      MACHINE_THREAD_STATE_SET_PC (&state->basic, &&trampoline);
+      state->basic.r20 = (unsigned int) sigsp;
+      /* Set up the arguments for the handler function.  */
+      state->basic.r26 = signo;
+      state->basic.r25 = sigcode;
+      state->basic.r24 = (unsigned int) scp;
+    }
+
+  /* We pass the handler function to the trampoline code in %r9.  */
+  state->basic.r9 = (unsigned int) handler;
+  /* For convenience, we pass the address of __sigreturn in %r10.  */
+  state->basic.r10 = (unsigned int) &__sigreturn;
+  /* The extra copy of SCP for the __sigreturn arg goes in %r8.  */
+  state->basic.r10 = (unsigned int) scp;
+
+  return scp;
+
+  /* The trampoline code follows.  This is not actually executed as part of
+     this function, it is just convenient to write it that way.  */
+
+ rpc_wait_trampoline:
+  /* This is the entry point when we have an RPC reply message to receive
+     before running the handler.  The MACH_MSG_SEND bit has already been
+     cleared in the OPTION argument on our stack.  The interrupted user
+     stack pointer has not been changed, so the system call can find its
+     arguments; the signal stack pointer is in %ebx.  For our convenience,
+     %ecx points to the sc_eax member of the sigcontext.  */
+  asm volatile
+    (/* Retry the interrupted mach_msg system call.  */
+     "ldil L%0xC0000000,%r1\nble 4(%sr7,%r1)\n"
+     "ldi -25, %r22\n"		/* mach_msg_trap */
+     /* When the sigcontext was saved, %r28 was MACH_RCV_INTERRUPTED.  But
+	now the message receive has completed and the original caller of
+	the RPC (i.e. the code running when the signal arrived) needs to
+	see the final return value of the message receive in %r28.  So
+	store the new %r28 value into the sc_regs[27] member of the sigcontext
+	(whose address is in %r4 to make this code simpler).  */
+     "stw (%r4), %r28\n"
+     /* Switch to the signal stack.  */
+     "copy %r5, %r30\n"
+     /* Copy the handler arguments to the argument registers.  */
+     "copy %r6, %r26\n"
+     "copy %r7, %r25\n"
+     "copy %r8, %r24\n"
+     );
+
+ trampoline:
+  /* Entry point for running the handler normally.  The arguments to the
+     handler function are already in the argument registers.  */
+  asm volatile
+    ("bv (%r9); nop"		/* Call the handler function.  */
+     "bv (%r10)\n"		/* Call __sigreturn (SCP); never returns.  */
+     "copy %r8, %r26"		/* Set up arg in delay slot.  */
+     : : "i" (&__sigreturn));
+
+  /* NOTREACHED */
+  return NULL;
+}
+
+/* STATE describes a thread that had intr_port set (meaning it was inside
+   HURD_EINTR_RPC), after it has been thread_abort'd.  It it looks to have
+   just completed a mach_msg_trap system call that returned
+   MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right
+   being waited on.  */
+int
+_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state,
+			    mach_port_t *port)
+{
+  const unsigned int *volatile pc
+    = MACHINE_THREAD_STATE_PC (&state->basic);
+  const mach_port_t *rcv_name
+    = (void *) state->r30 -32-20; /* VA_ARG4 from <mach/machine/asm.h>.  */
+
+  if (_hurdsig_catch_fault (SIGSEGV))
+    assert (_hurdsig_fault_sigcode == (long int) pc ||
+	    _hurdsig_fault_sigcode == (long int) rcv_name);
+  else
+    {
+      int rcving = (state->basic.r28 == MACH_RCV_INTERRUPTED &&
+		    pc == ???unfinished???);
+      if (rcving)
+	/* We did just return from a mach_msg_trap system call
+	   doing a message receive that was interrupted.
+	   Examine the parameters to find the receive right.  */
+	*port = *rcv_name;
+      _hurdsig_end_catch_fault ();
+      if (rcving)
+	return 1;
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/i386/exc2signal.c b/sysdeps/mach/hurd/i386/exc2signal.c
new file mode 100644
index 0000000000..19f845a49e
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/exc2signal.c
@@ -0,0 +1,165 @@
+/* Translate Mach exception codes into signal numbers.  i386 version.
+Copyright (C) 1991, 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <mach/exception.h>
+
+/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
+   into a signal number and signal subcode.  */
+
+void
+_hurd_exception2signal (int exception, int code, int subcode,
+			int *signo, long int *sigcode, int *error)
+{
+  *error = 0;
+
+  switch (exception)
+    {
+    default:
+      *signo = SIGIOT;
+      *sigcode = exception;
+      break;
+      
+    case EXC_BAD_ACCESS:
+      if (code == KERN_PROTECTION_FAILURE)
+	*signo = SIGSEGV;
+      else
+	*signo = SIGBUS;
+      *sigcode = subcode;
+      *error = code;
+      break;
+
+    case EXC_BAD_INSTRUCTION:
+      *signo = SIGILL;
+      if (code == EXC_I386_INVOP)
+	*sigcode = ILL_INVOPR_FAULT;
+      else if (code == EXC_I386_STKFLT)
+	*sigcode = ILL_STACK_FAULT;
+      else
+	*sigcode = 0;
+      break;
+      
+    case EXC_ARITHMETIC:
+      switch (code)
+	{
+	case EXC_I386_DIV:	/* integer divide by zero */
+	  *signo = SIGFPE;
+	  *sigcode = FPE_INTDIV_FAULT;
+	  break;
+	  
+	case EXC_I386_INTO:	/* integer overflow */
+	  *signo = SIGFPE;
+	  *sigcode = FPE_INTOVF_TRAP;
+	  break;
+
+	  /* These aren't anywhere documented or used in Mach 3.0.  */
+	case EXC_I386_NOEXT:
+	case EXC_I386_EXTOVR:
+	default:
+	  *signo = SIGFPE;
+	  *sigcode = 0;
+	  break;
+
+	case EXC_I386_EXTERR:
+	  /* Subcode is the fp_status word saved by the hardware.
+	     Give an error code corresponding to the first bit set.  */
+	  if (subcode & FPS_IE)
+	    {
+	      *signo = SIGILL;
+	      *sigcode = ILL_FPEOPR_FAULT;
+	    }
+	  else if (subcode & FPS_DE)
+	    {
+	      *signo = SIGFPE;
+	      *sigcode = FPE_FLTDNR_FAULT;
+	    }
+	  else if (subcode & FPS_ZE)
+	    {
+	      *signo = SIGFPE;
+	      *sigcode = FPE_FLTDIV_FAULT;
+	    }
+	  else if (subcode & FPS_OE)
+	    {
+	      *signo = SIGFPE;
+	      *sigcode = FPE_FLTOVF_FAULT;
+	    }
+	  else if (subcode & FPS_UE)
+	    {
+	      *signo = SIGFPE;
+	      *sigcode = FPE_FLTUND_FAULT;
+	    }
+	  else if (subcode & FPS_PE)
+	    {
+	      *signo = SIGFPE;
+	      *sigcode = FPE_FLTINX_FAULT;
+	    }
+	  else
+	    {
+	      *signo = SIGFPE;
+	      *sigcode = 0;
+	    }
+	  break;
+
+	  /* These two can only be arithmetic exceptions if we 
+	     are in V86 mode, which sounds like emulation to me.
+	     (See Mach 3.0 i386/trap.c.)  */
+	case EXC_I386_EMERR:
+	  *signo = SIGFPE;
+	  *sigcode = FPE_EMERR_FAULT;
+	  break;
+	case EXC_I386_BOUND:
+	  *signo = SIGFPE;
+	  *sigcode = FPE_EMBND_FAULT;
+	  break;
+	}
+      break;
+
+    case EXC_EMULATION:		
+      /* 3.0 doesn't give this one, why, I don't know.  */
+      *signo = SIGEMT;
+      *sigcode = 0;
+      break;
+
+    case EXC_SOFTWARE:
+      /* The only time we get this in Mach 3.0
+	 is for an out of bounds trap.  */
+      if (code == EXC_I386_BOUND)
+	{
+	  *signo = SIGFPE;
+	  *sigcode = FPE_SUBRNG_FAULT;
+	}
+      else
+	{
+	  *signo = SIGEMT;
+	  *sigcode = 0;
+	}
+      break;
+      
+    case EXC_BREAKPOINT:
+      *signo = SIGTRAP;
+      if (code == EXC_I386_SGL)
+	*sigcode = DBG_SINGLE_TRAP;
+      else if (code == EXC_I386_BPT)
+	*sigcode = DBG_BRKPNT_FAULT;
+      else
+	*sigcode = 0;
+      break;
+    }
+}
diff --git a/sysdeps/mach/hurd/i386/init-fault.c b/sysdeps/mach/hurd/i386/init-fault.c
new file mode 100644
index 0000000000..ff22814308
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/init-fault.c
@@ -0,0 +1,41 @@
+/* Set up a thread_state for proc_handle_exceptions.  i386 version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include <mach/thread_status.h>
+#include <string.h>
+#include <setjmp.h>
+
+extern jmp_buf _hurd_sigthread_fault_env;
+
+static char fault_stack[32];
+static volatile void
+faulted (void)
+{
+  __longjmp (_hurd_sigthread_fault_env, 1);
+}
+
+void
+_hurd_initialize_fault_recovery_state (void *state)
+{
+  struct i386_thread_state *ts = state;
+  memset (ts, 0, sizeof (*ts));
+  ts->uesp = (int) &fault_stack[sizeof (fault_stack)];
+  ts->eip = (int) &faulted;
+}
diff --git a/sysdeps/mach/hurd/i386/longjmp-ctx.c b/sysdeps/mach/hurd/i386/longjmp-ctx.c
new file mode 100644
index 0000000000..acfbee602e
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/longjmp-ctx.c
@@ -0,0 +1,35 @@
+/* Perform a `longjmp' on a `struct sigcontext'.  i386 version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <setjmp.h>
+#include <hurd/signal.h>
+#include <string.h>
+
+void
+_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval)
+{
+  memset (scp, 0, sizeof (*scp));
+  scp->sc_ebx = env[0].__bx;
+  scp->sc_esi = env[0].__si;
+  scp->sc_edi = env[0].__di;
+  scp->sc_ebp = (int) env[0].__bp;
+  scp->sc_uesp = (int) env[0].__sp;
+  scp->sc_eip = (int) env[0].__pc;
+  scp->sc_eax = retval == 0 ? 1 : retval;
+}
diff --git a/sysdeps/mach/hurd/i386/longjmp-ts.c b/sysdeps/mach/hurd/i386/longjmp-ts.c
new file mode 100644
index 0000000000..7da9be2a26
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/longjmp-ts.c
@@ -0,0 +1,39 @@
+/* Perform a `longjmp' on a Mach thread_state.  i386 version.
+Copyright (C) 1991, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <mach/thread_status.h>
+
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'.  */
+
+void
+_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
+{
+  struct i386_thread_state *ts = state;
+
+  ts->ebx = env[0].__jmpbuf[0].__bx;
+  ts->esi = env[0].__jmpbuf[0].__si;
+  ts->edi = env[0].__jmpbuf[0].__di;
+  ts->ebp = (int) env[0].__jmpbuf[0].__bp;
+  ts->uesp = (int) env[0].__jmpbuf[0].__sp;
+  ts->eip = (int) env[0].__jmpbuf[0].__pc;
+  ts->eax = val ?: 1;
+}
diff --git a/sysdeps/mach/hurd/i386/sigcontext.h b/sysdeps/mach/hurd/i386/sigcontext.h
new file mode 100644
index 0000000000..b742326bdb
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/sigcontext.h
@@ -0,0 +1,106 @@
+/* Machine-dependent signal context structure for GNU Hurd.  i386 version.
+Copyright (C) 1991, 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* Signal handlers are actually called:
+   void handler (int sig, int code, struct sigcontext *scp);  */
+
+#include <mach/machine/fp_reg.h>
+
+/* State of this thread when the signal was taken.  */
+struct sigcontext
+  {
+    /* These first members are machine-independent.  */
+
+    int sc_onstack;		/* Nonzero if running on sigstack.  */
+    __sigset_t sc_mask;		/* Blocked signals to restore.  */
+
+    /* MiG reply port this thread is using.  */
+    unsigned int sc_reply_port;
+
+    /* Port this thread is doing an interruptible RPC on.  */
+    unsigned int sc_intr_port;
+
+    /* Error code associated with this signal (interpreted as `error_t').  */
+    int sc_error;
+
+    /* All following members are machine-dependent.  The rest of this
+       structure is written to be laid out identically to:
+       {
+         struct i386_thread_state basic;
+         struct i386_float_state fpu;
+       }
+       trampoline.c knows this, so it must be changed if this changes.  */
+
+#define sc_i386_thread_state sc_gs /* Beginning of correspondence.  */
+    /* Segment registers.  */
+    int sc_gs;
+    int sc_fs;
+    int sc_es;
+    int sc_ds;
+  
+    /* "General" registers.  These members are in the order that the i386
+       `pusha' and `popa' instructions use (`popa' ignores %esp).  */
+    int sc_edi;
+    int sc_esi;
+    int sc_ebp;
+    int sc_esp;			/* Not used; sc_uesp is used instead.  */
+    int sc_ebx;
+    int sc_edx;
+    int sc_ecx;
+    int sc_eax;
+  
+    int sc_eip;			/* Instruction pointer.  */
+    int sc_cs;			/* Code segment register.  */
+  
+    int sc_efl;			/* Processor flags.  */
+
+    int sc_uesp;		/* This stack pointer is used.  */
+    int sc_ss;			/* Stack segment register.  */
+
+    /* Following mimics struct i386_float_state.  Structures and symbolic
+       values can be found in <mach/i386/fp_reg.h>.  */
+#define sc_i386_float_state sc_fpkind
+    int sc_fpkind;		/* FP_NO, FP_387, etc.  */
+    int sc_fpused;		/* If zero, ignore rest of float state.  */
+    struct i386_fp_save sc_fpsave;
+    struct i386_fp_regs sc_fpregs;
+    int sc_fpexcsr;		/* FPSR including exception bits.  */
+  };
+
+
+/* Codes for SIGFPE.  */
+#define FPE_INTOVF_TRAP		0x1 /* integer overflow */
+#define FPE_INTDIV_FAULT	0x2 /* integer divide by zero */
+#define FPE_FLTOVF_FAULT	0x3 /* floating overflow */
+#define FPE_FLTDIV_FAULT	0x4 /* floating divide by zero */
+#define FPE_FLTUND_FAULT	0x5 /* floating underflow */
+#define FPE_SUBRNG_FAULT	0x7 /* BOUNDS instruction failed */
+#define FPE_FLTDNR_FAULT	0x8 /* denormalized operand */
+#define FPE_FLTINX_FAULT	0x9 /* floating loss of precision */
+#define FPE_EMERR_FAULT		0xa /* mysterious emulation error 33 */
+#define FPE_EMBND_FAULT		0xb /* emulation BOUNDS instruction failed */
+
+/* Codes for SIGILL.  */
+#define ILL_INVOPR_FAULT	0x1 /* invalid operation */
+#define ILL_STACK_FAULT		0x2 /* fault on microkernel stack access */
+#define ILL_FPEOPR_FAULT	0x3 /* invalid floating operation */
+
+/* Codes for SIGTRAP.  */
+#define DBG_SINGLE_TRAP		0x1 /* single step */
+#define DBG_BRKPNT_FAULT	0x2 /* breakpoint instruction */
diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c
new file mode 100644
index 0000000000..df8960669f
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/sigreturn.c
@@ -0,0 +1,126 @@
+/* Copyright (C) 1991, 1992, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+register int *sp asm ("%esp");
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/threadvar.h>
+#include <hurd/msg.h>
+#include <stdlib.h>
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+  struct hurd_sigstate *ss;
+  mach_port_t *reply_port;
+
+  if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  ss = _hurd_self_sigstate ();
+  __spin_lock (&ss->lock);
+
+  /* Restore the set of blocked signals, and the intr_port slot.  */
+  ss->blocked = scp->sc_mask;
+  ss->intr_port = scp->sc_intr_port;
+
+  /* Check for pending signals that were blocked by the old set.  */
+  if (ss->pending & ~ss->blocked)
+    {
+      /* There are pending signals that just became unblocked.  Wake up the
+	 signal thread to deliver them.  But first, squirrel away SCP where
+	 the signal thread will notice it if it runs another handler, and
+	 arrange to have us called over again in the new reality.  */
+      ss->context = scp;
+      /* Clear the intr_port slot, since we are not in fact doing
+	 an interruptible RPC right now.  If SS->intr_port is not null,
+	 the SCP context is doing an interruptible RPC, but the signal
+	 thread will examine us while we are blocked in the sig_post RPC.  */
+      ss->intr_port = MACH_PORT_NULL;
+      __spin_unlock (&ss->lock);
+      __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+      /* If a pending signal was handled, sig_post never returned.  */
+      __spin_lock (&ss->lock);
+    }
+
+  if (scp->sc_onstack)
+    {
+      ss->sigaltstack.ss_flags &= ~SA_ONSTACK; /* XXX threadvars */
+      /* XXX cannot unlock until off sigstack */
+      abort ();
+    }
+  else
+    __spin_unlock (&ss->lock);
+
+  /* Destroy the MiG reply port used by the signal handler, and restore the
+     reply port in use by the thread when interrupted.  */
+  reply_port =
+    (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+  if (*reply_port)
+    __mach_port_destroy (__mach_task_self (), *reply_port);
+  *reply_port = scp->sc_reply_port;
+
+  if (scp->sc_fpused)
+    {
+  /* XXX should restore FPU state here XXX roland needs 387 manual */
+  /*    abort (); */
+    }
+
+  {
+    /* There are convenient instructions to pop state off the stack, so we
+       copy the registers onto the user's stack, switch there, pop and
+       return.  */
+
+    int *usp = (int *) scp->sc_uesp;
+
+    *--usp = scp->sc_eip;
+    *--usp = scp->sc_efl;
+    memcpy (usp -= 12, &scp->sc_i386_thread_state, 12 * sizeof (int));
+
+    sp = usp;
+
+#define A(line) asm volatile (#line)
+    /* The members in the sigcontext are arranged in this order
+       so we can pop them easily.  */
+
+    /* Pop the segment registers (except %cs and %ss, done last).  */
+    A (popl %gs);
+    A (popl %fs);
+    A (popl %es);
+    A (popl %ds);
+    /* Pop the general registers.  */
+    A (popa);
+    /* Pop the processor flags.  */
+    A (popf);
+    /* Return to the saved PC.  */
+    A (ret);
+
+    /* Firewall.  */
+    A (hlt);
+#undef A
+  }
+
+  /* NOTREACHED */
+  return -1;
+}
+
+weak_alias (__sigreturn, sigreturn)
diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
new file mode 100644
index 0000000000..eabf940b44
--- /dev/null
+++ b/sysdeps/mach/hurd/i386/trampoline.c
@@ -0,0 +1,271 @@
+/* Set thread_state for sighandler, and sigcontext to recover.  i386 version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include "thread_state.h"
+#include <assert.h>
+#include <errno.h>
+#include "hurdfault.h"
+
+     
+struct mach_msg_trap_args
+  {
+    void *retaddr;		/* Address mach_msg_trap will return to.  */
+    /* This is the order of arguments to mach_msg_trap.  */
+    mach_msg_header_t *msg;
+    mach_msg_option_t option;
+    mach_msg_size_t send_size;
+    mach_msg_size_t rcv_size;
+    mach_port_t rcv_name;
+    mach_msg_timeout_t timeout;
+    mach_port_t notify;
+  };
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+			int signo, long int sigcode,
+			volatile int rpc_wait,
+			struct machine_thread_all_state *state)
+{
+  __label__ trampoline, rpc_wait_trampoline;
+  void *volatile sigsp;
+  struct sigcontext *scp;
+  struct 
+    {
+      int signo;
+      long int sigcode;
+      struct sigcontext *scp;	/* Points to ctx, below.  */
+      struct sigcontext *return_scp; /* Same; arg to sigreturn.  */
+      struct sigcontext ctx;
+    } *stackframe;
+
+  if (ss->context)
+    {
+      /* We have a previous sigcontext that sigreturn was about
+	 to restore when another signal arrived.  We will just base
+	 our setup on that.  */
+      if (_hurdsig_catch_fault (SIGSEGV))
+	assert (_hurdsig_fault_sigcode >= (long int) ss->context &&
+		_hurdsig_fault_sigcode < (long int) (ss->context + 1));
+      else
+	{
+	  memcpy (&state->basic, &ss->context->sc_i386_thread_state,
+		  sizeof (state->basic));
+	  memcpy (&state->fpu, &ss->context->sc_i386_float_state,
+		  sizeof (state->fpu));
+	  state->set = (1 << i386_THREAD_STATE) | (1 << i386_FLOAT_STATE);
+	  assert (! rpc_wait);
+	  /* The intr_port slot was cleared before sigreturn sent us the
+	     sig_post that made us notice this pending signal, so
+	     _hurd_internal_post_signal wouldn't do interrupt_operation.
+	     After we return, our caller will set SCP->sc_intr_port (in the
+	     new context) from SS->intr_port and clear SS->intr_port.  Now
+	     that we are restoring this old context recorded by sigreturn,
+	     we want to restore its intr_port too; so store it in
+	     SS->intr_port now, so it will end up in SCP->sc_intr_port
+	     later.  */
+	  ss->intr_port = ss->context->sc_intr_port;
+	}
+      /* If the sigreturn context was bogus, just ignore it.  */
+      ss->context = NULL;
+    }
+  else if (! machine_get_basic_state (ss->thread, state))
+    return NULL;
+
+  if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+      !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK)))
+    {
+      sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+      ss->sigaltstack.ss_flags |= SA_ONSTACK;
+      /* XXX need to set up base of new stack for
+	 per-thread variables, cthreads.  */
+    }
+  else
+    sigsp = (char *) state->basic.uesp;
+
+  /* Push the arguments to call `trampoline' on the stack.  */
+  sigsp -= sizeof (*stackframe);
+  stackframe = sigsp;
+
+  if (_hurdsig_catch_fault (SIGSEGV))
+    {
+      assert (_hurdsig_fault_sigcode >= (long int) stackframe &&
+	      _hurdsig_fault_sigcode <= (long int) (stackframe + 1));
+      /* We got a fault trying to write the stack frame.
+	 We cannot set up the signal handler.
+	 Returning NULL tells our caller, who will nuke us with a SIGILL.  */
+      return NULL;
+    }
+  else
+    {
+      int ok;
+
+      /* Set up the arguments for the signal handler.  */
+      stackframe->signo = signo;
+      stackframe->sigcode = sigcode;
+      stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
+
+      /* Set up the sigcontext from the current state of the thread.  */
+
+      scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0;
+
+      /* struct sigcontext is laid out so that starting at sc_gs mimics a
+	 struct i386_thread_state.  */
+      memcpy (&scp->sc_i386_thread_state,
+	      &state->basic, sizeof (state->basic));
+
+      /* struct sigcontext is laid out so that starting at sc_fpkind mimics
+	 a struct i386_float_state.  */
+      ok = machine_get_state (ss->thread, state, i386_FLOAT_STATE,
+			      &state->fpu, &scp->sc_i386_float_state,
+			      sizeof (state->fpu));
+
+      _hurdsig_end_catch_fault ();
+
+      if (! ok)
+	return NULL;
+    }
+
+  /* Modify the thread state to call the trampoline code on the new stack.  */
+  if (rpc_wait)
+    {
+      /* The signalee thread was blocked in a mach_msg_trap system call,
+	 still waiting for a reply.  We will have it run the special
+	 trampoline code which retries the message receive before running
+	 the signal handler.
+	 
+	 To do this we change the OPTION argument on its stack to enable only
+	 message reception, since the request message has already been
+	 sent.  */
+
+      struct mach_msg_trap_args *args = (void *) state->basic.uesp;
+
+      if (_hurdsig_catch_fault (SIGSEGV))
+	{
+	  assert (_hurdsig_fault_sigcode >= (long int) args &&
+		  _hurdsig_fault_sigcode < (long int) (args + 1));
+	  /* Faulted accessing ARGS.  Bomb.  */
+	  return NULL;
+	}
+
+      assert (args->option & MACH_RCV_MSG);
+      /* Disable the message-send, since it has already completed.  The
+	 calls we retry need only wait to receive the reply message.  */
+      args->option &= ~MACH_SEND_MSG;
+
+      _hurdsig_end_catch_fault ();
+
+      state->basic.eip = (int) &&rpc_wait_trampoline;
+      /* The reply-receiving trampoline code runs initially on the original
+	 user stack.  We pass it the signal stack pointer in %ebx.  */
+      state->basic.ebx = (int) sigsp;
+      /* After doing the message receive, the trampoline code will need to
+	 update the %eax value to be restored by sigreturn.  To simplify
+	 the assembly code, we pass the address of its slot in SCP to the
+	 trampoline code in %ecx.  */
+      state->basic.ecx = (int) &scp->sc_eax;
+    }
+  else
+    {
+      state->basic.eip = (int) &&trampoline;
+      state->basic.uesp = (int) sigsp;
+    }
+  /* We pass the handler function to the trampoline code in %edx.  */
+  state->basic.edx = (int) handler;
+
+  return scp;
+
+  /* The trampoline code follows.  This is not actually executed as part of
+     this function, it is just convenient to write it that way.  */
+
+ rpc_wait_trampoline:
+  /* This is the entry point when we have an RPC reply message to receive
+     before running the handler.  The MACH_MSG_SEND bit has already been
+     cleared in the OPTION argument on our stack.  The interrupted user
+     stack pointer has not been changed, so the system call can find its
+     arguments; the signal stack pointer is in %ebx.  For our convenience,
+     %ecx points to the sc_eax member of the sigcontext.  */
+  asm volatile
+    (/* Retry the interrupted mach_msg system call.  */
+     "movl $-25, %eax\n"	/* mach_msg_trap */
+     "lcall $7, $0\n"
+     /* When the sigcontext was saved, %eax was MACH_RCV_INTERRUPTED.  But
+	now the message receive has completed and the original caller of
+	the RPC (i.e. the code running when the signal arrived) needs to
+	see the final return value of the message receive in %eax.  So
+	store the new %eax value into the sc_eax member of the sigcontext
+	(whose address is in %ecx to make this code simpler).  */
+     "movl %eax, (%ecx)\n"
+     /* Switch to the signal stack.  */
+     "movl %ebx, %esp\n");
+
+ trampoline:
+  /* Entry point for running the handler normally.  The arguments to the
+     handler function are already on the top of the stack:
+
+       0(%esp)	SIGNO
+       4(%esp)	SIGCODE
+       8(%esp)	SCP
+     */
+  asm volatile
+    ("call %*%%edx\n"		/* Call the handler function.  */
+     "addl $12, %%esp\n"	/* Pop its args.  */
+     "call %P0\n"		/* Call __sigreturn (SCP); never returns.  */
+     "hlt"			/* Just in case.  */
+     : : "i" (&__sigreturn));
+
+  /* NOTREACHED */
+  return NULL;
+}
+
+/* STATE describes a thread that had intr_port set (meaning it was inside
+   HURD_EINTR_RPC), after it has been thread_abort'd.  It it looks to have
+   just completed a mach_msg_trap system call that returned
+   MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right
+   being waited on.  */
+int
+_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state,
+			    mach_port_t *port)
+{
+  static const unsigned char syscall[] = { 0x9a, 0, 0, 0, 0, 7, 0 };
+  const unsigned char *volatile pc
+    = (void *) state->basic.eip - sizeof syscall;
+
+  if (_hurdsig_catch_fault (SIGSEGV))
+    assert (_hurdsig_fault_sigcode >= (long int) pc &&
+	    _hurdsig_fault_sigcode < (long int) pc + sizeof syscall);
+  else
+    {
+      int rcving = (state->basic.eax == MACH_RCV_INTERRUPTED &&
+		    !memcmp (pc, &syscall, sizeof syscall));
+      _hurdsig_end_catch_fault ();
+      if (rcving)
+	{
+	  /* We did just return from a mach_msg_trap system call
+	     doing a message receive that was interrupted.
+	     Examine the parameters to find the receive right.  */
+	  struct mach_msg_trap_args *args = (void *) state->basic.uesp;
+
+	  *port = args->rcv_name;
+	  return 1;
+	}
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c
new file mode 100644
index 0000000000..4aad0bb377
--- /dev/null
+++ b/sysdeps/mach/hurd/ioctl.c
@@ -0,0 +1,242 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#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 <hurd/ioctl.h>
+
+
+#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
+DEFUN(__ioctl, (fd, request),
+      int fd AND unsigned long int request DOTS)
+{
+  /* 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,
+      -1 };
+#define io2mach_type(count, type) \
+  ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 })
+
+  /* Extract the type information encoded in the request.  */
+  unsigned int type = _IOC_TYPE (request);
+
+  /* Message buffer.  */
+  struct
+    {
+      mig_reply_header_t header;
+      char data[3 * sizeof (mach_msg_type_t) +
+		_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)) +
+		_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)) +
+		_IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+    } msg;
+  mach_msg_header_t *const m = &msg.header.Head;
+  mach_msg_type_t *t = &msg.header.RetCodeType;
+  mach_msg_id_t msgid;
+  unsigned int reply_size;
+
+  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;
+
+      m->msgh_size = (char *) t - (char *) &msg;
+      m->msgh_remote_port = ioport;
+      m->msgh_local_port = __mig_get_reply_port ();
+      m->msgh_seqno = 0;
+      m->msgh_id = msgid;
+      m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
+				     MACH_MSG_TYPE_MAKE_SEND_ONCE);
+      err = HURD_EINTR_RPC (ioport, __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 (mig_reply_header_t))
+	return MIG_TYPE_ERROR;
+
+      if (*(int *) &msg.header.RetCodeType !=
+	  ((union { mach_msg_type_t t; int i; })
+	   { t: io2mach_type (1, _IOTS (sizeof msg.header.RetCode)) }).i)
+	return MIG_TYPE_ERROR;
+      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.  */
+      return (*handler) (fd, request, arg);
+  }
+
+  /* Compute the Mach message ID for the RPC from the group and command
+     parts of the ioctl request.  */
+  msgid = 100000 + ((_IOC_GROUP (request) - 'f') * 4000); /* Base subsystem */
+  /* Because of MiG's poorly chosen algorithm of adding 100 to a request
+     msgid to produce the reply msgid, we cannot just add the command part
+     of the ioctl request to the subsystem base msgid.  For ioctl requests
+     past 99, we must skip blocks of 100 msgids to allow for the reply
+     msgids corresponding to the earlier requests.  */
+  if (_IOC_COMMAND (request) >= 100)
+    msgid += 100;
+  if (_IOC_COMMAND (request) >= 200)
+    msgid += 100;
+  msgid += _IOC_COMMAND (request);
+
+  if (_IOC_INOUT (request) & IOC_IN)
+    {
+      /* Pack an argument into the message buffer.  */
+      void in (unsigned int count, enum __ioctl_datum type)
+	{
+	  if (count > 0)
+	    {
+	      void *p = &t[1];
+	      const size_t len = count * typesize ((unsigned int) type);
+	      *t = io2mach_type (count, type);
+	      memcpy (p, arg, len);
+	      arg += len;
+	      p += len;
+	      p = (void *) (((unsigned long int) p + sizeof (*t) - 1)
+			    & ~(sizeof (*t) - 1));
+	      t = p;
+	    }
+	}
+
+      /* 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));
+    }
+
+  /* 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 (mig_reply_header_t);
+
+  if (_IOC_INOUT (request) & IOC_OUT)
+    {
+      inline void figure_reply (unsigned int count, enum __ioctl_datum type)
+	{
+	  if (count > 0)
+	    {
+	      /* 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);
+	    }
+	}
+      figure_reply (_IOT_COUNT0 (type), _IOT_TYPE0 (type));
+      figure_reply (_IOT_COUNT1 (type), _IOT_TYPE1 (type));
+      figure_reply (_IOT_COUNT2 (type), _IOT_TYPE2 (type));
+    }
+
+  err = HURD_DPORT_USE (fd, _hurd_ctty_output (port, ctty, send_rpc));
+
+  t = (mach_msg_type_t *) msg.data;
+  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);
+	      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 *) (((unsigned long int) t + len + sizeof (*t) - 1)
+			    & ~(sizeof (*t) - 1));
+	    }
+	  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 --git a/sysdeps/mach/hurd/ioctls.h b/sysdeps/mach/hurd/ioctls.h
new file mode 100644
index 0000000000..af44873cb7
--- /dev/null
+++ b/sysdeps/mach/hurd/ioctls.h
@@ -0,0 +1,323 @@
+/* Copyright (C) 1992, 1993 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef	_IOCTLS_H
+
+#define	_IOCTLS_H	1
+
+/* Hurd ioctl request are made up of several fields:
+     bits 31-30: inout direction (enum __ioctl_dir)
+     bits 29-12: type encoding as follows; zero count indicates omitted datum
+	  29-28: datum #0 type (enum __ioctl_datum)
+	  27-26: datum #1 type (enum __ioctl_datum)
+	  25-24: datum #2 type (enum __ioctl_datum)
+	  23-19: datum #0 count	[0..31]
+	  18-14: datum #1 count [0..31]
+	  13-12: datum #2 count [0..3]
+     bits 11- 8: group (letter - 'f': ['f'..'v'])
+     bits  7- 0: command	[0..127]
+
+   The following macros construct and dissect these fields.  */
+
+enum __ioctl_dir
+  {
+    IOC_VOID = 0,		/* No parameters.  */
+    IOC_OUT = 1,		/* Data is written into the user's buffer.  */
+    IOC_IN = 2,			/* Data is read from the user's buffer.  */
+    IOC_INOUT = (IOC_IN|IOC_OUT)
+  };
+
+enum __ioctl_datum { IOC_8, IOC_16, IOC_32 };
+
+/* Construct an ioctl from constructed type plus other fields.  */
+#define	_IOC(inout, group, num, type) \
+  ((num) | ((((group) - 'f') | ((type) | (inout) << 19) << 4) << 7))
+
+/* Dissect an ioctl into its component fields.  */
+#define _IOC_INOUT(request)	(((unsigned int) (request) >> 30) & IOC_INOUT)
+#define _IOC_GROUP(request)	('f' + (((unsigned int) (request) >> 7) & 15))
+#define _IOC_COMMAND(request)	((unsigned int) (request) & 0x7f)
+#define _IOC_TYPE(request)	(((unsigned int) (request) >> 11) & 0x7ffff)
+
+/* Construct a type information field from
+   the broken-out type and count fields.  */
+#define	_IOT(t0, c0, t1, c1, t2, c2) \
+  ((c2) | (((c1) | ((c0) | ((t2) | ((t1) | (t0) << 2) << 2) << 5) << 5) << 3))
+
+/* Dissect a type information field into the type and count fields.  */
+#define	_IOT_TYPE0(type)	(((unsigned int) (type) >> 17) & 3)
+#define	_IOT_TYPE1(type)	(((unsigned int) (type) >> 15) & 3)
+#define	_IOT_TYPE2(type)	(((unsigned int) (type) >> 13) & 3)
+#define	_IOT_COUNT0(type)	(((unsigned int) (type) >> 8) & 0x1f)
+#define	_IOT_COUNT1(type)	(((unsigned int) (type) >> 3) & 0x1f)
+#define	_IOT_COUNT2(type)	(((unsigned int) (type) >> 0) & 3)
+
+/* Construct an ioctl from all the broken-out fields.  */
+#define	_IOCT(inout, group, num, t0, c0, t1, c1, t2, c2)		      \
+  _IOC ((inout), (group), (num), _IOT ((t0), (c0), (t1), (c1), (t2), (c2)))
+
+/* Standard flavors of ioctls.
+   _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	_IOR(g, n, t)	_IOC (IOC_OUT, (g), (n), _IOT_##t)
+#define	_IOW(g, n, t)	_IOC (IOC_IN, (g), (n), _IOT_##t)
+#define	_IOWR(g, n, t)	_IOC (IOC_INOUT, (g), (n), _IOT_##t)
+
+/* Construct an individual type field for TYPE.  */
+#define _IOTS(type)		(sizeof (type) >> 1)
+
+/* Construct a type information field for
+   a single argument of the scalar TYPE.  */
+#define	_IOT_SIMPLE(type)	_IOT (_IOTS (type), 1, 0, 0, 0, 0)
+
+/* Basic C types.  */
+#define	_IOT_int		_IOT_SIMPLE (int)
+#define	_IOT_char		_IOT_SIMPLE (char)
+#define	_IOT_short		_IOT_SIMPLE (short)
+
+
+/* ioctls verbatim from 4.4 <sys/ioctl.h>, with `struct' keywords removed.  */
+
+#define	TIOCMODG	_IOR('t', 3, int)	/* get modem control state */
+#define	TIOCMODS	_IOW('t', 4, int)	/* set modem control state */
+#define		TIOCM_LE	0001		/* line enable */
+#define		TIOCM_DTR	0002		/* data terminal ready */
+#define		TIOCM_RTS	0004		/* request to send */
+#define		TIOCM_ST	0010		/* secondary transmit */
+#define		TIOCM_SR	0020		/* secondary receive */
+#define		TIOCM_CTS	0040		/* clear to send */
+#define		TIOCM_CAR	0100		/* carrier detect */
+#define		TIOCM_CD	TIOCM_CAR
+#define		TIOCM_RNG	0200		/* ring */
+#define		TIOCM_RI	TIOCM_RNG
+#define		TIOCM_DSR	0400		/* data set ready */
+						/* 8-10 compat */
+#define	TIOCEXCL	_IO('t', 13)		/* set exclusive use of tty */
+#define	TIOCNXCL	_IO('t', 14)		/* reset exclusive use of tty */
+						/* 15 unused */
+#define	TIOCFLUSH	_IOW('t', 16, int)	/* flush buffers */
+						/* 17-18 compat */
+#define	TIOCGETA	_IOR('t', 19, termios) /* get termios struct */
+#define	TIOCSETA	_IOW('t', 20, termios) /* set termios struct */
+#define	TIOCSETAW	_IOW('t', 21, termios) /* drain output, set */
+#define	TIOCSETAF	_IOW('t', 22, termios) /* drn out, fls in, set */
+#define	TIOCGETD	_IOR('t', 26, int)	/* get line discipline */
+#define	TIOCSETD	_IOW('t', 27, int)	/* set line discipline */
+						/* 127-124 compat */
+#define	TIOCSBRK	_IO('t', 123)		/* set break bit */
+#define	TIOCCBRK	_IO('t', 122)		/* clear break bit */
+#define	TIOCSDTR	_IO('t', 121)		/* set data terminal ready */
+#define	TIOCCDTR	_IO('t', 120)		/* clear data terminal ready */
+#define	TIOCGPGRP	_IOR('t', 119, int)	/* get pgrp of tty */
+#define	TIOCSPGRP	_IOW('t', 118, int)	/* set pgrp of tty */
+						/* 117-116 compat */
+#define	TIOCOUTQ	_IOR('t', 115, int)	/* output queue size */
+#define	TIOCSTI		_IOW('t', 114, char)	/* simulate terminal input */
+#define	TIOCNOTTY	_IO('t', 113)		/* void tty association */
+#define	TIOCPKT		_IOW('t', 112, int)	/* pty: set/clear packet mode */
+#define		TIOCPKT_DATA		0x00	/* data packet */
+#define		TIOCPKT_FLUSHREAD	0x01	/* flush packet */
+#define		TIOCPKT_FLUSHWRITE	0x02	/* flush packet */
+#define		TIOCPKT_STOP		0x04	/* stop output */
+#define		TIOCPKT_START		0x08	/* start output */
+#define		TIOCPKT_NOSTOP		0x10	/* no more ^S, ^Q */
+#define		TIOCPKT_DOSTOP		0x20	/* now do ^S ^Q */
+#define		TIOCPKT_IOCTL		0x40	/* state change of pty driver */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCMSET	_IOW('t', 109, int)	/* set all modem bits */
+#define	TIOCMBIS	_IOW('t', 108, int)	/* bis modem bits */
+#define	TIOCMBIC	_IOW('t', 107, int)	/* bic modem bits */
+#define	TIOCMGET	_IOR('t', 106, int)	/* get all modem bits */
+#define	TIOCREMOTE	_IOW('t', 105, int)	/* remote input editing */
+#define	TIOCGWINSZ	_IOR('t', 104, winsize)	/* get window size */
+#define	TIOCSWINSZ	_IOW('t', 103, winsize)	/* set window size */
+#define	TIOCUCNTL	_IOW('t', 102, int)	/* pty: set/clr usr cntl mode */
+#define		UIOCCMD(n)	_IO('u', n)		/* usr cntl op "n" */
+#define	TIOCCONS	_IOW('t', 98, int)		/* become virtual console */
+#define	TIOCSCTTY	_IO('t', 97)		/* become controlling tty */
+#define	TIOCEXT		_IOW('t', 96, int)	/* pty: external processing */
+#define	TIOCSIG		_IO('t', 95)		/* pty: generate signal */
+#define TIOCDRAIN	_IO('t', 94)		/* wait till output drained */
+
+#define TTYDISC		0		/* termios tty line discipline */
+#define	TABLDISC	3		/* tablet discipline */
+#define	SLIPDISC	4		/* serial IP discipline */
+
+
+#define	FIOCLEX		_IO('f', 1)		/* set close on exec on fd */
+#define	FIONCLEX	_IO('f', 2)		/* remove close on exec */
+#define	FIONREAD	_IOR('f', 127, int)	/* get # bytes to read */
+#define	FIONBIO		_IOW('f', 126, int)	/* set/clear non-blocking i/o */
+#define	FIOASYNC	_IOW('f', 125, int)	/* set/clear async i/o */
+#define	FIOSETOWN	_IOW('f', 124, int)	/* set owner */
+#define	FIOGETOWN	_IOR('f', 123, int)	/* get owner */
+
+/* socket i/o controls */
+#define	SIOCSHIWAT	_IOW('s',  0, int)		/* set high watermark */
+#define	SIOCGHIWAT	_IOR('s',  1, int)		/* get high watermark */
+#define	SIOCSLOWAT	_IOW('s',  2, int)		/* set low watermark */
+#define	SIOCGLOWAT	_IOR('s',  3, int)		/* get low watermark */
+#define	SIOCATMARK	_IOR('s',  7, int)		/* at oob mark? */
+#define	SIOCSPGRP	_IOW('s',  8, int)		/* set process group */
+#define	SIOCGPGRP	_IOR('s',  9, int)		/* get process group */
+
+#define	SIOCADDRT	_IOW('r', 10, ortentry)	/* add route */
+#define	SIOCDELRT	_IOW('r', 11, ortentry)	/* delete route */
+
+#define	SIOCSIFADDR	_IOW('i', 12, ifreq)	/* set ifnet address */
+#define	OSIOCGIFADDR	_IOWR('i',13, ifreq)	/* get ifnet address */
+#define	SIOCGIFADDR	_IOWR('i',33, ifreq)	/* get ifnet address */
+#define	SIOCSIFDSTADDR	_IOW('i', 14, ifreq)	/* set p-p address */
+#define	OSIOCGIFDSTADDR	_IOWR('i',15, ifreq)	/* get p-p address */
+#define	SIOCGIFDSTADDR	_IOWR('i',34, ifreq)	/* get p-p address */
+#define	SIOCSIFFLAGS	_IOW('i', 16, ifreq)	/* set ifnet flags */
+#define	SIOCGIFFLAGS	_IOWR('i',17, ifreq)	/* get ifnet flags */
+#define	OSIOCGIFBRDADDR	_IOWR('i',18, ifreq)	/* get broadcast addr */
+#define	SIOCGIFBRDADDR	_IOWR('i',35, ifreq)	/* get broadcast addr */
+#define	SIOCSIFBRDADDR	_IOW('i',19, ifreq)	/* set broadcast addr */
+#define	OSIOCGIFCONF	_IOWR('i',20, ifconf)	/* get ifnet list */
+#define	SIOCGIFCONF	_IOWR('i',36, ifconf)	/* get ifnet list */
+#define	OSIOCGIFNETMASK	_IOWR('i',21, ifreq)	/* get net addr mask */
+#define	SIOCGIFNETMASK	_IOWR('i',37, ifreq)	/* get net addr mask */
+#define	SIOCSIFNETMASK	_IOW('i',22, ifreq)	/* set net addr mask */
+#define	SIOCGIFMETRIC	_IOWR('i',23, ifreq)	/* get IF metric */
+#define	SIOCSIFMETRIC	_IOW('i',24, ifreq)	/* set IF metric */
+#define	SIOCDIFADDR	_IOW('i',25, ifreq)	/* delete IF addr */
+#define	SIOCAIFADDR	_IOW('i',26, ifaliasreq)	/* add/chg IF alias */
+
+#define	SIOCSARP	_IOW('i', 30, arpreq)	/* set arp entry */
+#define	OSIOCGARP	_IOWR('i',31, arpreq)	/* get arp entry */
+#define	SIOCGARP	_IOWR('i',38, arpreq)	/* get arp entry */
+#define	SIOCDARP	_IOW('i', 32, arpreq)	/* delete arp entry */
+
+
+/* Compatibility with 4.3 BSD terminal driver.
+   From 4.4 <sys/ioctl_compat.h>.  */
+
+#ifdef USE_OLD_TTY
+# undef  TIOCGETD
+# define TIOCGETD	_IOR('t', 0, int)	/* get line discipline */
+# undef  TIOCSETD
+# define TIOCSETD	_IOW('t', 1, int)	/* set line discipline */
+#else
+# define OTIOCGETD	_IOR('t', 0, int)	/* get line discipline */
+# define OTIOCSETD	_IOW('t', 1, int)	/* set line discipline */
+#endif
+#define	TIOCHPCL	_IO('t', 2)		/* hang up on last close */
+#define	TIOCGETP	_IOR('t', 8,sgttyb)/* get parameters -- gtty */
+#define	TIOCSETP	_IOW('t', 9,sgttyb)/* set parameters -- stty */
+#define	TIOCSETN	_IOW('t',10,sgttyb)/* as above, but no flushtty*/
+#define	TIOCSETC	_IOW('t',17,tchars)/* set special characters */
+#define	TIOCGETC	_IOR('t',18,tchars)/* get special characters */
+#define		TANDEM		0x00000001	/* send stopc on out q full */
+#define		CBREAK		0x00000002	/* half-cooked mode */
+#define		LCASE		0x00000004	/* simulate lower case */
+#define		ECHO		0x00000008	/* echo input */
+#define		CRMOD		0x00000010	/* map \r to \r\n on output */
+#define		RAW		0x00000020	/* no i/o processing */
+#define		ODDP		0x00000040	/* get/send odd parity */
+#define		EVENP		0x00000080	/* get/send even parity */
+#define		ANYP		0x000000c0	/* get any parity/send none */
+#define		NLDELAY		0x00000300	/* \n delay */
+#define			NL0	0x00000000
+#define			NL1	0x00000100	/* tty 37 */
+#define			NL2	0x00000200	/* vt05 */
+#define			NL3	0x00000300
+#define		TBDELAY		0x00000c00	/* horizontal tab delay */
+#define			TAB0	0x00000000
+#define			TAB1	0x00000400	/* tty 37 */
+#define			TAB2	0x00000800
+#define		XTABS		0x00000c00	/* expand tabs on output */
+#define		CRDELAY		0x00003000	/* \r delay */
+#define			CR0	0x00000000
+#define			CR1	0x00001000	/* tn 300 */
+#define			CR2	0x00002000	/* tty 37 */
+#define			CR3	0x00003000	/* concept 100 */
+#define		VTDELAY		0x00004000	/* vertical tab delay */
+#define			FF0	0x00000000
+#define			FF1	0x00004000	/* tty 37 */
+#define		BSDELAY		0x00008000	/* \b delay */
+#define			BS0	0x00000000
+#define			BS1	0x00008000
+#define		ALLDELAY	(NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)
+#define		CRTBS		0x00010000	/* do backspacing for crt */
+#define		PRTERA		0x00020000	/* \ ... / erase */
+#define		CRTERA		0x00040000	/* " \b " to wipe out char */
+#define		TILDE		0x00080000	/* hazeltine tilde kludge */
+#define		MDMBUF		0x00100000	/*start/stop output on carrier*/
+#define		LITOUT		0x00200000	/* literal output */
+#define		TOSTOP		0x00400000	/*SIGSTOP on background output*/
+#define		FLUSHO		0x00800000	/* flush output to terminal */
+#define		NOHANG		0x01000000	/* (no-op) was no SIGHUP on carrier drop */
+#define		L001000		0x02000000
+#define		CRTKIL		0x04000000	/* kill line with " \b " */
+#define		PASS8		0x08000000
+#define		CTLECH		0x10000000	/* echo control chars as ^X */
+#define		PENDIN		0x20000000	/* tp->t_rawq needs reread */
+#define		DECCTQ		0x40000000	/* only ^Q starts after ^S */
+#define		NOFLSH		0x80000000	/* no output flush on signal */
+#define	TIOCLBIS	_IOW('t', 127, int)	/* bis local mode bits */
+#define	TIOCLBIC	_IOW('t', 126, int)	/* bic local mode bits */
+#define	TIOCLSET	_IOW('t', 125, int)	/* set entire local mode word */
+#define	TIOCLGET	_IOR('t', 124, int)	/* get local modes */
+#define		LCRTBS		(CRTBS>>16)
+#define		LPRTERA		(PRTERA>>16)
+#define		LCRTERA		(CRTERA>>16)
+#define		LTILDE		(TILDE>>16)
+#define		LMDMBUF		(MDMBUF>>16)
+#define		LLITOUT		(LITOUT>>16)
+#define		LTOSTOP		(TOSTOP>>16)
+#define		LFLUSHO		(FLUSHO>>16)
+#define		LNOHANG		(NOHANG>>16)
+#define		LCRTKIL		(CRTKIL>>16)
+#define		LPASS8		(PASS8>>16)
+#define		LCTLECH		(CTLECH>>16)
+#define		LPENDIN		(PENDIN>>16)
+#define		LDECCTQ		(DECCTQ>>16)
+#define		LNOFLSH		(NOFLSH>>16)
+#define	TIOCSLTC	_IOW('t',117,ltchars)/* set local special chars*/
+#define	TIOCGLTC	_IOR('t',116,ltchars)/* get local special chars*/
+#define OTIOCCONS	_IO('t', 98)	/* for hp300 -- sans int arg */
+#define	OTTYDISC	0
+#define	NETLDISC	1
+#define	NTTYDISC	2
+
+/* From 4.4 <sys/ttydev.h>.   */
+#ifdef USE_OLD_TTY
+#define B0	0
+#define B50	1
+#define B75	2
+#define B110	3
+#define B134	4
+#define B150	5
+#define B200	6
+#define B300	7
+#define B600	8
+#define B1200	9
+#define	B1800	10
+#define B2400	11
+#define B4800	12
+#define B9600	13
+#define EXTA	14
+#define EXTB	15
+#endif /* USE_OLD_TTY */
+
+
+#endif /* ioctls.h */
diff --git a/sysdeps/mach/hurd/isatty.c b/sysdeps/mach/hurd/isatty.c
new file mode 100644
index 0000000000..e04793a6a2
--- /dev/null
+++ b/sysdeps/mach/hurd/isatty.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+#include <hurd/term.h>
+
+/* Return 1 if FD is a terminal, 0 if not.  */
+int
+DEFUN(__isatty, (fd), int fd)
+{
+  error_t err;
+  mach_port_t id;
+
+  err = HURD_DPORT_USE (fd, __term_getctty (port, &id));
+  if (! err)
+    __mach_port_deallocate (__mach_task_self (), id);
+
+  return !err;
+}
+
+weak_alias (__isatty, isatty)
diff --git a/sysdeps/mach/hurd/kill.c b/sysdeps/mach/hurd/kill.c
new file mode 100644
index 0000000000..0d4af62127
--- /dev/null
+++ b/sysdeps/mach/hurd/kill.c
@@ -0,0 +1,106 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <hurd.h>
+#include <hurd/port.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+
+/* Send signal SIG to process number PID.  If PID is zero,
+   send SIG to all processes in the current process's process group.
+   If PID is < -1, send SIG to all processes in process group - PID.  */
+int
+__kill (pid_t pid, int sig)
+{
+  int delivered = 0;		/* Set when we deliver any signal.  */
+  error_t err;
+  mach_port_t proc;
+  struct hurd_userlink ulink;
+
+  inline void kill_pid (pid_t pid) /* Kill one PID.  */
+    {
+      /* SIGKILL is not delivered as a normal signal.
+	 Sending SIGKILL to a process means to terminate its task.  */
+      if (sig == SIGKILL)
+	/* Fetch the process's task port and terminate the task.  We
+	   loop in case the process execs and changes its task port.
+	   If the old task port dies after we fetch it but before we
+	   send the RPC, we get MACH_SEND_INVALID_DEST; if it dies
+	   after we send the RPC request but before it is serviced, we
+	   get MIG_SERVER_DIED.  */
+	do
+	  {
+	    task_t refport;
+	    err = __proc_pid2task (proc, pid, &refport);
+	    if (!err)
+	      {
+		err = __task_terminate (refport);
+		__mach_port_deallocate (__mach_task_self (), refport);
+	      }
+	  } while (err == MACH_SEND_INVALID_DEST ||
+		   err == MIG_SERVER_DIED);
+      else
+	err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport),
+				__proc_pid2task (proc, pid, &refport) ?
+				__proc_getsidport (proc, &refport) : 0, 1,
+				/* If no msgport, we cannot send a signal.  */
+				msgport == MACH_PORT_NULL ? EPERM :
+				__msg_sig_post (msgport, sig, refport));
+      if (! err)
+	delivered = 1;
+    }
+
+  proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);
+
+  if (pid <= 0)
+    {
+      /* Send SIG to each process in pgrp (- PID).  */
+      pid_t pidbuf[10], *pids = pidbuf;
+      mach_msg_type_number_t i, npids = sizeof (pidbuf) / sizeof (pidbuf[0]);
+      
+      err = __proc_getpgrppids (proc, - pid, &pids, &npids);
+      if (!err)
+	{
+	  for (i = 0; i < npids; ++i)
+	    {
+	      kill_pid (pids[i]);
+	      if (err == ESRCH)
+		/* The process died already.  Ignore it.  */
+		err = 0;
+	    }
+	  if (pids != pidbuf)
+	    __vm_deallocate (__mach_task_self (),
+			     (vm_address_t) pids, npids * sizeof (pids[0]));
+	}
+    }
+  else
+    kill_pid (pid);
+
+  _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc);
+
+  /* If we delivered no signals, but ERR is clear, this must mean that
+     every kill_pid call failed with ESRCH, meaning all the processes in
+     the pgrp died between proc_getpgrppids and kill_pid; in that case we
+     fail with ESRCH.  */
+  return delivered ? 0 : __hurd_fail (err ?: ESRCH);
+}
+
+weak_alias (__kill, kill)
diff --git a/sysdeps/mach/hurd/libc-ldscript b/sysdeps/mach/hurd/libc-ldscript
new file mode 100644
index 0000000000..26aca50272
--- /dev/null
+++ b/sysdeps/mach/hurd/libc-ldscript
@@ -0,0 +1,5 @@
+/* This linker script is installed as /lib/libc.a.
+   It makes -lc become just like -( -lcrt -lmachuser -lhurduser -).
+   */
+
+GROUP ( libcrt.a libmachuser.a libhurduser.a )
diff --git a/sysdeps/mach/hurd/link.c b/sysdeps/mach/hurd/link.c
new file mode 100644
index 0000000000..11262f5a0f
--- /dev/null
+++ b/sysdeps/mach/hurd/link.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Make a link to FROM called TO.  */
+int
+DEFUN(__link, (from, to), CONST char *from AND CONST char *to)
+{
+  error_t err;
+  file_t oldfile, linknode, todir;
+  char *toname;
+
+  oldfile = __file_name_lookup (from, 0, 0);
+  if (oldfile == MACH_PORT_NULL)
+    return -1;
+
+  /* The file_getlinknode RPC returns the port that should be passed to
+     the receiving filesystem (the one containing TODIR) in dir_link.  */
+
+  err = __file_getlinknode (oldfile, &linknode);
+  __mach_port_deallocate (__mach_task_self (), oldfile);
+  if (err)
+    return __hurd_fail (err);
+
+  todir = __file_name_split (to, &toname);
+  if (todir != MACH_PORT_NULL)
+    {
+      err = __dir_link (linknode, todir, toname);
+      __mach_port_deallocate (__mach_task_self (), todir);
+    }
+  __mach_port_deallocate (__mach_task_self (), linknode);
+  if (todir == MACH_PORT_NULL)
+    return -1;
+
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__link, link)
diff --git a/sysdeps/mach/hurd/listen.c b/sysdeps/mach/hurd/listen.c
new file mode 100644
index 0000000000..2f9c412c8b
--- /dev/null
+++ b/sysdeps/mach/hurd/listen.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/socket.h>
+#include <hurd/socket.h>
+
+/* Prepare to accept connections on socket FD.
+   N connection requests will be queued before further requests are refused.
+   Returns 0 on success, -1 for errors.  */
+int
+DEFUN(listen, (fd, n), int fd AND unsigned int n)
+{
+  error_t err = HURD_DPORT_USE (fd, __socket_listen (port, n));
+  if (err)
+    return __hurd_dfail (fd, err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/local_lim.h b/sysdeps/mach/hurd/local_lim.h
new file mode 100644
index 0000000000..766bd25244
--- /dev/null
+++ b/sysdeps/mach/hurd/local_lim.h
@@ -0,0 +1,40 @@
+/* Minimum guaranteed maximum values for system limits.  Hurd version.
+
+Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* GNU has no arbitrary fixed limits on these things, so we don't
+   define the macros.  Some things are unlimited.  Some are in fact
+   limited but the limit is run-time dependent and fetched with
+   `sysconf' or `pathconf'.
+
+   POSIX.1 requires that we define NGROUPS_MAX (though none of the others
+   is required).  GNU allows any number of supplementary groups,
+   dynamically allocated.  So we pick a number which seems vaguely
+   suitable, and `sysconf' will return a number at least as large.  */
+   
+#define NGROUPS_MAX	256
+
+/* The maximum number of symbolic links that are allowed in a single file
+   name resolution.  When a further link is encountered, the call returns
+   ELOOP.  This name is a GNU extension; POSIX.1 has no such limit, and BSD
+   calls it MAXSYMLINKS in <sys/param.h>.  */
+
+#ifdef __USE_GNU		/* 1003.1a defines this */
+#define	SYMLOOP_MAX	8
+#endif
diff --git a/sysdeps/mach/hurd/lseek.c b/sysdeps/mach/hurd/lseek.c
new file mode 100644
index 0000000000..396d2b9e09
--- /dev/null
+++ b/sysdeps/mach/hurd/lseek.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Seek to OFFSET on FD, starting from WHENCE.  */
+off_t
+DEFUN(__lseek, (fd, offset, whence), int fd AND off_t offset AND int whence)
+{
+  error_t err;
+  if (err = HURD_DPORT_USE (fd, __io_seek (port, offset, whence, &offset)))
+    return __hurd_dfail (fd, err);
+  return offset;
+}
+
+weak_alias (__lseek, lseek)
diff --git a/sysdeps/mach/hurd/lstat.c b/sysdeps/mach/hurd/lstat.c
new file mode 100644
index 0000000000..21eb448fe8
--- /dev/null
+++ b/sysdeps/mach/hurd/lstat.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <hurd.h>
+
+int
+DEFUN(__lstat, (file, buf), CONST char *file AND struct stat *buf)
+{
+  error_t err;
+  file_t port = __file_name_lookup (file, O_NOLINK, 0);
+  if (port == MACH_PORT_NULL)
+    return -1;
+  err = __io_stat (port, buf);
+  __mach_port_deallocate (__mach_task_self (), port);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__lstat, lstat)
diff --git a/sysdeps/mach/hurd/mig-reply.c b/sysdeps/mach/hurd/mig-reply.c
new file mode 100644
index 0000000000..feb03257dd
--- /dev/null
+++ b/sysdeps/mach/hurd/mig-reply.c
@@ -0,0 +1,86 @@
+/* Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mach.h>
+#include <hurd/threadvar.h>
+
+#define GETPORT \
+  mach_port_t *portloc = \
+    (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY)
+#define reply_port (use_threadvar ? *portloc : global_reply_port)
+
+static int use_threadvar;
+static mach_port_t global_reply_port;
+
+/* These functions are called by MiG-generated code.  */
+
+/* Called by MiG to get a reply port.  */
+mach_port_t
+__mig_get_reply_port (void)
+{
+  GETPORT;
+
+  if (reply_port == MACH_PORT_NULL)
+    reply_port = __mach_reply_port ();
+
+  return reply_port;
+}
+weak_alias (__mig_get_reply_port, mig_get_reply_port)
+
+/* Called by MiG to deallocate the reply port.  */
+void
+__mig_dealloc_reply_port (mach_port_t arg)
+{
+  mach_port_t port;
+
+  GETPORT;
+
+  port = reply_port;
+  reply_port = MACH_PORT_NULL;	/* So the mod_refs RPC won't use it.  */
+  __mach_port_mod_refs (__mach_task_self (), port,
+			MACH_PORT_RIGHT_RECEIVE, -1);
+}
+weak_alias (__mig_dealloc_reply_port, mig_dealloc_reply_port)
+
+/* Called by mig interfaces when done with a port.  Used to provide the
+   same interface as needed when a custom allocator is used.  */
+void
+__mig_put_reply_port(mach_port_t port)
+{
+  /* Do nothing.  */
+}
+weak_alias (__mig_put_reply_port, mig_put_reply_port)
+
+/* Called at startup with STACK == NULL.  When per-thread variables are set
+   up, this is called again with STACK set to the new stack being switched
+   to, where per-thread variables should be set up.  */
+void
+__mig_init (void *stack)
+{
+  use_threadvar = stack != 0;
+
+  if (use_threadvar)
+    {
+      /* Recycle the reply port used before multithreading was enabled.  */
+      mach_port_t *portloc = (mach_port_t *)
+	__hurd_threadvar_location_from_sp (_HURD_THREADVAR_MIG_REPLY, stack);
+      *portloc = global_reply_port;
+      global_reply_port = MACH_PORT_NULL;
+    }
+}
+weak_alias (__mig_init, mig_init)
diff --git a/sysdeps/mach/hurd/mips/exc2signal.c b/sysdeps/mach/hurd/mips/exc2signal.c
new file mode 100644
index 0000000000..f907c89cf0
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/exc2signal.c
@@ -0,0 +1,98 @@
+/* Translate Mach exception codes into signal numbers.  MIPS version.
+Copyright (C) 1991, 1992, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <mach/exception.h>
+
+/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
+   into a signal number and signal subcode.  */
+
+void
+_hurd_exception2signal (int exception, int code, int subcode,
+			int *signo, long int *sigcode, int *error)
+{
+  *error = 0;
+
+  switch (exception)
+    {
+    default:
+      *signo = SIGIOT;
+      *sigcode = exception;
+      break;
+      
+    case EXC_BAD_ACCESS:
+      if (code == KERN_PROTECTION_FAILURE)
+	*signo = SIGSEGV;
+      else
+	*signo = SIGBUS;
+      *sigcode = subcode;
+      *error = code;
+      break;
+
+    case EXC_BAD_INSTRUCTION:
+      *signo = SIGILL;
+      if (code == EXC_MIPS_II)
+	*sigcode = code;
+      else
+	*sigcode = 0;
+      break;
+      
+    case EXC_ARITHMETIC:
+      switch (code)
+	{
+	case EXC_MIPS_OV:	/* integer overflow */
+	  *signo = SIGFPE;
+	  *sigcode = EXC_MIPS_FLT_OVERFLOW;
+	  break;
+
+	default:
+	  *signo = SIGFPE;
+	  *sigcode = 0;
+	  break;
+
+	case EXC_MIPS_INT:
+	  /* Subcode is the fp_status word saved by the hardware.
+	     Give an error code corresponding to the first bit set.  */
+	  if (subcode == EXC_MIPS_FLT_UNIMP)
+	    *signo = SIGILL;
+	  else
+	    *signo = SIGFPE;
+	  *sigcode = subcode;
+	  break;
+	}
+      break;
+
+    case EXC_EMULATION:		
+      /* 3.0 doesn't give this one, why, I don't know.  */
+      *signo = SIGEMT;
+      *sigcode = 0;
+      break;
+
+    case EXC_SOFTWARE:
+      *signo = SIGEMT;
+      *sigcode = 0;
+      break;
+      
+    case EXC_BREAKPOINT:
+      *signo = SIGTRAP;
+      *sigcode = code;
+      break;
+    }
+}
diff --git a/sysdeps/mach/hurd/mips/init-fault.c b/sysdeps/mach/hurd/mips/init-fault.c
new file mode 100644
index 0000000000..e6f8acf64d
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/init-fault.c
@@ -0,0 +1,41 @@
+/* Set up a thread_state for proc_handle_exceptions.  MIPS version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include <mach/thread_status.h>
+#include <string.h>
+#include <setjmp.h>
+
+extern jmp_buf _hurd_sigthread_fault_env;
+
+static char fault_stack[32];
+static volatile void
+faulted (void)
+{
+  __longjmp (_hurd_sigthread_fault_env, 1);
+}
+
+void
+_hurd_initialize_fault_recovery_state (void *state)
+{
+  struct mips_thread_state *ts = state;
+  memset (ts, 0, sizeof (*ts));
+  ts->r29 = (int) &fault_stack[sizeof (fault_stack)];
+  ts->pc = (int) &faulted;
+}
diff --git a/sysdeps/mach/hurd/mips/longjmp-ctx.c b/sysdeps/mach/hurd/mips/longjmp-ctx.c
new file mode 100644
index 0000000000..0c78f6b4d6
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/longjmp-ctx.c
@@ -0,0 +1,41 @@
+/* Perform a `longjmp' on a `struct sigcontext'.  MIPS version.
+Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <setjmp.h>
+#include <hurd/signal.h>
+#include <string.h>
+
+void
+_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval)
+{
+  scp->sc_gpr[16] = env[0].__regs[0];
+  scp->sc_gpr[17] = env[0].__regs[1];
+  scp->sc_gpr[18] = env[0].__regs[2];
+  scp->sc_gpr[19] = env[0].__regs[3];
+  scp->sc_gpr[20] = env[0].__regs[4];
+  scp->sc_gpr[21] = env[0].__regs[5];
+  scp->sc_gpr[22] = env[0].__regs[6];
+  scp->sc_gpr[23] = env[0].__regs[7];
+
+  scp->sc_gpr[28] = (int) env[0].__gp;
+  scp->sc_fp = (int) env[0].__fp;
+  scp->sc_sp = (int) env[0].__sp;
+  scp->sc_pc = (int) env[0].__pc;
+  scp->sc_gpr[2] = retval ?: 1;
+}
diff --git a/sysdeps/mach/hurd/mips/longjmp-ts.c b/sysdeps/mach/hurd/mips/longjmp-ts.c
new file mode 100644
index 0000000000..980a2ceb94
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/longjmp-ts.c
@@ -0,0 +1,45 @@
+/* Perform a `longjmp' on a Mach thread_state.  MIPS version.
+Copyright (C) 1991, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+#include <mach/thread_status.h>
+
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'.  */
+
+void
+_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
+{
+  struct mips_thread_state *ts = state;
+
+  ts->r16 = env[0].__jmpbuf[0].__regs[0];
+  ts->r17 = env[0].__jmpbuf[0].__regs[1];
+  ts->r18 = env[0].__jmpbuf[0].__regs[2];
+  ts->r19 = env[0].__jmpbuf[0].__regs[3];
+  ts->r20 = env[0].__jmpbuf[0].__regs[4];
+  ts->r21 = env[0].__jmpbuf[0].__regs[5];
+  ts->r22 = env[0].__jmpbuf[0].__regs[6];
+  ts->r23 = env[0].__jmpbuf[0].__regs[7];
+  ts->r28 = (int) env[0].__jmpbuf[0].__gp;
+  ts->r29 = (int) env[0].__jmpbuf[0].__sp;
+  ts->r30 = (int) env[0].__jmpbuf[0].__fp;
+  ts->pc = (int) env[0].__jmpbuf[0].__pc;
+  ts->r2 = val ?: 1;
+}
diff --git a/sysdeps/mach/hurd/mips/sigcontext.h b/sysdeps/mach/hurd/mips/sigcontext.h
new file mode 100644
index 0000000000..81d1f25f25
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/sigcontext.h
@@ -0,0 +1,71 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* Signal handlers are actually called:
+   void handler (int sig, int code, struct sigcontext *scp);  */
+
+/* State of this thread when the signal was taken.  */
+struct sigcontext
+  {
+    /* These first members are machine-independent.  */
+
+    int sc_onstack;		/* Nonzero if running on sigstack.  */
+    __sigset_t sc_mask;		/* Blocked signals to restore.  */
+
+    /* MiG reply port this thread is using.  */
+    unsigned int sc_reply_port;
+
+    /* Port this thread is doing an interruptible RPC on.  */
+    unsigned int sc_intr_port;
+
+    /* Error code associated with this signal (interpreted as `error_t').  */
+    int sc_error;
+
+    /* All following members are machine-dependent.  The rest of this
+       structure is written to be laid out identically to:
+    	{
+	  struct mips_thread_state ts;
+	  struct mips_exc_state es;
+	  struct mips_float_state fs;
+	}
+       trampoline.c knows this, so it must be changed if this changes.  */
+#define	sc_mips_thread_state sc_gpr /* Beginning of correspondence.  */
+    int sc_gpr[31];		/* "General" registers; [0] is r1.  */
+    int sc_mdlo, sc_mdhi;	/* Low and high multiplication results.  */
+    int sc_pc;			/* Instruction pointer.  */
+
+    /* struct mips_exc_state */
+#define sc_mips_exc_state sc_cause
+    unsigned int sc_cause;	/* Machine-level trap code.  */
+#define SC_CAUSE_SST	0x00000044
+    unsigned int sc_badvaddr;
+    unsigned int sc_coproc_used; /* Which coprocessors the thread has used.  */
+#define SC_COPROC_USE_COP0	1 /* (by definition) */
+#define SC_COPROC_USE_COP1	2 /* FPA */
+#define	SC_COPROC_USE_FPU	SC_COPROC_USE_COP1
+#define SC_COPROC_USE_COP2	4
+#define SC_COPROC_USE_COP3	8
+
+    /* struct mips_float_state
+       This is only filled in if the SC_COPROC_USE_FPU bit
+       is set in sc_coproc_used.  */
+#define sc_mips_float_state sc_fpr
+    int sc_fpr[32];		/* FP registers.  */
+    int sc_fpcsr;		/* FPU status register.  */
+    int sc_fpeir;		/* FP exception instruction register.  */
+  };
diff --git a/sysdeps/mach/hurd/mips/sigreturn.c b/sysdeps/mach/hurd/mips/sigreturn.c
new file mode 100644
index 0000000000..7396a8bb22
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/sigreturn.c
@@ -0,0 +1,169 @@
+/* Copyright (C) 1991, 1992, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/threadvar.h>
+#include <stdlib.h>
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+  struct hurd_sigstate *ss;
+  mach_port_t *reply_port;
+
+  if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  ss = _hurd_self_sigstate ();
+  __spin_lock (&ss->lock);
+
+  /* Restore the set of blocked signals, and the intr_port slot.  */
+  ss->blocked = scp->sc_mask;
+  ss->intr_port = scp->sc_intr_port;
+
+  /* Check for pending signals that were blocked by the old set.  */
+  if (ss->pending & ~ss->blocked)
+    {
+      /* There are pending signals that just became unblocked.  Wake up the
+	 signal thread to deliver them.  But first, squirrel away SCP where
+	 the signal thread will notice it if it runs another handler, and
+	 arrange to have us called over again in the new reality.  */
+      ss->context = scp;
+      /* Clear the intr_port slot, since we are not in fact doing
+	 an interruptible RPC right now.  If SS->intr_port is not null,
+	 the SCP context is doing an interruptible RPC, but the signal
+	 thread will examine us while we are blocked in the sig_post RPC.  */
+      ss->intr_port = MACH_PORT_NULL;
+      __spin_unlock (&ss->lock);
+      __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+      /* If a pending signal was handled, sig_post never returned.  */
+      __spin_lock (&ss->lock);
+    }
+
+  if (scp->sc_onstack)
+    {
+      ss->sigaltstack.ss_flags &= ~SA_ONSTACK; /* XXX threadvars */
+      /* XXX cannot unlock until off sigstack */
+      abort ();
+    }
+  else
+    __spin_unlock (&ss->lock);
+
+  /* Destroy the MiG reply port used by the signal handler, and restore the
+     reply port in use by the thread when interrupted.  */
+  reply_port =
+    (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
+  if (*reply_port)
+    __mach_port_destroy (__mach_task_self (), *reply_port);
+  *reply_port = scp->sc_reply_port;
+
+  if (scp->sc_coproc_used & SC_COPROC_USE_FPU)
+    {
+      /* Restore FPU state.  */
+#define restore_fpr(n) \
+  asm volatile ("l.d $f" #n ",%0" : : "m" (scp->sc_fpr[n]))
+
+      /* Restore floating-point registers. */
+      restore_fpr (0);
+      restore_fpr (2);
+      restore_fpr (4);
+      restore_fpr (6);
+      restore_fpr (8);
+      restore_fpr (10);
+      restore_fpr (12);
+      restore_fpr (14);
+      restore_fpr (16);
+      restore_fpr (18);
+      restore_fpr (20);
+      restore_fpr (22);
+      restore_fpr (24);
+      restore_fpr (26);
+      restore_fpr (28);
+      restore_fpr (30);
+
+      /* Restore the floating-point control/status register ($f31).  */
+      asm volatile ("ctc1 %0,$f31" : : "r" (scp->sc_fpcsr));
+    }
+
+  /* Load all the registers from the sigcontext.  */
+#define restore_gpr(n) \
+  asm volatile ("lw $" #n ",%0" : : "m" (scpreg->sc_gpr[n - 1]))
+
+  {
+    register const struct sigcontext *const scpreg asm ("$1") = scp;
+    register int *at asm ("$1");
+
+    /* First restore the multiplication result registers.  The compiler
+       will use some temporary registers, so we do this before restoring
+       the general registers.  */
+    asm volatile ("mtlo %0" : : "r" (scpreg->sc_mdlo));
+    asm volatile ("mthi %0" : : "r" (scpreg->sc_mdhi));
+
+    /* In the word after the saved PC, store the saved $1 value.  */
+    (&scpreg->sc_pc)[1] = scpreg->sc_gpr[0];
+
+    asm volatile (".set noreorder; .set noat;");
+
+    /* Restore the normal registers.  */
+    restore_gpr (2);
+    restore_gpr (3);
+    restore_gpr (4);
+    restore_gpr (5);
+    restore_gpr (6);
+    restore_gpr (7);
+    restore_gpr (8);
+    restore_gpr (9);
+    restore_gpr (10);
+    restore_gpr (11);
+    restore_gpr (12);
+    restore_gpr (13);
+    restore_gpr (14);
+    restore_gpr (15);
+    restore_gpr (16);
+    restore_gpr (17);
+    restore_gpr (18);
+    restore_gpr (19);
+    restore_gpr (20);
+    restore_gpr (21);
+    restore_gpr (22);
+    restore_gpr (23);
+    restore_gpr (24);
+    restore_gpr (25);
+    /* Registers 26-27 are kernel-only.  */
+    restore_gpr (28);
+    restore_gpr (29);		/* Stack pointer.  */
+    restore_gpr (30);		/* Frame pointer.  */
+    restore_gpr (31);		/* Return address.  */
+
+    at = &scpreg->sc_pc;
+    /* This is an emulated instruction that will find at the address in $1
+       two words: the PC value to restore, and the $1 value to restore.  */
+    asm volatile (".word op_sigreturn");
+
+    asm volatile (".set reorder; .set at;");
+  }
+
+  /* NOTREACHED */
+  return -1;
+}
+
+weak_alias (__sigreturn, sigreturn)
diff --git a/sysdeps/mach/hurd/mips/trampoline.c b/sysdeps/mach/hurd/mips/trampoline.c
new file mode 100644
index 0000000000..f03ad5852f
--- /dev/null
+++ b/sysdeps/mach/hurd/mips/trampoline.c
@@ -0,0 +1,260 @@
+/* Set thread_state for sighandler, and sigcontext to recover.  MIPS version.
+Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd/signal.h>
+#include "thread_state.h"
+
+
+struct mach_msg_trap_args
+  {
+    /* This is the order of arguments to mach_msg_trap.  */
+    mach_msg_header_t *msg;
+    mach_msg_option_t option;
+    mach_msg_size_t send_size;
+    mach_msg_size_t rcv_size;
+    mach_port_t rcv_name;
+    mach_msg_timeout_t timeout;
+    mach_port_t notify;
+  };
+
+
+struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+			int signo, long int sigcode,
+			int rpc_wait,
+			struct machine_thread_all_state *state)
+{
+
+  __label__ trampoline, rpc_wait_trampoline;
+  void *sigsp;
+  struct sigcontext *scp;
+
+  if (ss->context)
+    {
+      /* We have a previous sigcontext that sigreturn was about
+	 to restore when another signal arrived.  We will just base
+	 our setup on that.  */
+      if (! setjmp (_hurd_sigthread_fault_env))
+	{
+	  memcpy (&state->basic, &ss->context->sc_mips_thread_state,
+		  sizeof (state->basic));
+	  memcpy (&state->exc, &ss->context->sc_mips_exc_state,
+		  sizeof (state->exc));
+	  state->set = (1 << MIPS_THREAD_STATE) | (1 << MIPS_EXC_STATE);
+	  if (state->exc.coproc_state & SC_COPROC_USE_FPU)
+	    {
+	      memcpy (&state->fpu, &ss->context->sc_mips_float_state,
+		      sizeof (state->fpu));
+	      state->set |= (1 << MIPS_FLOAT_STATE);
+	    }
+	  assert (! rpc_wait);
+	  /* The intr_port slot was cleared before sigreturn sent us the
+	     sig_post that made us notice this pending signal, so
+	     _hurd_internal_post_signal wouldn't do interrupt_operation.
+	     After we return, our caller will set SCP->sc_intr_port (in the
+	     new context) from SS->intr_port and clear SS->intr_port.  Now
+	     that we are restoring this old context recorded by sigreturn,
+	     we want to restore its intr_port too; so store it in
+	     SS->intr_port now, so it will end up in SCP->sc_intr_port
+	     later.  */
+	  ss->intr_port = ss->context->sc_intr_port;
+	}
+      /* If the sigreturn context was bogus, just ignore it.  */
+      ss->context = NULL;
+    }
+  else if (! machine_get_basic_state (ss->thread, state))
+    return NULL;
+
+  if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
+      !(ss->sigaltstack.ss_flags & (SA_DISABLE|SA_ONSTACK)))
+    {
+      sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+      ss->sigaltstack.ss_flags |= SA_ONSTACK;
+      /* XXX need to set up base of new stack for
+	 per-thread variables, cthreads.  */
+    }
+  else
+    sigsp = (char *) state->basic.r29;
+
+  /* Set up the sigcontext structure on the stack.  This is all the stack
+     needs, since the args are passed in registers (below).  */
+  sigsp -= sizeof (*scp);
+  scp = sigsp;
+
+  if (! setjmp (_hurd_sigthread_fault_env))
+    {
+      /* Set up the sigcontext from the current state of the thread.  */
+
+      scp->sc_onstack = ss->sigaltstack.ss_flags & SA_ONSTACK ? 1 : 0;
+
+      /* struct sigcontext is laid out so that starting at sc_gpr
+	 mimics a struct mips_thread_state.  */
+      memcpy (&scp->sc_mips_thread_state,
+	      &state->basic, sizeof (state->basic));
+
+      /* struct sigcontext is laid out so that starting at sc_cause
+	 mimics a struct mips_exc_state.  */
+      if (! machine_get_state (ss->thread, state, MIPS_EXC_STATE,
+			       &state->exc, &scp->sc_cause,
+			       sizeof (state->exc)))
+	return NULL;
+      if ((scp->sc_coproc_used & SC_COPROC_USE_FPU) &&
+	  /* struct sigcontext is laid out so that starting at sc_fpr
+	     mimics a struct mips_float_state.  This state
+	     is only meaningful if the coprocessor was used.  */
+	  ! machine_get_state (ss->thread, state, MIPS_FLOAT_STATE,
+			       &state->fpu,
+			       &scp->sc_mips_float_state, sizeof (state->fpu)))
+	return NULL;
+    }
+  else
+    /* We got a fault trying to write the stack frame.
+       We cannot set up the signal handler.
+       Returning NULL tells our caller, who will nuke us with a SIGILL.  */
+    return NULL;
+
+  /* Modify the thread state to call the trampoline code on the new stack.  */
+  if (rpc_wait)
+    {
+      /* The signalee thread was blocked in a mach_msg_trap system call,
+	 still waiting for a reply.  We will have it run the special
+	 trampoline code which retries the message receive before running
+	 the signal handler.
+	 
+	 To do this we change the OPTION argument in its registers to
+	 enable only message reception, since the request message has
+	 already been sent.  */
+
+      /* The system call arguments are stored in consecutive registers
+	 starting with a0 ($4).  */
+      struct mach_msg_trap_args *args = (void *) &state->basic.r4;
+
+      assert (args->option & MACH_RCV_MSG);
+      /* Disable the message-send, since it has already completed.  The
+	 calls we retry need only wait to receive the reply message.  */
+      args->option &= ~MACH_SEND_MSG;
+
+      state->basic.pc = (int) &&rpc_wait_trampoline;
+      state->basic.r29 = (int) sigsp; /* $29 is the stack pointer register.  */
+      /* After doing the message receive, the trampoline code will need to
+	 update the v0 ($2) value to be restored by sigreturn.  To simplify
+	 the assembly code, we pass the address of its slot in SCP to the
+	 trampoline code in v1 ($3).  */
+      state->basic.r3 = (int) &scp->sc_gpr[1];
+      /* We must preserve the mach_msg_trap args in a0..t2 ($4..$10).
+	 Pass the handler args to the trampoline code in s1..s3 ($17..$19).  */
+      state->basic.r17 = signo;
+      state->basic.r18 = sigcode;
+      state->basic.r19 = (int) scp;
+    }
+  else
+    {
+      state->basic.pc = (int) &&trampoline;
+      state->basic.r29 = (int) sigsp;
+      state->basic.r4 = signo;
+      state->basic.r5 = sigcode;
+      state->basic.r6 = (int) scp;
+    }
+
+  /* We pass the handler function to the trampoline code in at ($1).  */
+  state->basic.r1 = (int) handler;
+  /* In the callee-saved register s0 ($16), we save the SCP value to pass
+     to __sigreturn after the handler returns.  */
+  state->basic.r16 = (int) scp;
+
+  return scp;
+
+  /* The trampoline code follows.  This is not actually executed as part of
+     this function, it is just convenient to write it that way.  */
+
+ rpc_wait_trampoline:
+  /* This is the entry point when we have an RPC reply message to receive
+     before running the handler.  The MACH_MSG_SEND bit has already been
+     cleared in the OPTION argument in our registers.  For our convenience,
+     $3 points to the sc_gpr[1] member of the sigcontext (saved v0 ($2)).  */
+  asm volatile
+    (".set noat; .set noreorder; .set nomacro\n"
+     /* Retry the interrupted mach_msg system call.  */
+     "li $2, -25\n"		/* mach_msg_trap */
+     "syscall\n"
+     /* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED.  But
+	now the message receive has completed and the original caller of
+	the RPC (i.e. the code running when the signal arrived) needs to
+	see the final return value of the message receive in v0.  So
+	store the new v0 value into the sc_gpr[1] member of the sigcontext
+	(whose address is in v1 to make this code simpler).  */
+     "sw $2, ($3)\n"
+     /* Since the argument registers needed to have the mach_msg_trap
+	arguments, we've stored the arguments to the handler function
+	in registers s1..s3 ($17..$19).  */
+     "move $4, $17\n"
+     "move $5, $18\n"
+     "move $6, $19\n");
+
+ trampoline:
+  /* Entry point for running the handler normally.  The arguments to the
+     handler function are already in the standard registers:
+
+       a0	SIGNO
+       a1	SIGCODE
+       a2	SCP
+     */
+  asm volatile
+    ("jal $1; nop\n"		/* Call the handler function.  */
+     /* Call __sigreturn (SCP); this cannot return.  */
+     "j %0\n"
+     "move $4, $16"		/* Set up arg from saved SCP in delay slot.  */
+     : : "i" (&__sigreturn));
+
+  /* NOTREACHED */
+  asm volatile (".set reorder; .set at; .set macro");
+
+  return NULL;
+}
+
+/* STATE describes a thread that had intr_port set (meaning it was inside
+   HURD_EINTR_RPC), after it has been thread_abort'd.  It it looks to have
+   just completed a mach_msg_trap system call that returned
+   MACH_RCV_INTERRUPTED, return nonzero and set *PORT to the receive right
+   being waited on.  */
+int
+_hurdsig_rcv_interrupted_p (struct machine_thread_all_state *state,
+			    mach_port_t *port)
+{
+  const unsigned int *const pc = (void *) state->basic.pc;
+
+  if (_hurdsig_catch_fault (SIGSEGV))
+    assert (_hurdsig_fault_sigcode == (long int) pc);
+  else
+    {
+      if (state->basic.r2 == MACH_RCV_INTERRUPTED &&
+	  pc[-1] == 0xc)	/* syscall */
+	{
+	  /* We did just return from a mach_msg_trap system call
+	     doing a message receive that was interrupted.
+	     Examine the parameters to find the receive right.  */
+	  struct mach_msg_trap_args *args = (void *) &state->basic.r4;
+
+	  *port = args->rcv_name;
+	  return 1;
+	}
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/mkdir.c b/sysdeps/mach/hurd/mkdir.c
new file mode 100644
index 0000000000..d477815994
--- /dev/null
+++ b/sysdeps/mach/hurd/mkdir.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Create a directory named FILE_NAME with protections MODE.  */
+int
+DEFUN(__mkdir, (file_name, mode), CONST char *file_name AND mode_t mode)
+{
+  error_t err;
+  const char *name;
+  file_t parent = __file_name_split (file_name, (char **) &name);
+  if (parent == MACH_PORT_NULL)
+    return -1;
+  err = __dir_mkdir (parent, name, mode);
+  __mach_port_deallocate (__mach_task_self (), parent);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__mkdir, mkdir)
diff --git a/sysdeps/mach/hurd/mknod.c b/sysdeps/mach/hurd/mknod.c
new file mode 100644
index 0000000000..cf1b4d021e
--- /dev/null
+++ b/sysdeps/mach/hurd/mknod.c
@@ -0,0 +1,114 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include "stdio/_itoa.h"
+#include <string.h>
+
+/* Temporary hack; this belongs in a header file, probably types.h. */
+#define major(x) ((int)(((unsigned) (x) >> 8) & 0xff))
+#define minor(x) ((int)((x) & 0xff))
+
+
+/* Create a device file named FILE_NAME, with permission and special bits MODE
+   and device number DEV (which can be constructed from major and minor
+   device numbers with the `makedev' macro above).  */
+int
+DEFUN(__mknod, (file_name, mode, dev),
+      CONST char *file_name AND mode_t mode AND dev_t dev)
+{
+  error_t err;
+  file_t dir, node;
+  char *name;
+  char buf[100], *bp;
+  const char *translator;
+  size_t len;
+
+  if (S_ISCHR (mode))
+    {
+      translator = _HURD_CHRDEV;
+      len = sizeof (_HURD_CHRDEV);
+    }
+  else if (S_ISBLK (mode))
+    {
+      translator = _HURD_BLKDEV;
+      len = sizeof (_HURD_BLKDEV);
+    }
+  else if (S_ISFIFO (mode))
+    {
+      translator = _HURD_FIFO;
+      len = sizeof (_HURD_FIFO);
+    }
+  else
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  
+  if (! S_ISFIFO (mode))
+    {
+      /* We set the translator to "ifmt\0major\0minor\0", where IFMT
+	 depends on the S_IFMT bits of our MODE argument, and MAJOR and
+	 MINOR are ASCII decimal (octal or hex would do as well)
+	 representations of our arguments.  Thus the convention is that
+	 CHRDEV and BLKDEV translators are invoked with two non-switch
+	 arguments, giving the major and minor device numbers in %i format. */
+
+      bp = buf + sizeof (buf);
+      *--bp = '\0';
+      bp = _itoa (minor (dev), bp, 10, 0);
+      *--bp = '\0';
+      bp = _itoa (major (dev), bp, 10, 0);
+      memcpy (bp - len, translator, len);
+      translator = bp - len;
+      len = buf + sizeof (buf) - translator;
+    }
+  
+  dir = __file_name_split (file_name, &name);
+  if (dir == MACH_PORT_NULL)
+    return -1;
+
+  /* Create a new, unlinked node in the target directory.  */
+  err = __dir_mkfile (dir, O_WRITE, mode & ~S_IFMT & _hurd_umask, &node);
+
+  if (! err)
+    /* Set the node's translator to make it a device.  */
+    err = __file_set_translator (node, 
+				 FS_TRANS_EXCL | FS_TRANS_SET,
+				 FS_TRANS_EXCL | FS_TRANS_SET, 0,
+				 translator, len,
+				 MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+
+  if (! err)
+    /* Link the node, now a valid device, into the target directory.  */
+    err = __dir_link (node, dir, name);
+
+  __mach_port_deallocate (__mach_task_self (), dir);
+  __mach_port_deallocate (__mach_task_self (), node);
+
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__mknod, mknod)
diff --git a/sysdeps/mach/hurd/mmap.c b/sysdeps/mach/hurd/mmap.c
new file mode 100644
index 0000000000..e682225ec8
--- /dev/null
+++ b/sysdeps/mach/hurd/mmap.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Map addresses starting near ADDR and extending for LEN bytes.  from
+   OFFSET into the file FD describes according to PROT and FLAGS.  If ADDR
+   is nonzero, it is the desired mapping address.  If the MAP_FIXED bit is
+   set in FLAGS, the mapping will be at ADDR exactly (which must be
+   page-aligned); otherwise the system chooses a convenient nearby address.
+   The return value is the actual mapping address chosen or (caddr_t) -1
+   for errors (in which case `errno' is set).  A successful `mmap' call
+   deallocates any previous mapping for the affected region.  */
+
+caddr_t
+mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+  error_t err;
+  vm_prot_t vmprot;
+  memory_object_t memobj;
+  vm_address_t mapaddr;
+
+  vmprot = VM_PROT_NONE;
+  if (prot & PROT_READ)
+    vmprot |= VM_PROT_READ;
+  if (prot & PROT_WRITE)
+    vmprot |= VM_PROT_WRITE;
+  if (prot & PROT_EXEC)
+    vmprot |= VM_PROT_EXECUTE;
+
+  switch (flags & MAP_TYPE)
+    {
+    default:
+      return (caddr_t) (long int) __hurd_fail (EINVAL);
+
+    case MAP_ANON:
+      memobj = MACH_PORT_NULL;
+      break;
+
+    case MAP_FILE:
+      {
+	mach_port_t robj, wobj;
+	if (err = HURD_DPORT_USE (fd, __io_map (port, &robj, &wobj)))
+	  return (caddr_t) (long int) __hurd_dfail (fd, err);
+	switch (prot & (PROT_READ|PROT_WRITE))
+	  {
+	  case PROT_READ:
+	    memobj = robj;
+	    __mach_port_deallocate (__mach_task_self (), wobj);
+	    break;
+	  case PROT_WRITE:
+	    memobj = wobj;
+	    __mach_port_deallocate (__mach_task_self (), robj);
+	    break;
+	  case PROT_READ|PROT_WRITE:
+	    __mach_port_deallocate (__mach_task_self (), robj);
+	    if (robj == wobj)
+	      memobj = wobj;
+	    else
+	      {
+		__mach_port_deallocate (__mach_task_self (), wobj);
+		return ((caddr_t) (long int)
+			__hurd_fail (EGRATUITOUS)); /* XXX */
+	      }
+	    break;
+	  }
+	break;
+	/* XXX handle MAP_NOEXTEND */
+      }
+    }
+
+  mapaddr = (vm_address_t) addr;
+  err = __vm_map (__mach_task_self (),
+		  &mapaddr, (vm_size_t) len, (vm_address_t) 0,
+		  flags & MAP_FIXED,
+		  memobj, (vm_offset_t) offset,
+		  flags & (MAP_COPY|MAP_PRIVATE),
+		  vmprot, VM_PROT_ALL,
+		  flags & MAP_INHERIT);
+
+  if (memobj != MACH_PORT_NULL)
+    __mach_port_deallocate (__mach_task_self (), memobj);
+
+  return err ? (caddr_t) (long int) __hurd_fail (err) : (caddr_t) mapaddr;
+}
+	
diff --git a/sysdeps/mach/hurd/open.c b/sysdeps/mach/hurd/open.c
new file mode 100644
index 0000000000..0d22e7f36d
--- /dev/null
+++ b/sysdeps/mach/hurd/open.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+   a third argument is the file protection.  */
+int
+DEFUN(__open, (file, oflag), CONST char *file AND int oflag DOTS)
+{
+  mode_t mode;
+  io_t port;
+
+  if (oflag & O_CREAT)
+    {
+      va_list arg;
+      va_start (arg, oflag);
+      mode = va_arg (arg, mode_t);
+      va_end (arg);
+    }
+  else
+    mode = 0;
+
+  port = __file_name_lookup (file, oflag, mode);
+  if (port == MACH_PORT_NULL)
+    return -1;
+
+  return _hurd_intern_fd (port, oflag, 1);
+}
+
+weak_alias (__open, open)
diff --git a/sysdeps/mach/hurd/opendir.c b/sysdeps/mach/hurd/opendir.c
new file mode 100644
index 0000000000..d843da8aeb
--- /dev/null
+++ b/sysdeps/mach/hurd/opendir.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <hurd.h>
+
+
+/* Open a directory stream on NAME.  */
+DIR *
+DEFUN(opendir, (name), CONST char *name)
+{
+  DIR *dirp;
+  file_t port;
+
+  port = __file_name_lookup (name, O_RDONLY, 0);
+  if (port == MACH_PORT_NULL)
+    return NULL;
+
+  /* XXX this port should be deallocated on exec */
+
+  dirp = (DIR *) malloc (sizeof (DIR));
+  if (dirp == NULL)
+    {
+      __mach_port_deallocate (__mach_task_self (), port);
+      return NULL;
+    }    
+
+  dirp->__port = port;
+  dirp->__data = dirp->__ptr = NULL;
+  dirp->__entry_data = dirp->__entry_ptr = 0;
+  dirp->__allocation = 0;
+  dirp->__size = 0;
+
+  return dirp;
+}
diff --git a/sysdeps/mach/hurd/pipe.c b/sysdeps/mach/hurd/pipe.c
new file mode 100644
index 0000000000..07c802f5a0
--- /dev/null
+++ b/sysdeps/mach/hurd/pipe.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <sys/socket.h>
+#include <hurd/socket.h>
+#include <fcntl.h>
+
+/* Create a one-way communication channel (pipe).
+   If successul, two file descriptors are stored in FDS;
+   bytes written on FDS[1] can be read from FDS[0].
+   Returns 0 if successful, -1 if not.  */
+int
+DEFUN(__pipe, (fds), int fds[2])
+{
+  error_t err;
+  socket_t server, sock1, sock2;
+  int d1, d2;
+
+  if (fds == NULL)
+    return __hurd_fail (EINVAL);
+
+  /* Find the local domain socket server.  */
+  server = _hurd_socket_server (PF_LOCAL, 0);
+  if (server == MACH_PORT_NULL)
+    return -1;
+
+  /* Create two local domain sockets and connect them together.  */
+
+  err = __socket_create (server, SOCK_STREAM, 0, &sock1);
+  if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
+    {
+      /* On the first use of the socket server during the operation,
+	 allow for the old server port dying.  */
+      server = _hurd_socket_server (PF_LOCAL, 1);
+      if (server == MACH_PORT_NULL)
+	return -1;
+      err = __socket_create (server, SOCK_STREAM, 0, &sock1);
+    }
+  if (err)
+    return __hurd_fail (err);
+  if (err = __socket_create (server, SOCK_STREAM, 0, &sock2))
+    {
+      __mach_port_deallocate (__mach_task_self (), sock1);
+      return __hurd_fail (err);
+    }
+  if (err = __socket_connect2 (sock1, sock2))
+    {
+      __mach_port_deallocate (__mach_task_self (), sock1);
+      __mach_port_deallocate (__mach_task_self (), sock2);
+      return __hurd_fail (err);
+    }
+
+  /* Shut down the unused sides of the sockets.  */
+  __socket_shutdown (sock1, 1);
+  __socket_shutdown (sock2, 0);
+
+  /* Put the sockets into file descriptors.  */
+
+  d1 = _hurd_intern_fd (sock1, O_IGNORE_CTTY, 1);
+  if (d1 < 0)
+    {
+      __mach_port_deallocate (__mach_task_self (), sock2);
+      return -1;
+    }
+  d2 = _hurd_intern_fd (sock2, O_IGNORE_CTTY, 1);
+  if (d2 < 0)
+    {
+      err = errno;
+      (void) close (d1);
+      return __hurd_fail (err);
+    }
+
+  fds[0] = d1;
+  fds[1] = d2;
+  return 0;
+}
+
+weak_alias (__pipe, pipe)
diff --git a/sysdeps/mach/hurd/ptrace.c b/sysdeps/mach/hurd/ptrace.c
new file mode 100644
index 0000000000..3d8558734f
--- /dev/null
+++ b/sysdeps/mach/hurd/ptrace.c
@@ -0,0 +1,392 @@
+/* Process tracing interface `ptrace' for GNU Hurd.
+Copyright (C) 1991, 1992, 1993, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+#include <thread_state.h>
+
+/* Perform process tracing functions.  REQUEST is one of the values
+   in <sys/ptrace.h>, and determines the action to be taken.
+   For all requests except PTRACE_TRACEME, PID specifies the process to be
+   traced.
+
+   PID and the other arguments described above for the various requests should
+   appear (those that are used for the particular request) as:
+     pid_t PID, void *ADDR, int DATA, void *ADDR2
+   after PID.  */
+int
+ptrace (enum __ptrace_request request, ... )
+{
+  pid_t pid;
+  void *addr, *addr2;
+  natural_t data;
+  va_list ap;
+
+  /* Read data from PID's address space, from ADDR for DATA bytes.  */
+  error_t read_data (task_t task, vm_address_t *ourpage, vm_size_t *size)
+    {
+      /* Read the pages containing the addressed range.  */
+      error_t err;
+      *size = round_page (addr + data) - trunc_page (addr);
+      err = __vm_read (task, trunc_page (addr), *size, ourpage, size);
+      return err;
+    }
+
+  /* Fetch the thread port for PID's user thread.  */
+  error_t fetch_user_thread (task_t task, thread_t *thread)
+    {
+      thread_t threadbuf[3], *threads = threadbuf;
+      mach_msg_type_number_t nthreads = 3, i;
+      error_t err = __task_threads (task, &threads, &nthreads);
+      if (err)
+	return err;
+      if (nthreads == 0)
+	return EINVAL;
+      *thread = threads[0];	/* Assume user thread is first.  */
+      for (i = 1; i < nthreads; ++i)
+	__mach_port_deallocate (__mach_task_self (), threads[i]);
+      if (threads != threadbuf)
+	__vm_deallocate (__mach_task_self (),
+			 (vm_address_t) threads, nthreads * sizeof threads[0]);
+      return 0;
+    }
+
+  /* Fetch a thread state structure from PID and store it at ADDR.  */
+  int get_regs (int flavor, mach_msg_type_number_t count)
+    {
+      error_t err;
+      task_t task = __pid2task (pid);
+      thread_t thread;
+      if (task == MACH_PORT_NULL)
+	return -1;
+      err = fetch_user_thread (task, &thread);
+      __mach_port_deallocate (__mach_task_self (), task);
+      if (!err)
+	err = __thread_get_state (thread, flavor, addr, &count);
+      __mach_port_deallocate (__mach_task_self (), thread);
+      return err ? __hurd_fail (err) : 0;
+    }
+
+
+  switch (request)
+    {
+    case PTRACE_TRACEME:
+      /* Make this process be traced.  */
+      _hurd_exec_flags |= EXEC_TRACED;
+      break;
+
+    case PTRACE_CONT:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      data = va_arg (ap, int);
+      va_end (ap);
+      {
+	/* Send a DATA signal to PID, telling it to take the signal
+	   normally even if it's traced.  */
+	error_t err; task_t task = __pid2task (pid);
+	if (task == MACH_PORT_NULL)
+	  return -1;
+	if (data == SIGKILL)
+	  err = __task_terminate (task);
+	else
+	  {
+	    mach_port_t msgport;
+	    err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport));
+
+	    if (!err && addr != (void *) 1)
+	      {
+		/* Move the user thread's PC to ADDR.  */
+		thread_t thread;
+		err = fetch_user_thread (task, &thread);
+		if (!err)
+		  {
+		    struct machine_thread_state state;
+		    mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
+		    err = __thread_get_state (thread,
+					      MACHINE_THREAD_STATE_FLAVOR,
+					      (natural_t *) &state, &count);
+		    if (!err)
+		      {
+			MACHINE_THREAD_STATE_SET_PC (&state, addr);
+			err = __thread_set_state (thread,
+						  MACHINE_THREAD_STATE_FLAVOR,
+						  (natural_t *) &state, count);
+		      }
+		    
+		  }
+		__mach_port_deallocate (__mach_task_self (), thread);
+	      }
+
+	    if (! err)
+	      /* Tell the process to take the signal (or just resume if 0).  */
+	      err = __msg_sig_post_untraced (msgport, data, task);
+	    __mach_port_deallocate (__mach_task_self (), msgport);
+	  }
+	__mach_port_deallocate (__mach_task_self (), task);
+	return err ? __hurd_fail (err) : 0;
+      }
+
+    case PTRACE_KILL:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      va_end (ap);
+      /* SIGKILL always just terminates the task,
+	 so normal kill is just the same when traced.  */
+      return kill (pid, SIGKILL);
+
+    case PTRACE_SINGLESTEP:
+      /* This is a machine-dependent kernel RPC on
+	 machines that support it.  Punt.  */
+      return EOPNOTSUPP;
+
+    case PTRACE_ATTACH:
+    case PTRACE_DETACH:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      va_end (ap);
+      {
+	/* Tell PID to set or clear its trace bit.  */
+	error_t err;
+	mach_port_t msgport;
+	task_t task = __pid2task (pid);
+	if (task == MACH_PORT_NULL)
+	  return -1;
+	err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport));
+	if (! err)
+	  {
+	    err = (request == PTRACE_ATTACH ?
+		   __msg_set_some_exec_flags :
+		   __msg_clear_some_exec_flags) (msgport, task, EXEC_TRACED);
+#ifdef notyet			/* XXX */
+	    if (! err)
+	      /* Request (or request an end to) SIGCHLD notification
+		 when PID stops or dies, and proc_wait working on PID.  */
+	      err = __USEPORT (PROC,
+			       __proc_trace_pid (port, pid,
+						 request == PTRACE_ATTACH));
+#endif
+	    if (! err)
+	      {
+		if (request == PTRACE_ATTACH)
+		  /* Now stop the process.  */
+		  err = __msg_sig_post (msgport, SIGSTOP, task);
+		else
+		  /* Resume the process from tracing stop.  */
+		  err = __msg_sig_post_untraced (msgport, 0, task);
+	      }
+	    __mach_port_deallocate (__mach_task_self (), msgport);
+	  }
+	__mach_port_deallocate (__mach_task_self (), task);
+	return err ? __hurd_fail (err) : 0;
+      }      
+
+    case PTRACE_PEEKTEXT:
+    case PTRACE_PEEKDATA:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      va_end (ap);
+      {
+	/* Read the page (or two pages, if the word lies on a boundary)
+	   containing the addressed word.  */
+	error_t err;
+	vm_address_t ourpage;
+	vm_size_t size;
+	natural_t word;
+	task_t task = __pid2task (pid);
+	if (task == MACH_PORT_NULL)
+	  return -1;
+	data = sizeof word;
+	ourpage = 0;
+	size = 0;
+	err = read_data (task, &ourpage, &size);
+	__mach_port_deallocate (__mach_task_self (), task);
+	if (err)
+	  return __hurd_fail (err);
+	word = *(natural_t *) ((vm_address_t) addr - trunc_page (addr)
+			       + ourpage);
+	__vm_deallocate (__mach_task_self (), ourpage, size);
+	return word;
+      }
+
+    case PTRACE_PEEKUSER:
+    case PTRACE_POKEUSER:
+      /* U area, what's that?  */
+      return EOPNOTSUPP;
+
+    case PTRACE_GETREGS:
+    case PTRACE_SETREGS:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      va_end (ap);
+      return get_regs (MACHINE_THREAD_STATE_FLAVOR,
+		       MACHINE_THREAD_STATE_COUNT);
+
+    case PTRACE_GETFPREGS:
+    case PTRACE_SETFPREGS:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      va_end (ap);
+#ifdef MACHINE_THREAD_FLOAT_STATE_FLAVOR
+      return get_regs (MACHINE_THREAD_FLOAT_STATE_FLAVOR,
+		       MACHINE_THREAD_FLOAT_STATE_COUNT);
+#else
+      return EOPNOTSUPP;
+#endif
+
+    case PTRACE_GETFPAREGS:
+    case PTRACE_SETFPAREGS:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      va_end (ap);
+#ifdef MACHINE_THREAD_FPA_STATE_FLAVOR
+      return get_regs (MACHINE_THREAD_FPA_STATE_FLAVOR,
+		       MACHINE_THREAD_FPA_STATE_COUNT);
+#else
+      return EOPNOTSUPP;
+#endif
+
+    case PTRACE_POKETEXT:
+    case PTRACE_POKEDATA:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      data = va_arg (ap, int);
+      va_end (ap);
+      {
+	/* Read the page (or two pages, if the word lies on a boundary)
+	   containing the addressed word.  */
+	error_t err;
+	vm_address_t ourpage;
+	vm_size_t size;
+	task_t task = __pid2task (pid);
+	if (task == MACH_PORT_NULL)
+	  return -1;
+	data = sizeof (natural_t);
+	ourpage = 0;
+	size = 0;
+	err = read_data (task, &ourpage, &size);
+
+	if (!err)
+	  {
+	    /* Now modify the specified word and write the page back.  */
+	    *(natural_t *) ((vm_address_t) addr - trunc_page (addr)
+			    + ourpage) = data;
+	    err = __vm_write (task, trunc_page (addr), ourpage, size);
+	    __vm_deallocate (__mach_task_self (), ourpage, size);
+	  }
+
+	__mach_port_deallocate (__mach_task_self (), task);
+	return err ? __hurd_fail (err) : 0;
+      }
+
+    case PTRACE_READDATA:
+    case PTRACE_READTEXT:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      data = va_arg (ap, int);
+      addr2 = va_arg (ap, void *);
+      va_end (ap);
+      {
+	error_t err;
+	vm_address_t ourpage;
+	vm_size_t size;
+	task_t task = __pid2task (pid);
+	if (task == MACH_PORT_NULL)
+	  return -1;
+	if (((vm_address_t) addr2 + data) % __vm_page_size == 0)
+	  {
+	    /* Perhaps we can write directly to the user's buffer.  */
+	    ourpage = (vm_address_t) addr2;
+	    size = data;
+	  }
+	else
+	  {
+	    ourpage = 0;
+	    size = 0;
+	  }
+	err = read_data (task, &ourpage, &size);
+	__mach_port_deallocate (__mach_task_self (), task);
+	if (!err && ourpage != (vm_address_t) addr2)
+	  {
+	    memcpy (addr2, (void *) ourpage, data);
+	    __vm_deallocate (__mach_task_self (), ourpage, size);
+	  }
+	return err ? __hurd_fail (err) : 0;
+      }
+
+    case PTRACE_WRITEDATA:
+    case PTRACE_WRITETEXT:
+      va_start (ap, request);
+      pid = va_arg (ap, pid_t);
+      addr = va_arg (ap, void *);
+      data = va_arg (ap, int);
+      addr2 = va_arg (ap, void *);
+      va_end (ap);
+      {
+	error_t err;
+	vm_address_t ourpage;
+	vm_size_t size;
+	task_t task = __pid2task (pid);
+	if (task == MACH_PORT_NULL)
+	  return -1;
+	if ((vm_address_t) addr % __vm_page_size == 0 &&
+	    (vm_address_t) data % __vm_page_size == 0)
+	  {
+	    /* Writing whole pages; can go directly from the user's buffer.  */
+	    ourpage = (vm_address_t) addr2;
+	    size = data;
+	    err = 0;
+	  }
+	else
+	  {
+	    /* Read the task's pages and modify our own copy.  */
+	    ourpage = 0;
+	    size = 0;
+	    err = read_data (task, &ourpage, &size);
+	    if (!err)
+	      memcpy ((void *) ((vm_address_t) addr - trunc_page (addr)
+				+ ourpage),
+		      addr2,
+		      data);
+	  }
+	if (!err)
+	  /* Write back the modified pages.  */
+	  err = __vm_write (task, trunc_page (addr), ourpage, size);
+	__mach_port_deallocate (__mach_task_self (), task);
+	return err ? __hurd_fail (err) : 0;
+      }
+
+    default:
+      errno = EINVAL;
+      return -1;
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/read.c b/sysdeps/mach/hurd/read.c
new file mode 100644
index 0000000000..c7fdaf8a4d
--- /dev/null
+++ b/sysdeps/mach/hurd/read.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+/* Read NBYTES into BUF from FD.  Return the number read or -1.  */
+ssize_t
+DEFUN(__read, (fd, buf, nbytes),
+      int fd AND PTR buf AND size_t nbytes)
+{
+  error_t err = HURD_FD_USE (fd, _hurd_fd_read (descriptor, buf, &nbytes));
+  return err ? __hurd_dfail (fd, err) : nbytes;
+}
+
+weak_alias (__read, read)
diff --git a/sysdeps/mach/hurd/readdir.c b/sysdeps/mach/hurd/readdir.c
new file mode 100644
index 0000000000..185aeee2b1
--- /dev/null
+++ b/sysdeps/mach/hurd/readdir.c
@@ -0,0 +1,90 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+
+
+/* Read a directory entry from DIRP.  */
+struct dirent *
+DEFUN(readdir, (dirp), DIR *dirp)
+{
+  struct dirent *dp;
+
+  if (dirp == NULL)
+    {
+      errno = EINVAL;
+      return NULL;
+    }
+
+  do
+    {
+      if (dirp->__ptr - dirp->__data >= dirp->__size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  char *data = dirp->__data;
+	  int nentries;
+	  error_t err;
+
+	  if (err = __dir_readdir (dirp->__port, &data, &dirp->__size,
+				   dirp->__entry_ptr, -1, 0, &nentries))
+	    return __hurd_fail (err), NULL;
+
+	  /* DATA now corresponds to entry index DIRP->__entry_ptr.  */
+	  dirp->__entry_data = dirp->__entry_ptr;
+
+	  if (data != dirp->__data)
+	    {
+	      /* The data was passed out of line, so our old buffer is no
+		 longer useful.  Deallocate the old buffer and reset our
+		 information for the new buffer.  */
+	      __vm_deallocate (__mach_task_self (),
+			       (vm_address_t) dirp->__data,
+			       dirp->__allocation);
+	      dirp->__data = data;
+	      dirp->__allocation = round_page (dirp->__size);
+	    }
+
+	  /* Reset the pointer into the buffer.  */
+	  dirp->__ptr = dirp->__data;
+
+	  if (nentries == 0)
+	    /* End of file.  */
+	    return NULL;
+
+	  /* We trust the filesystem to return correct data and so we
+	     ignore NENTRIES.  */
+	}
+
+      dp = (struct dirent *) dirp->__ptr;
+      dirp->__ptr += dp->d_reclen;
+      ++dirp->__entry_ptr;
+
+      /* Loop to ignore deleted files.  */
+    } while (dp->d_fileno == 0);
+
+  return dp;
+}
diff --git a/sysdeps/mach/hurd/readlink.c b/sysdeps/mach/hurd/readlink.c
new file mode 100644
index 0000000000..2f51e200b5
--- /dev/null
+++ b/sysdeps/mach/hurd/readlink.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+#include <string.h>
+
+/* Read the contents of the symbolic link FILE_NAME into no more than
+   LEN bytes of BUF.  The contents are not null-terminated.
+   Returns the number of characters read, or -1 for errors.  */
+ssize_t
+DEFUN(__readlink, (file_name, buf, len),
+      CONST char *file_name AND char *buf AND size_t len)
+{
+  error_t err;
+  file_t file;
+  char mybuf[2048], *transp = mybuf;
+  mach_msg_type_number_t translen = sizeof (mybuf);
+
+  file = __file_name_lookup (file_name, O_NOTRANS, 0);
+  if (file == MACH_PORT_NULL)
+    return -1;
+
+  err = __file_get_translator (file, &transp, &translen);
+  __mach_port_deallocate (__mach_task_self (), file);
+
+  if (err)
+    return __hurd_fail (err);
+
+  if (translen < sizeof (_HURD_SYMLINK) ||
+      memcmp (transp, _HURD_SYMLINK, sizeof (_HURD_SYMLINK)))
+    /* The file is not actually a symlink.  */
+    err = EINVAL;
+  else
+    {
+      /* This is a symlink; its translator is "/hurd/symlink\0target\0".  */
+      if (len >= translen - sizeof (_HURD_SYMLINK))
+	{
+	  len = translen - sizeof (_HURD_SYMLINK);
+	  if (transp[translen - 1] == '\0')
+	    /* Remove the null terminator.  */
+	    --len;
+	}
+      if (buf == NULL)
+	/* This call is just to find out how large a buffer is required.  */
+	len = translen - sizeof (_HURD_SYMLINK) - 1;
+      else
+	/* Copy into the user's buffer.  */
+	memcpy (buf, transp + sizeof (_HURD_SYMLINK), len);
+    }
+
+  if (transp != mybuf)
+    __vm_deallocate (__mach_task_self (), (vm_address_t) transp, translen);
+
+  return err ? __hurd_fail (err) : len;
+}
+
+weak_alias (__readlink, readlink)
diff --git a/sysdeps/mach/hurd/reboot.c b/sysdeps/mach/hurd/reboot.c
new file mode 100644
index 0000000000..80356fdf5a
--- /dev/null
+++ b/sysdeps/mach/hurd/reboot.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/startup.h>
+
+/* Reboot the system.  */
+int
+DEFUN(reboot, (howto), int howto)
+{
+  error_t err;
+  startup_t init;
+  mach_port_t hostpriv, devmaster;
+
+  if (err = __USEPORT (PROC, __proc_getprivports (port,
+						  &hostpriv, &devmaster)))
+    return __hurd_fail (err);
+  __mach_port_deallocate (__mach_task_self (), devmaster);
+
+  err = __USEPORT (PROC, __proc_getmsgport (port, 1, &init));
+  if (!err)
+    {
+      err = __startup_reboot (init, hostpriv, howto);
+      __mach_port_deallocate (__mach_task_self (), init);
+    }
+
+  __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+  if (err)
+    return __hurd_fail (err);
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/recv.c b/sysdeps/mach/hurd/recv.c
new file mode 100644
index 0000000000..7d06919c4b
--- /dev/null
+++ b/sysdeps/mach/hurd/recv.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1994 Fremach_msg_type_number_t 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <string.h>
+
+/* Read N bytes into BUF from socket FD.
+   Returns the number read or -1 for errors.  */
+int
+DEFUN(recv, (fd, buf, n, flags),
+      int fd AND PTR buf AND size_t n AND int flags)
+{
+  error_t err;
+  mach_port_t addrport;
+  char *bufp = buf;
+  mach_msg_type_number_t nread = n;
+  mach_port_t *ports;
+  mach_msg_type_number_t nports;
+  char *cdata = NULL;
+  mach_msg_type_number_t clen = 0;
+
+  if (err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport,
+					       flags, &bufp, &nread,
+					       &ports, &nports,
+					       &cdata, &clen,
+					       &flags,
+					       n)))
+    return __hurd_dfail (fd, err);
+
+  __mach_port_deallocate (__mach_task_self (), addrport);
+  __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
+
+  if (bufp != buf)
+    {
+      memcpy (buf, bufp, nread);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) bufp, nread);
+    }
+
+  return nread;
+}
diff --git a/sysdeps/mach/hurd/recvfrom.c b/sysdeps/mach/hurd/recvfrom.c
new file mode 100644
index 0000000000..09d45c7cc8
--- /dev/null
+++ b/sysdeps/mach/hurd/recvfrom.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <hurd/socket.h>
+#include <string.h>
+
+/* Read N bytes into BUF through socket FD from peer
+   at address ADDR (which is ADDR_LEN bytes long).
+   Returns the number read or -1 for errors.  */
+int
+DEFUN(recvfrom, (fd, buf, n, flags, addr, addr_len),
+      int fd AND PTR buf AND size_t n AND int flags AND
+      struct sockaddr *addr AND size_t *addr_len)
+{
+  error_t err;
+  mach_port_t addrport;
+  char *bufp = buf;
+  mach_msg_type_number_t nread = n;
+  mach_port_t *ports;
+  mach_msg_type_number_t nports;
+  char *cdata = NULL;
+  mach_msg_type_number_t clen = 0;
+
+  if (err = HURD_DPORT_USE (fd, __socket_recv (port, &addrport,
+					       flags, &bufp, &nread,
+					       &ports, &nports,
+					       &cdata, &clen,
+					       &flags,
+					       n)))
+    return __hurd_dfail (fd, err);
+
+  /* Get address data for the returned address port.  */
+  {
+    char *buf = (char *) addr;
+    mach_msg_type_number_t buflen = *addr_len;
+    int type;
+
+    err = __socket_whatis_address (addrport, &type, &buf, &buflen);
+    __mach_port_deallocate (__mach_task_self (), addrport);
+    if (err)
+      return __hurd_dfail (fd, err);
+
+    if (buf != (char *) addr)
+      {
+	if (*addr_len < buflen)
+	  *addr_len = buflen;
+	memcpy (addr, buf, *addr_len);
+	__vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);
+      }
+
+    addr->sa_family = type;
+  }
+
+  /* Toss control data; we don't care.  */
+  __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen);
+
+  if (bufp != buf)
+    {
+      memcpy (buf, bufp, nread);
+      __vm_deallocate (__mach_task_self (), (vm_address_t) bufp, nread);
+    }
+
+  return nread;
+}
+
diff --git a/sysdeps/mach/hurd/rename.c b/sysdeps/mach/hurd/rename.c
new file mode 100644
index 0000000000..63efbfb43f
--- /dev/null
+++ b/sysdeps/mach/hurd/rename.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stdio.h>
+#include <hurd.h>
+
+/* Rename the file OLD to NEW.  */
+int
+DEFUN(rename, (old, new), CONST char *old AND CONST char *new)
+{
+  error_t err;
+  file_t olddir, newdir;
+  const char *oldname, *newname;
+
+  olddir = __file_name_split (old, (char **) &oldname);
+  if (olddir == MACH_PORT_NULL)
+    return -1;
+  newdir = __file_name_split (new, (char **) &newname);
+  if (newdir == MACH_PORT_NULL)
+    {
+       __mach_port_deallocate (__mach_task_self (), olddir);
+      return -1;
+    }
+
+  err = __dir_rename (olddir, oldname, newdir, newname);
+  __mach_port_deallocate (__mach_task_self (), olddir);
+  __mach_port_deallocate (__mach_task_self (), newdir);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/rewinddir.c b/sysdeps/mach/hurd/rewinddir.c
new file mode 100644
index 0000000000..66a11d619f
--- /dev/null
+++ b/sysdeps/mach/hurd/rewinddir.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+/* Rewind DIRP to the beginning of the directory.  */
+void
+DEFUN(rewinddir, (dirp), DIR *dirp)
+{
+  seekdir (dirp, (off_t) 0L);
+}
diff --git a/sysdeps/mach/hurd/rmdir.c b/sysdeps/mach/hurd/rmdir.c
new file mode 100644
index 0000000000..13a199f5ae
--- /dev/null
+++ b/sysdeps/mach/hurd/rmdir.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Remove the directory FILE_NAME.  */
+int
+DEFUN(__rmdir, (file_name), CONST char *file_name)
+{
+  error_t err;
+  const char *name;
+  file_t parent = __file_name_split (file_name, (char **) &name);
+  if (parent == MACH_PORT_NULL)
+    return -1;
+  err = __dir_rmdir (parent, name);
+  __mach_port_deallocate (__mach_task_self (), parent);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__rmdir, rmdir)
diff --git a/sysdeps/mach/hurd/sbrk.c b/sysdeps/mach/hurd/sbrk.c
new file mode 100644
index 0000000000..855cab8a60
--- /dev/null
+++ b/sysdeps/mach/hurd/sbrk.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <hurd.h>
+
+/* Extend the process's data space by INCREMENT.
+   If INCREMENT is negative, shrink data space by - INCREMENT.
+   Return the address of the start of the new data space, or -1 for errors.  */
+PTR
+DEFUN(__sbrk, (increment), int increment)
+{
+  PTR result;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_brk_lock);
+  result = (PTR) _hurd_brk;
+  if (increment != 0 && _hurd_set_brk (_hurd_brk + increment) < 0)
+    result = (PTR) -1;
+  __mutex_unlock (&_hurd_brk_lock);
+  HURD_CRITICAL_END;
+
+  return result;
+}
+
+weak_alias (__sbrk, sbrk)
diff --git a/sysdeps/mach/hurd/seekdir.c b/sysdeps/mach/hurd/seekdir.c
new file mode 100644
index 0000000000..9f585eba63
--- /dev/null
+++ b/sysdeps/mach/hurd/seekdir.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+
+/* Seek to position POS in DIRP.  */
+void
+DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos)
+{
+  /* Change our entry index pointer to POS and discard any data already
+     read.  The next `readdir' call will notice the empty block and read
+     anew from the location in DIRP->__entry_ptr and reset the other state
+     variables.  */
+  dirp->__entry_ptr = pos;
+  dirp->__size = 0;
+}
diff --git a/sysdeps/mach/hurd/select.c b/sysdeps/mach/hurd/select.c
new file mode 100644
index 0000000000..d1c5913cb8
--- /dev/null
+++ b/sysdeps/mach/hurd/select.c
@@ -0,0 +1,275 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
+   readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
+   (if not NULL) for exceptional conditions.  If TIMEOUT is not NULL, time out
+   after waiting the interval specified therein.  Returns the number of ready
+   descriptors, or -1 for errors.  */
+int
+DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
+      int nfds AND fd_set *readfds AND fd_set *writefds AND
+      fd_set *exceptfds AND struct timeval *timeout)
+{
+  int i;
+  mach_port_t port;
+  int got;
+  int *types;
+  struct hurd_userlink *ulink;
+  mach_port_t *ports;
+  struct hurd_fd **cells;
+  error_t err;
+  fd_set rfds, wfds, xfds;
+  int firstfd, lastfd;
+  mach_msg_timeout_t to = (timeout != NULL ?
+			   (timeout->tv_sec * 1000 +
+			    timeout->tv_usec / 1000) :
+			   0);
+
+  /* Use local copies so we can't crash from user bogosity.  */
+  if (readfds == NULL)
+    FD_ZERO (&rfds);
+  else
+    rfds = *readfds;
+  if (writefds == NULL)
+    FD_ZERO (&wfds);
+  else
+    wfds = *writefds;
+  if (exceptfds == NULL)
+    FD_ZERO (&xfds);
+  else
+    xfds = *exceptfds;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_dtable_lock);
+
+  if (nfds > _hurd_dtablesize)
+    nfds = _hurd_dtablesize;
+
+  /* Collect the ports for interesting FDs.  */
+  cells = __alloca (nfds * sizeof (*cells));
+  ports = __alloca (nfds * sizeof (*ports));
+  types = __alloca (nfds * sizeof (*types));
+  ulink = __alloca (nfds * sizeof (*ulink));
+  firstfd = lastfd = -1;
+  for (i = 0; i < nfds; ++i)
+    {
+      int type = 0;
+      if (readfds != NULL && FD_ISSET (i, &rfds))
+	type |= SELECT_READ;
+      if (writefds != NULL && FD_ISSET (i, &wfds))
+	type |= SELECT_WRITE;
+      if (exceptfds != NULL && FD_ISSET (i, &xfds))
+	type |= SELECT_URG;
+      types[i] = type;
+      if (type)
+	{
+	  cells[i] = _hurd_dtable[i];
+	  ports[i] = _hurd_port_get (&cells[i]->port, &ulink[i]);
+	  if (ports[i] == MACH_PORT_NULL)
+	    {
+	      /* If one descriptor is bogus, we fail completely.  */
+	      while (i-- > 0)
+		_hurd_port_free (&cells[i]->port, &ulink[i], ports[i]);
+	      errno = EBADF;
+	      break;
+	    }
+	  lastfd = i;
+	  if (firstfd == -1)
+	    firstfd = i;
+	}
+    }
+
+  __mutex_unlock (&_hurd_dtable_lock);
+  HURD_CRITICAL_END;
+
+  if (i < nfds)
+    return -1;
+
+  /* Get a port to receive the io_select_reply messages on.  */
+  port = __mach_reply_port ();
+
+  /* Send them all io_select request messages.  */
+  got = 0;
+  err = 0;
+  for (i = firstfd; i <= lastfd; ++i)
+    if (types[i])
+      {
+	if (!err)
+	  {
+	    int tag = i;
+	    err = __io_select (ports[i], port,
+			       /* Poll for each but the last.  */
+			       (i == lastfd && got == 0) ? to : 0,
+			       &types[i], &tag);
+	    if (!err)
+	      {
+		if (tag != i)
+		  err = EGRATUITOUS;
+		else if (types[i] & (SELECT_READ|SELECT_URG|SELECT_WRITE))
+		  ++got;
+	      }
+	  }
+	_hurd_port_free (&cells[i]->port, &ulink[i], ports[i]);
+      }
+
+  /* Now wait for reply messages.  */
+  if (!err && got == 0 && port != MACH_PORT_NULL)
+    {
+      /* Now wait for io_select_reply messages on PORT,
+	 timing out as appropriate.  */
+
+      union
+	{
+	  mach_msg_header_t head;
+	  struct
+	    {
+	      mach_msg_header_t head;
+	      mach_msg_type_t err_type;
+	      error_t err;
+	    } error;
+	  struct
+	    {
+	      mach_msg_header_t head;
+	      mach_msg_type_t err_type;
+	      error_t err;
+	      mach_msg_type_t result_type;
+	      int result;
+	      mach_msg_type_t tag_type;
+	      int tag;
+	    } success;
+	} msg;
+      mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
+      error_t msgerr;
+      while ((msgerr = __mach_msg (&msg.head,
+				   MACH_RCV_MSG | options,
+				   sizeof msg, 0, port, to,
+				   MACH_PORT_NULL)) == MACH_MSG_SUCCESS)
+	{
+	  /* We got a message.  Decode it.  */
+#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
+	  const mach_msg_type_t inttype =
+	    { MACH_MSG_TYPE_INTEGER_32, 32, 1, 1, 0, 0 };
+	  if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID &&
+	      msg.head.msgh_size >= sizeof msg.error &&
+	      !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&
+	      *(int *) &msg.error.err_type == *(int *) &inttype)
+	    {
+	      /* This is a properly formatted message so far.
+		 See if it is a success or a failure.  */
+	      if (msg.error.err)
+		{
+		  err = msg.error.err;
+		  if (msg.head.msgh_size != sizeof msg.error)
+		    __mach_msg_destroy (&msg);
+		}
+	      else if (msg.head.msgh_size != sizeof msg.success ||
+		       *(int *) &msg.success.tag_type != *(int *) &inttype ||
+		       *(int *) &msg.success.result_type != *(int *) &inttype)
+		__mach_msg_destroy (&msg);
+	      else if ((msg.success.result &
+			(SELECT_READ|SELECT_WRITE|SELECT_URG)) == 0 ||
+		       msg.success.tag < firstfd || msg.success.tag > lastfd)
+		err = EGRATUITOUS;
+	      else
+		{
+		  /* This is a winning io_select_reply message!
+		     Record the readiness it indicates and send a reply.  */
+		  if (types[msg.success.tag] == 0)
+		    /* This descriptor is ready and it was not before,
+		       so we increment our count of ready descriptors.  */
+		    ++got;
+		  types[msg.success.tag] |= msg.success.result;
+		}
+	    }
+
+	  if (msg.head.msgh_remote_port != MACH_PORT_NULL)
+	    __mach_port_deallocate (__mach_task_self (),
+				    msg.head.msgh_remote_port);
+
+	  if (got || err == EINTR)
+	    {
+	      /* Poll for another message.  */
+	      to = 0;
+	      options |= MACH_RCV_TIMEOUT;
+	    }
+	}
+
+    if (err == MACH_RCV_TIMED_OUT)
+      /* This is the normal value for ERR.  We might have timed out and
+         read no messages.  Otherwise, after receiving the first message,
+         we poll for more messages.  We receive with a timeout of 0 to
+         effect a poll, so ERR is MACH_RCV_TIMED_OUT when the poll finds no
+         message waiting.  */
+      err = 0;
+
+      if (got && err == EINTR)
+	/* Some calls were interrupted, but at least one descriptor
+	   is known to be ready now, so we will return success.  */
+	err = 0;
+    }
+
+  if (port != MACH_PORT_NULL)
+    /* We must destroy the port if we made some select requests
+       that might send notification on that port after we no longer care.
+       If the port were reused, that notification could confuse the next
+       select call to use the port.  The notification might be valid,
+       but the descriptor may have changed to a different server.  */
+    __mach_port_destroy (__mach_task_self (), port);
+
+  if (timeout && got == 0 && err == MACH_RCV_TIMED_OUT)
+    /* No io_select call returned success immediately, and the last call
+       blocked for our full timeout period and then timed out.  So the
+       multiplex times out too.  */
+    return 0;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Set the user bitarrays.  */
+  for (i = 0; i < nfds; ++i)
+    {
+      if (readfds != NULL)
+	if (types[i] & SELECT_READ)
+	  FD_SET (i, readfds);
+	else
+	  FD_CLR (i, readfds);
+      if (writefds != NULL)
+	if (types[i] & SELECT_WRITE)
+	  FD_SET (i, writefds);
+	else
+	  FD_CLR (i, writefds);
+      if (exceptfds != NULL)
+	if (types[i] & SELECT_URG)
+	  FD_SET (i, exceptfds);
+	else
+	  FD_CLR (i, exceptfds);
+    }
+
+  return got;
+}
+
+weak_alias (__select, select)
diff --git a/sysdeps/mach/hurd/send.c b/sysdeps/mach/hurd/send.c
new file mode 100644
index 0000000000..153ee93701
--- /dev/null
+++ b/sysdeps/mach/hurd/send.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+
+/* Send N bytes of BUF to socket FD.  Returns the number sent or -1.  */
+int
+DEFUN(send, (fd, buf, n, flags),
+      int fd AND PTR buf AND size_t n AND int flags)
+{
+  error_t err;
+  int wrote;
+
+  err = HURD_DPORT_USE (fd, __socket_send (port, MACH_PORT_NULL,
+					   flags, buf, n,
+					   NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+					   NULL, 0, &wrote));
+
+  return err ? __hurd_dfail (fd, err) : wrote;
+}
diff --git a/sysdeps/mach/hurd/sendto.c b/sysdeps/mach/hurd/sendto.c
new file mode 100644
index 0000000000..c3d4a4e121
--- /dev/null
+++ b/sysdeps/mach/hurd/sendto.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+
+/* Send N bytes of BUF on socket FD to peer at address ADDR (which is
+   ADDR_LEN bytes long).  Returns the number sent, or -1 for errors.  */
+int
+DEFUN(sendto, (fd, buf, n, flags, addr, addr_len),
+      int fd AND PTR buf AND size_t n AND int flags AND
+      struct sockaddr *addr AND size_t addr_len)
+{
+  addr_port_t aport;
+  error_t err;
+  int wrote;
+
+  /* Get an address port for the desired destination address.  */
+  err = HURD_DPORT_USE (fd,
+			({
+			  err = __socket_create_address (port,
+							 addr->sa_family,
+							 (char *) addr,
+							 addr_len,
+							 &aport, 1);
+			  if (! err)
+			    {
+			      /* Send the data.  */
+			      err = __socket_send (port, aport,
+						   flags, buf, n,
+						   NULL,
+						   MACH_MSG_TYPE_COPY_SEND, 0,
+						   NULL, 0, &wrote);
+			      __mach_port_deallocate (__mach_task_self (),
+						      aport);
+			    }
+			  err;
+			}));
+
+  return err ? __hurd_dfail (fd, err) : wrote;
+}
diff --git a/sysdeps/mach/hurd/setegid.c b/sysdeps/mach/hurd/setegid.c
new file mode 100644
index 0000000000..8ca4abee06
--- /dev/null
+++ b/sysdeps/mach/hurd/setegid.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <sys/types.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the effective user ID of the calling process to GID.  */
+int
+DEFUN(setegid, (gid), gid_t gid)
+{
+  auth_t newauth;
+  error_t err;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+  err = _hurd_check_ids ();
+
+  if (!err)
+    {
+      /* Make a new auth handle which has EGID as the first element in the
+         list of effective gids.  */
+
+      size_t ngen = _hurd_id.gen.ngids < 1 ? 1 : _hurd_id.gen.ngids;
+      gid_t newgen[ngen];
+
+      newgen[0] = gid;
+      memcpy (&newgen[1], _hurd_id.gen.gids, (ngen - 1) * sizeof (gid_t));
+
+      err = __USEPORT (AUTH, __auth_makeauth
+		       (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+			_hurd_id.gen.uids, _hurd_id.gen.nuids,
+			_hurd_id.aux.uids, _hurd_id.aux.nuids,
+			newgen, ngen,
+			_hurd_id.aux.gids, _hurd_id.aux.ngids,
+			&newauth));
+    }
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Install the new handle and reauthenticate everything.  */
+  err = __setauth (newauth);
+  __mach_port_deallocate (__mach_task_self (), newauth);
+  return err;
+}
diff --git a/sysdeps/mach/hurd/seteuid.c b/sysdeps/mach/hurd/seteuid.c
new file mode 100644
index 0000000000..9c44c4d275
--- /dev/null
+++ b/sysdeps/mach/hurd/seteuid.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <sys/types.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the effective user ID of the calling process to UID.  */
+int
+DEFUN(seteuid, (uid), uid_t uid)
+{
+  auth_t newauth;
+  error_t err;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+  err = _hurd_check_ids ();
+
+  if (!err)
+    {
+      /* Make a new auth handle which has EUID as the first element in the
+         list of effective uids.  */
+
+      size_t ngen = _hurd_id.gen.nuids < 1 ? 1 : _hurd_id.gen.nuids;
+      uid_t newgen[ngen];
+
+      newgen[0] = uid;
+      memcpy (&newgen[1], _hurd_id.gen.uids, (ngen - 1) * sizeof (uid_t));
+
+      err = __USEPORT (AUTH, __auth_makeauth
+		       (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+			newgen, ngen,
+			_hurd_id.aux.uids, _hurd_id.aux.nuids,
+			_hurd_id.gen.gids, _hurd_id.gen.ngids,
+			_hurd_id.aux.gids, _hurd_id.aux.ngids,
+			&newauth));
+    }
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Install the new handle and reauthenticate everything.  */
+  err = __setauth (newauth);
+  __mach_port_deallocate (__mach_task_self (), newauth);
+  return err;
+}
diff --git a/sysdeps/mach/hurd/setgid.c b/sysdeps/mach/hurd/setgid.c
new file mode 100644
index 0000000000..726b4130be
--- /dev/null
+++ b/sysdeps/mach/hurd/setgid.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the group ID of the calling process to UID.
+   If the calling process is the super-user, the real
+   and effective group IDs, and the saved set-group-ID to UID;
+   if not, the effective group ID is set to GID.  */
+int
+DEFUN(__setgid, (gid), gid_t gid)
+{
+  auth_t newauth;
+  error_t err;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+  err = _hurd_check_ids ();
+
+  if (!err)
+    {
+      /* Make a new auth handle which has GID as the real gid,
+	 and as the first element in the list of effective gids.  */
+
+      gid_t newgen[_hurd_id.gen.ngids + 1];
+      gid_t newaux[_hurd_id.aux.ngids];
+      
+      newgen[0] = gid;
+      memcpy (&newgen[1], _hurd_id.gen.gids,
+	      _hurd_id.gen.ngids * sizeof (gid_t));
+      newaux[0] = gid;
+      memcpy (&newaux[1], _hurd_id.aux.gids,
+	      (_hurd_id.aux.ngids - 1) * sizeof (gid_t));
+
+      err = __USEPORT (AUTH, __auth_makeauth
+		       (port, NULL, 0, MACH_MSG_TYPE_COPY_SEND,
+			_hurd_id.gen.uids, _hurd_id.gen.nuids,
+			_hurd_id.aux.uids, _hurd_id.aux.nuids,
+			newgen, 1 + _hurd_id.gen.ngids,
+			newaux, _hurd_id.aux.ngids,
+			&newauth));
+    }
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Install the new handle and reauthenticate everything.  */
+  err = __setauth (newauth);
+  __mach_port_deallocate (__mach_task_self (), newauth);
+  return err;
+}
+
+weak_alias (__setgid, setgid)
diff --git a/sysdeps/mach/hurd/setgroups.c b/sysdeps/mach/hurd/setgroups.c
new file mode 100644
index 0000000000..c3431477fb
--- /dev/null
+++ b/sysdeps/mach/hurd/setgroups.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <hurd.h>
+#include <hurd/id.h>
+
+/* Set the group set for the current user to GROUPS (N of them).  */
+int
+DEFUN(setgroups, (n, groups), size_t n AND CONST gid_t *groups)
+{
+  error_t err;
+  auth_t newauth;
+  size_t i;
+  gid_t new[n];
+
+  /* Fault before taking locks.  */
+  for (i = 0; i < n; ++i)
+    new[i] = groups[i];
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+  err = _hurd_check_ids ();
+  if (! err)
+    {
+      /* Get a new auth port using those IDs.  */
+      err = __USEPORT (AUTH,
+		       __auth_makeauth (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+					_hurd_id.gen.uids, _hurd_id.gen.nuids,
+					_hurd_id.aux.uids, _hurd_id.aux.nuids,
+					new, n,
+					_hurd_id.aux.gids, _hurd_id.aux.ngids,
+					&newauth));
+    }
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Install the new auth port and reauthenticate everything.  */
+  err = __setauth (newauth);
+  __mach_port_deallocate (__mach_task_self (), newauth);
+  return err;
+}
diff --git a/sysdeps/mach/hurd/sethostid.c b/sysdeps/mach/hurd/sethostid.c
new file mode 100644
index 0000000000..dc8153caa6
--- /dev/null
+++ b/sysdeps/mach/hurd/sethostid.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1993 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Set the current machine's Internet number to ID.
+   This call is restricted to the super-user.  */
+int
+DEFUN(sethostid, (id), long int id)
+{
+  error_t err = __USEPORT (PROC, __proc_sethostid (port, id));
+  return err ? __hurd_fail (err) : 0;
+}
diff --git a/sysdeps/mach/hurd/sethostname.c b/sysdeps/mach/hurd/sethostname.c
new file mode 100644
index 0000000000..2c019cf99e
--- /dev/null
+++ b/sysdeps/mach/hurd/sethostname.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Set the name of the current host to NAME, which is LEN bytes long.
+   This call is restricted to the super-user.  */
+int
+DEFUN(sethostname, (name, len),
+      CONST char *name AND size_t len)
+{
+  error_t err = __USEPORT (PROC, __proc_sethostname (port, name, len));
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
new file mode 100644
index 0000000000..4351c5ea99
--- /dev/null
+++ b/sysdeps/mach/hurd/setitimer.c
@@ -0,0 +1,332 @@
+/* Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stddef.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg_request.h>
+#include <mach/message.h>
+
+/* XXX Temporary cheezoid implementation of ITIMER_REAL/SIGALRM.  */
+
+spin_lock_t _hurd_itimer_lock = SPIN_LOCK_INITIALIZER;
+struct itimerval _hurd_itimerval; /* Current state of the timer.  */
+mach_port_t _hurd_itimer_port;	/* Port the timer thread blocks on.  */
+thread_t _hurd_itimer_thread;	/* Thread waiting for timeout.  */
+int _hurd_itimer_thread_suspended; /* Nonzero if that thread is suspended.  */
+vm_address_t _hurd_itimer_thread_stack_base; /* Base of its stack.  */
+vm_address_t _hurd_itimer_thread_stack_size; /* Size of its stack.  */
+struct timeval _hurd_itimer_started; /* Time the thread started waiting.  */
+
+static inline void
+subtract_timeval (struct timeval *from, const struct timeval *subtract)
+{
+  from->tv_usec -= subtract->tv_usec;
+  from->tv_sec -= subtract->tv_sec;
+  while (from->tv_usec < 0)
+    {
+      --from->tv_sec;
+      from->tv_usec += 1000000;
+    }
+}
+
+/* Function run by the itimer thread.
+   This code must be very careful not ever to require a MiG reply port.  */
+
+static void
+timer_thread (void)
+{
+  while (1)
+    {
+      error_t err;
+      /* The only message we ever expect to receive is the reply from the
+         signal thread to a sig_post call we did.  We never examine the
+	 contents.  */
+      struct
+	{
+	  mach_msg_header_t header;
+	  error_t return_code;
+	} msg;
+
+      /* Wait for a message on a port that noone sends to.  The purpose is
+	 the receive timeout.  Notice interrupts so that if we are
+	 thread_abort'd, we will loop around and fetch new values from
+	 _hurd_itimerval.  */
+      err = __mach_msg (&msg.header,
+			MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT,
+			0, 0, _hurd_itimer_port,
+			_hurd_itimerval.it_value.tv_sec * 1000 +
+			_hurd_itimerval.it_value.tv_usec / 1000,
+			MACH_PORT_NULL);
+      switch (err)
+	{
+	case MACH_RCV_TIMED_OUT:
+	  /* We got the expected timeout.  Send a message to the signal
+	     thread to tell it to post a SIGALRM signal.  We use
+	     _hurd_itimer_port as the reply port just so we will block until
+	     the signal thread has frobnicated things to reload the itimer or
+	     has terminated this thread.  */
+	  __msg_sig_post_request (_hurd_msgport,
+				  _hurd_itimer_port,
+				  MACH_MSG_TYPE_MAKE_SEND_ONCE,
+				  SIGALRM, __mach_task_self ());
+	  break;
+
+	case MACH_RCV_INTERRUPTED:
+	  /* We were thread_abort'd.  This is to tell us that
+	     _hurd_itimerval has changed and we need to reexamine it
+	     and start waiting with the new timeout value.  */
+	  break;
+
+	case MACH_MSG_SUCCESS:
+	  /* We got the reply message from the sig_post_request above.
+	     Ignore it and reexamine the timer value.  */
+	  __mach_msg_destroy (&msg.header); /* Just in case.  */
+	  break;
+
+	default:
+	  /* Unexpected lossage.  Oh well, keep trying.  */
+	  break;
+	}
+    }
+}
+
+/* Forward declaration.  */
+static sighandler_t preempt_sigalrm (thread_t thread, int signo,
+				     long int sigcode, int sigerror);
+
+/* Called before any normal SIGALRM signal is delivered.
+   Reload the itimer, or disable the itimer.  */
+
+static int
+setitimer_locked (const struct itimerval *new, struct itimerval *old,
+		  void *crit)
+{
+  struct itimerval newval = *new;
+  struct timeval now, remaining, elapsed;
+  struct timeval old_interval;
+  error_t err;
+
+  inline void kill_itimer_thread (void)
+    {
+      __thread_terminate (_hurd_itimer_thread);
+      __vm_deallocate (__mach_task_self (),
+		       _hurd_itimer_thread_stack_base,
+		       _hurd_itimer_thread_stack_size);
+      _hurd_itimer_thread = MACH_PORT_NULL;
+    }
+
+  if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0)
+    {
+      /* Make sure the itimer thread is set up.  */
+
+      if (_hurd_signal_preempt[SIGALRM] == NULL)
+	{
+	  static struct hurd_signal_preempt preempt =
+	    { preempt_sigalrm, 0, 0, NULL };
+	  _hurd_signal_preempt[SIGALRM] = &preempt;
+	}
+
+      if (_hurd_itimer_port == MACH_PORT_NULL)
+	{
+	  /* Allocate a receive right that the itimer thread will
+	     block waiting for a message on.  */
+	  if (err = __mach_port_allocate (__mach_task_self (),
+					  MACH_PORT_RIGHT_RECEIVE,
+					  &_hurd_itimer_port))
+	    goto out;
+	}
+
+      if (_hurd_itimer_thread == MACH_PORT_NULL)
+	{
+	  /* Start up the itimer thread running `timer_thread' (below).  */
+	  if (err = __thread_create (__mach_task_self (),
+				     &_hurd_itimer_thread))
+	    return __hurd_fail (err);
+	  _hurd_itimer_thread_stack_base = 0; /* Anywhere.  */
+	  _hurd_itimer_thread_stack_size = __vm_page_size; /* Small stack.  */
+	  if (err = __mach_setup_thread (__mach_task_self (),
+					 _hurd_itimer_thread,
+					 &timer_thread,
+					 &_hurd_itimer_thread_stack_base,
+					 &_hurd_itimer_thread_stack_size))
+	    {
+	      __thread_terminate (_hurd_itimer_thread);
+	      _hurd_itimer_thread = MACH_PORT_NULL;	  
+	      goto out;
+	    }
+	  _hurd_itimer_thread_suspended = 1;
+	}
+    }
+
+  if ((newval.it_value.tv_sec | newval.it_value.tv_usec) != 0 || old != NULL)
+    {
+      /* Calculate how much time is remaining for the pending alarm.  */
+      if (__gettimeofday (&now, NULL) < 0)
+	{
+	  __spin_unlock (&_hurd_itimer_lock);
+	  _hurd_critical_section_unlock (crit);
+	  return -1;
+	}
+      elapsed = now;
+      subtract_timeval (&elapsed, &_hurd_itimer_started);
+      remaining = _hurd_itimerval.it_value;
+      if (timercmp (&remaining, &elapsed, <))
+	{
+	  /* Hmm.  The timer should have just gone off, but has not been reset.
+	     This is a possible timing glitch.  The alarm will signal soon. */
+	  /* XXX wrong */
+	  remaining.tv_sec = 0;
+	  remaining.tv_usec = 0;
+	}
+      else
+	subtract_timeval (&remaining, &elapsed);
+
+      /* Remember the old reload interval before changing it.  */
+      old_interval = _hurd_itimerval.it_interval;
+
+      /* Record the starting time that the timer interval relates to.  */
+      _hurd_itimer_started = now;
+    }
+
+  /* Load the new itimer value.  */
+  _hurd_itimerval = newval;
+
+  if ((newval.it_value.tv_sec | newval.it_value.tv_usec) == 0)
+    {
+      /* Disable the itimer.  */
+      if (_hurd_itimer_thread && !_hurd_itimer_thread_suspended)
+	{
+	  /* Suspend the itimer thread so it does nothing.  Then abort its
+	     kernel context so that when the thread is resumed, mach_msg
+	     will return to timer_thread (below) and it will fetch new
+	     values from _hurd_itimerval.  */
+	  if ((err = __thread_suspend (_hurd_itimer_thread)) ||
+	      (err = __thread_abort (_hurd_itimer_thread)))
+	    /* If we can't save it for later, nuke it.  */
+	    kill_itimer_thread ();
+	  else
+	    _hurd_itimer_thread_suspended = 1;
+	}
+    }
+  /* See if the timeout changed.  If so, we must alert the itimer thread.  */
+  else if (remaining.tv_sec != new->it_value.tv_sec ||
+	   remaining.tv_usec != new->it_value.tv_usec)
+    {
+      /* The timeout value is changing.  Tell the itimer thread to
+	 reexamine it and start counting down.  If the itimer thread is
+	 marked as suspended, either we just created it, or it was
+	 suspended and thread_abort'd last time the itimer was disabled;
+	 either way it will wake up and start waiting for the new timeout
+	 value when we resume it.  If it is not suspended, the itimer
+	 thread is waiting to deliver a pending alarm that we will override
+	 (since it would come later than the new alarm being set);
+	 thread_abort will make mach_msg return MACH_RCV_INTERRUPTED, so it
+	 will loop around and use the new timeout value.  */
+      if (err = (_hurd_itimer_thread_suspended
+		 ? __thread_resume : __thread_abort) (_hurd_itimer_thread))
+	{
+	  kill_itimer_thread ();
+	  goto out;
+	}
+      _hurd_itimer_thread_suspended = 0;
+    }
+
+  __spin_unlock (&_hurd_itimer_lock);
+  _hurd_critical_section_unlock (crit);
+
+  if (old != NULL)
+    {
+      old->it_value = remaining;
+      old->it_interval = old_interval;
+    }
+  return 0;
+
+ out:
+  __spin_unlock (&_hurd_itimer_lock);
+  _hurd_critical_section_unlock (crit);
+  return __hurd_fail (err);
+}
+
+/* Set the timer WHICH to *NEW.  If OLD is not NULL,
+   set *OLD to the old value of timer WHICH.
+   Returns 0 on success, -1 on errors.  */
+int
+DEFUN(__setitimer, (which, new, old),
+      enum __itimer_which which AND
+      struct itimerval *new AND struct itimerval *old)
+{
+  void *crit;
+
+  switch (which)
+    {
+    default:
+      return __hurd_fail (EINVAL);
+
+    case ITIMER_VIRTUAL:
+    case ITIMER_PROF:
+      return __hurd_fail (ENOSYS);
+
+    case ITIMER_REAL:
+      break;
+    }
+
+  crit = _hurd_critical_section_lock ();
+  __spin_lock (&_hurd_itimer_lock);
+  return setitimer_locked (new, old, crit);
+}
+
+static sighandler_t
+preempt_sigalrm (thread_t thread, int signo, long int sigcode, int sigerror)
+{
+  struct itimerval it;
+
+  if (thread != _hurd_sigthread || signo != SIGALRM || sigcode != 0)
+    /* Too much monkey business.  */
+    return SIG_DFL;
+
+  /* Either reload or disable the itimer.  */
+  __spin_lock (&_hurd_itimer_lock);
+  it = _hurd_itimerval;
+  it.it_value = it.it_interval;
+  setitimer_locked (&it, NULL, NULL);
+
+  /* Continue with normal delivery of SIGALRM.  */
+  return SIG_DFL;
+}
+
+static void
+fork_itimer (void)
+{
+  /* We must restart the itimer in the child.  */
+
+  struct itimerval it;
+
+  __spin_lock (&_hurd_itimer_lock);
+  _hurd_itimer_thread = MACH_PORT_NULL;
+  it = _hurd_itimerval;
+  it.it_value = it.it_interval;
+
+  setitimer_locked (&it, NULL, NULL);
+}
+text_set_element (_hurd_fork_child_hook, fork_itimer);
+
+weak_alias (__setitimer, setitimer)
diff --git a/sysdeps/mach/hurd/setlogin.c b/sysdeps/mach/hurd/setlogin.c
new file mode 100644
index 0000000000..867d8e25c9
--- /dev/null
+++ b/sysdeps/mach/hurd/setlogin.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Set the login name returned by `getlogin'.  */
+int
+DEFUN(setlogin, (name), CONST char *name)
+{
+  error_t err;
+  if (err = __USEPORT (PROC, __proc_setlogin (port, name)))
+    return __hurd_fail (err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/setpgid.c b/sysdeps/mach/hurd/setpgid.c
new file mode 100644
index 0000000000..7c74ef8a4c
--- /dev/null
+++ b/sysdeps/mach/hurd/setpgid.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* 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.  */
+int
+DEFUN(__setpgid, (pid, pgid), pid_t pid AND pid_t pgid)
+{
+  error_t err;
+  unsigned int stamp;
+
+  stamp = _hurd_pids_changed_stamp; /* Atomic fetch.  */
+
+  if (err = __USEPORT (PROC, __proc_setpgrp (port, pid, pgid)))
+    return __hurd_fail (err);
+
+  if (pid == 0 || pid == _hurd_pid)
+    /* Synchronize with the signal thread to make sure we have
+       received and processed proc_newids before returning to the user.  */
+    while (_hurd_pids_changed_stamp == stamp)
+      {
+#ifdef noteven
+	/* XXX we have no need for a mutex, but cthreads demands one.  */
+	__condition_wait (&_hurd_pids_changed_sync, NULL);
+#else
+	__swtch_pri(0);
+#endif
+      }
+
+  return 0;
+
+}
+
+weak_alias (__setpgid, setpgid)
+weak_alias (__setpgid, setpgrp)
diff --git a/sysdeps/mach/hurd/setpriority.c b/sysdeps/mach/hurd/setpriority.c
new file mode 100644
index 0000000000..644bfdf6fe
--- /dev/null
+++ b/sysdeps/mach/hurd/setpriority.c
@@ -0,0 +1,85 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <hurd.h>
+#include <hurd/resource.h>
+
+/* Set the priority of all processes specified by WHICH and WHO
+   to PRIO.  Returns 0 on success, -1 on errors.  */
+int
+setpriority (enum __priority_which which, int who, int prio)
+{
+  error_t err;
+  error_t pidloser, priloser;
+  unsigned int npids, ntasks, nwin, nperm, nacces;
+
+  error_t setonepriority (pid_t pid, struct procinfo *pi)
+    {
+      task_t task;
+      error_t piderr = __USEPORT (PROC, __proc_pid2task (port, pid, &task));
+      if (piderr == EPERM)
+	++nperm;
+      if (piderr != ESRCH)
+	{
+	  ++npids;
+	  if (piderr && piderr != EPERM)
+	    pidloser = piderr;
+	}
+      if (! piderr)
+	{
+	  error_t prierr;
+	  ++ntasks;
+	  prierr = __task_priority (task, NICE_TO_MACH_PRIORITY (prio), 1);
+	  __mach_port_deallocate (__mach_task_self (), task);
+	  switch (prierr)
+	    {
+	    case KERN_FAILURE:
+	      ++nacces;
+	      break;
+	    case KERN_SUCCESS:
+	      ++nwin;
+	      break;
+	    case KERN_INVALID_ARGUMENT: /* Task died.  */
+	      --npids;
+	      --ntasks;
+	      break;
+	    default:
+	      priloser = prierr;
+	    }
+	}
+      return 0;
+    }
+
+  npids = ntasks = nwin = nperm = nacces = 0;
+  pidloser = priloser = 0;
+  err = _hurd_priority_which_map (which, who, setonepriority);
+
+  if (!err && npids == 0)
+    /* No error, but no pids found.  */
+    err = ESRCH;
+  else if (nperm == npids)
+    /* Got EPERM from proc_task2pid for every process.  */
+    err = EPERM;
+  else if (nacces == ntasks)
+    /* Got KERN_FAILURE from task_priority for every task.  */
+    err = EACCES;
+  else if (nwin == 0)
+    err = pidloser ?: priloser;
+
+  return err ? __hurd_fail (err) : 0;
+}
diff --git a/sysdeps/mach/hurd/setregid.c b/sysdeps/mach/hurd/setregid.c
new file mode 100644
index 0000000000..8b76f7008a
--- /dev/null
+++ b/sysdeps/mach/hurd/setregid.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+int
+__setregid (gid_t rgid, gid_t egid)
+{
+  auth_t newauth;
+  error_t err;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+  err = _hurd_check_ids ();
+
+  if (!err)
+    {
+      /* Make a new auth handle which has RGID as the real gid,
+	 and EGID as the first element in the list of effective gids.  */
+
+      size_t ngen = _hurd_id.gen.ngids < 1 ? 1 : _hurd_id.gen.ngids;
+      size_t naux = _hurd_id.aux.ngids < 1 ? 1 : _hurd_id.aux.ngids;
+      gid_t newaux[naux], newgen[ngen];
+
+      newgen[0] = egid;
+      memcpy (&newgen[1], _hurd_id.gen.gids, (ngen - 1) * sizeof (gid_t));
+      newaux[0] = rgid;
+      memcpy (&newaux[1], _hurd_id.aux.gids, (naux - 1) * sizeof (gid_t));
+
+      err = __USEPORT (AUTH, __auth_makeauth
+		       (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+			_hurd_id.gen.gids, _hurd_id.gen.ngids,
+			_hurd_id.aux.gids, _hurd_id.aux.ngids,
+			newgen, ngen,
+			newaux, naux,
+			&newauth));
+    }
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Install the new handle and reauthenticate everything.  */
+  err = __setauth (newauth);
+  __mach_port_deallocate (__mach_task_self (), newauth);
+  return err;
+}
+
+weak_alias (__setregid, setregid)
diff --git a/sysdeps/mach/hurd/setreuid.c b/sysdeps/mach/hurd/setreuid.c
new file mode 100644
index 0000000000..1dcbf0ee82
--- /dev/null
+++ b/sysdeps/mach/hurd/setreuid.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+int
+__setreuid (uid_t ruid, uid_t euid)
+{
+  auth_t newauth;
+  error_t err;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+  err = _hurd_check_ids ();
+
+  if (!err)
+    {
+      /* Make a new auth handle which has RUID as the real uid,
+	 and EUID as the first element in the list of effective uids.  */
+
+      size_t ngen = _hurd_id.gen.nuids < 1 ? 1 : _hurd_id.gen.nuids;
+      size_t naux = _hurd_id.aux.nuids < 1 ? 1 : _hurd_id.aux.nuids;
+      uid_t newaux[naux], newgen[ngen];
+
+      newgen[0] = euid;
+      memcpy (&newgen[1], _hurd_id.gen.uids, (ngen - 1) * sizeof (uid_t));
+      newaux[0] = ruid;
+      memcpy (&newaux[1], _hurd_id.aux.uids, (naux - 1) * sizeof (uid_t));
+
+      err = __USEPORT (AUTH, __auth_makeauth
+		       (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+			newgen, ngen,
+			newaux, naux,
+			_hurd_id.gen.gids, _hurd_id.gen.ngids,
+			_hurd_id.aux.gids, _hurd_id.aux.ngids,
+			&newauth));
+    }
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Install the new handle and reauthenticate everything.  */
+  err = __setauth (newauth);
+  __mach_port_deallocate (__mach_task_self (), newauth);
+  return err;
+}
+
+weak_alias (__setreuid, setreuid)
diff --git a/sysdeps/mach/hurd/setrlimit.c b/sysdeps/mach/hurd/setrlimit.c
new file mode 100644
index 0000000000..6d60d6dd57
--- /dev/null
+++ b/sysdeps/mach/hurd/setrlimit.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <hurd.h>
+#include <hurd/resource.h>
+#include <errno.h>
+#include <hurd/fd.h>
+
+
+/* Set the soft and hard limits for RESOURCE to *RLIMITS.
+   Only the super-user can increase hard limits.
+   Return 0 if successful, -1 if not (and sets errno).  */
+int
+DEFUN(setrlimit, (resource, rlimits),
+      enum __rlimit_resource resource AND struct rlimit *rlimits)
+{
+  struct rlimit lim;
+
+  if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  lim = *rlimits;
+
+  if (lim.rlim_max != RLIM_INFINITY)
+    {
+      /* We have no enforceable resource limits.  */
+      errno = ENOSYS;
+      return -1;
+    }
+
+  if (lim.rlim_cur > lim.rlim_max)
+    lim.rlim_cur = lim.rlim_max;
+
+  __mutex_lock (&_hurd_rlimit_lock);
+  _hurd_rlimits[resource] = lim;
+  __mutex_unlock (&_hurd_rlimit_lock);
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/setsid.c b/sysdeps/mach/hurd/setsid.c
new file mode 100644
index 0000000000..22dc965344
--- /dev/null
+++ b/sysdeps/mach/hurd/setsid.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+
+/* 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.  */
+int
+DEFUN_VOID(__setsid)
+{
+  error_t err;
+  unsigned int stamp;
+
+  stamp = _hurd_pids_changed_stamp; /* Atomic fetch.  */
+
+  /* Tell the proc server we want to start a new session.  */
+  if (err = __USEPORT (PROC, __proc_setsid (port)))
+    return __hurd_fail (err);
+
+  /* Punt our current ctty.  */
+  _hurd_setcttyid (MACH_PORT_NULL);
+
+  /* Synchronize with the signal thread to make sure we have
+     received and processed proc_newids before returning to the user.  */
+  while (_hurd_pids_changed_stamp == stamp)
+    {
+#ifdef noteven
+      /* XXX we have no need for a mutex, but cthreads demands one.  */
+      __condition_wait (&_hurd_pids_changed_sync, NULL);
+#else
+      __swtch_pri(0);
+#endif
+    }
+
+  return 0;
+}
+
+weak_alias (__setsid, setsid)
diff --git a/sysdeps/mach/hurd/setsockopt.c b/sysdeps/mach/hurd/setsockopt.c
new file mode 100644
index 0000000000..4d527696fe
--- /dev/null
+++ b/sysdeps/mach/hurd/setsockopt.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+
+/* Set socket FD's option OPTNAME at protocol level LEVEL
+   to *OPTVAL (which is OPTLEN bytes long).
+   Returns 0 on success, -1 for errors.  */
+int
+DEFUN(setsockopt, (fd, level, optname, optval, optlen),
+      int fd AND int level AND int optname AND
+      PTR optval AND size_t optlen)
+{
+  error_t err = HURD_DPORT_USE (fd, __socket_setopt (port,
+						     level, optname,
+						     optval, optlen));
+  if (err)
+    return __hurd_dfail (fd, err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/settimeofday.c b/sysdeps/mach/hurd/settimeofday.c
new file mode 100644
index 0000000000..1747a443a4
--- /dev/null
+++ b/sysdeps/mach/hurd/settimeofday.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+/* Set the current time of day and timezone information.
+   This call is restricted to the super-user.  */
+int
+DEFUN(__settimeofday, (tv, tz),
+      CONST struct timeval *tv AND CONST struct timezone *tz)
+{
+  error_t err;
+  mach_port_t hostpriv, devmaster;
+
+  if (tz != NULL)
+    {
+      errno = ENOSYS;
+      return -1;
+    }
+
+  if (err = __USEPORT (PROC, __proc_getprivports (port,
+						  &hostpriv, &devmaster)))
+    return __hurd_fail (err);
+  __mach_port_deallocate (__mach_task_self (), devmaster);
+
+  /* `time_value_t' and `struct timeval' are in fact identical with the
+     names changed.  */
+  err = __host_set_time (hostpriv, *(time_value_t *) tv);
+  __mach_port_deallocate (__mach_task_self (), hostpriv);
+
+  if (err)
+    return __hurd_fail (err);
+
+  return 0;
+}
+
+weak_alias (__settimeofday, settimeofday)
diff --git a/sysdeps/mach/hurd/setuid.c b/sysdeps/mach/hurd/setuid.c
new file mode 100644
index 0000000000..7084038b0b
--- /dev/null
+++ b/sysdeps/mach/hurd/setuid.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <hurd/id.h>
+#include <string.h>
+
+/* Set the user ID of the calling process to UID.
+   If the calling process is the super-user, the real
+   and effective user IDs, and the saved set-user-ID to UID;
+   if not, the effective user ID is set to UID.  */
+int
+DEFUN(__setuid, (uid), uid_t uid)
+{
+  auth_t newauth;
+  error_t err;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_id.lock);
+  err = _hurd_check_ids ();
+
+  if (!err)
+    {
+      /* Make a new auth handle which has UID as the real uid,
+	 and as the first element in the list of effective uids.  */
+
+      uid_t newgen[_hurd_id.gen.nuids + 1];
+      uid_t newaux[_hurd_id.aux.nuids];
+      
+      newgen[0] = uid;
+      memcpy (&newgen[1], _hurd_id.gen.uids,
+	      _hurd_id.gen.nuids * sizeof (uid_t));
+      newaux[0] = uid;
+      memcpy (&newaux[1], _hurd_id.aux.uids,
+	      (_hurd_id.aux.nuids - 1) * sizeof (uid_t));
+
+      err = __USEPORT (AUTH, __auth_makeauth
+		       (port, NULL, 0, MACH_MSG_TYPE_COPY_SEND,
+			_hurd_id.gen.uids, _hurd_id.gen.nuids,
+			_hurd_id.aux.uids, _hurd_id.aux.nuids,
+			newgen, 1 + _hurd_id.gen.nuids,
+			newaux, _hurd_id.aux.nuids,
+			&newauth));
+    }
+  __mutex_unlock (&_hurd_id.lock);
+  HURD_CRITICAL_END;
+
+  if (err)
+    return __hurd_fail (err);
+
+  /* Install the new handle and reauthenticate everything.  */
+  err = __setauth (newauth);
+  __mach_port_deallocate (__mach_task_self (), newauth);
+  return err;
+}
+
+weak_alias (__setuid, setuid)
diff --git a/sysdeps/mach/hurd/shutdown.c b/sysdeps/mach/hurd/shutdown.c
new file mode 100644
index 0000000000..685057b709
--- /dev/null
+++ b/sysdeps/mach/hurd/shutdown.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+
+/* Shut down all or part of the connection open on socket FD.
+   HOW determines what to shut down:
+     0 = No more receptions;
+     1 = No more transmissions;
+     2 = No more receptions or transmissions.
+   Returns 0 on success, -1 for errors.  */
+int
+DEFUN(shutdown, (fd, how),
+      int fd AND int how)
+{
+  error_t err = HURD_DPORT_USE (fd, __socket_shutdown (port, how));
+  if (err)
+    return __hurd_dfail (fd, err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/sigaction.c b/sysdeps/mach/hurd/sigaction.c
new file mode 100644
index 0000000000..91de02cd17
--- /dev/null
+++ b/sysdeps/mach/hurd/sigaction.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <signal.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+   If OACT is not NULL, put the old action for SIG in *OACT.  */
+int
+DEFUN(__sigaction, (sig, act, oact),
+      int sig AND CONST struct sigaction *act AND struct sigaction *oact)
+{
+  struct hurd_sigstate *ss;
+  struct sigaction a, old;
+  sigset_t pending;
+
+  if (sig <= 0 || sig >= NSIG ||
+      (act != NULL && act->sa_handler != SIG_DFL &&
+       ((__sigmask (sig) & _SIG_CANT_MASK) ||
+	act->sa_handler == SIG_ERR)))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  /* Copy so we fault before taking locks.  */
+  if (act != NULL)
+    a = *act;
+
+  ss = _hurd_self_sigstate ();
+
+  __spin_lock (&ss->lock);
+  old = ss->actions[sig];
+  if (act != NULL)
+    ss->actions[sig] = a;
+
+  if (act != NULL && sig == SIGCHLD)
+    {
+      ss->critical_section = 1;
+      __spin_unlock (&ss->lock);
+
+      /* Inform the proc server whether or not it should send us SIGCHLD for
+	 stopped children.  We do this in a critical section so that no
+	 SIGCHLD can arrive in the middle and be of indeterminate status.  */
+      __USEPORT (PROC,
+		 __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP)));
+
+      __spin_lock (&ss->lock);
+      ss->critical_section = 0;
+      pending = ss->pending & ~ss->blocked;
+    }
+  else
+    pending = 0;
+
+  __spin_unlock (&ss->lock);
+
+  if (pending)
+    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+
+  if (oact != NULL)
+    *oact = old;
+
+  return 0;
+}
+
+weak_alias (__sigaction, sigaction)
diff --git a/sysdeps/mach/hurd/sigaltstack.c b/sysdeps/mach/hurd/sigaltstack.c
new file mode 100644
index 0000000000..c4a905213c
--- /dev/null
+++ b/sysdeps/mach/hurd/sigaltstack.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+
+/* Run signals handlers on the stack specified by SS (if not NULL).
+   If OSS is not NULL, it is filled in with the old signal stack status.  */
+int
+DEFUN(sigaltstack, (ss, oss),
+      CONST struct sigaltstack *argss AND struct sigaltstack *oss)
+{
+  struct hurd_sigstate *s;
+  struct sigaltstack ss, old;
+
+  /* Fault before taking any locks.  */
+  if (argss != NULL)
+    ss = *argss;
+  if (oss != NULL)
+    *(volatile struct sigaltstack *) oss = *oss;
+
+  s = _hurd_self_sigstate ();
+  __spin_lock (&s->lock);
+
+  if (argss != NULL &&
+      (ss.ss_flags & SA_DISABLE) && (s->sigaltstack.ss_flags & SA_ONSTACK))
+    {
+      /* Can't disable a stack that is in use.  */
+      __spin_unlock (&s->lock);
+      errno = EINVAL;
+      return -1;
+    }
+
+  old = s->sigaltstack;
+
+  if (argss != NULL)
+    s->sigaltstack = ss;
+
+  __spin_unlock (&s->lock);
+
+  if (oss != NULL)
+    *oss = old;
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/sigpending.c b/sysdeps/mach/hurd/sigpending.c
new file mode 100644
index 0000000000..8c12ed0bbf
--- /dev/null
+++ b/sysdeps/mach/hurd/sigpending.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+
+
+/* Store in SET all signals that are blocked and pending.  */
+int
+DEFUN(sigpending, (set), sigset_t *set)
+{
+  struct hurd_sigstate *ss;
+  sigset_t pending;
+
+  if (set == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  ss = _hurd_self_sigstate ();
+  __spin_lock (&ss->lock);
+  pending = ss->pending;
+  __spin_unlock (&ss->lock);
+
+  *set = pending;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/sigprocmask.c b/sysdeps/mach/hurd/sigprocmask.c
new file mode 100644
index 0000000000..bae3266708
--- /dev/null
+++ b/sysdeps/mach/hurd/sigprocmask.c
@@ -0,0 +1,87 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <signal.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+
+
+/* If SET is not NULL, modify the current set of blocked signals
+   according to HOW, which may be SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK.
+   If OSET is not NULL, store the old set of blocked signals in *OSET.  */
+int
+DEFUN(__sigprocmask, (how, set, oset),
+      int how AND CONST sigset_t *set AND sigset_t *oset)
+{
+  struct hurd_sigstate *ss;
+  sigset_t old, new;
+  sigset_t pending;
+
+  if (set != NULL)
+    new = *set;
+
+  ss = _hurd_self_sigstate ();
+
+  __spin_lock (&ss->lock);
+
+  old = ss->blocked;
+
+  if (set != NULL)
+    {
+      switch (how)
+	{
+	case SIG_BLOCK:
+	  ss->blocked |= new;
+	  break;
+
+	case SIG_UNBLOCK:
+	  ss->blocked &= ~new;
+	  break;
+
+	case SIG_SETMASK:
+	  ss->blocked = new;
+	  break;
+
+	default:
+	  __spin_unlock (&ss->lock);
+	  errno = EINVAL;
+	  return -1;
+	}
+
+      ss->blocked &= ~_SIG_CANT_MASK;
+    }
+
+  pending = ss->pending & ~ss->blocked;
+
+  __spin_unlock (&ss->lock);
+
+  if (oset != NULL)
+    *oset = old;
+
+  if (pending)
+    /* Send a message to the signal thread so it
+       will wake up and check for pending signals.  */
+    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+
+  return 0;
+}
+
+weak_alias (__sigprocmask, sigprocmask)
diff --git a/sysdeps/mach/hurd/sigstack.c b/sysdeps/mach/hurd/sigstack.c
new file mode 100644
index 0000000000..77803ab012
--- /dev/null
+++ b/sysdeps/mach/hurd/sigstack.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1992 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <signal.h>
+#include <hurd.h>
+
+/* Run signals handlers on the stack specified by SS (if not NULL).
+   If OSS is not NULL, it is filled in with the old signal stack status.  */
+int
+DEFUN(sigstack, (ss, oss),
+      CONST struct sigstack *ss AND struct sigstack *oss)
+{
+  struct sigaltstack as, oas;
+
+  as.ss_sp = ss->ss_sp;
+  as.ss_size = 0;
+  as.ss_flags = 0;
+
+  if (sigaltstack (&as, &oas) < 0)
+    return -1;
+
+  if (oss != NULL)
+    {
+      oss->ss_sp = oas.ss_sp;
+      oss->ss_onstack = oas.ss_flags & SA_ONSTACK;
+    }
+
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/sigsuspend.c b/sysdeps/mach/hurd/sigsuspend.c
new file mode 100644
index 0000000000..aa0b2876a4
--- /dev/null
+++ b/sysdeps/mach/hurd/sigsuspend.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/signal.h>
+#include <hurd/msg.h>
+
+/* Change the set of blocked signals to SET,
+   wait until a signal arrives, and restore the set of blocked signals.  */
+int
+DEFUN(sigsuspend, (set), CONST sigset_t *set)
+{
+  struct hurd_sigstate *ss;
+  sigset_t newmask, oldmask, pending;
+  mach_port_t wait;
+  mach_msg_header_t msg;
+
+  if (set != NULL)
+    /* Crash before locking.  */
+    newmask = *set;
+
+  /* Get a fresh port we will wait on.  */
+  wait = __mach_reply_port ();
+
+  ss = _hurd_self_sigstate ();
+
+  __spin_lock (&ss->lock);
+
+  oldmask = ss->blocked;
+  if (set != NULL)
+    /* Change to the new blocked signal mask.  */
+    ss->blocked = newmask & ~_SIG_CANT_MASK;
+
+  /* Notice if any pending signals just became unblocked.  */
+  pending = ss->pending & ~ss->blocked;
+
+  /* Tell the signal thread to message us when a signal arrives.  */
+  ss->suspended = wait;
+  __spin_unlock (&ss->lock);
+
+  if (pending)
+    /* Tell the signal thread to check for pending signals.  */
+    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+
+  /* Wait for the signal thread's message.  */
+  __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
+	      MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+  __mach_port_destroy (__mach_task_self (), wait);
+
+  __spin_lock (&ss->lock);
+  ss->blocked = oldmask;	/* Restore the old mask.  */
+  pending = ss->pending & ~ss->blocked;	/* Again check for pending signals.  */
+  __spin_unlock (&ss->lock);
+
+  if (pending)
+    /* Tell the signal thread to check for pending signals.  */
+    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+    
+  /* We've been interrupted!  And a good thing, too.
+     Otherwise we'd never return.
+     That's right; this function always returns an error.  */
+  errno = EINTR;
+  return -1;
+}
diff --git a/sysdeps/mach/hurd/socket.c b/sysdeps/mach/hurd/socket.c
new file mode 100644
index 0000000000..b779360780
--- /dev/null
+++ b/sysdeps/mach/hurd/socket.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+#include <fcntl.h>
+
+/* Create a new socket of type TYPE in domain DOMAIN, using
+   protocol PROTOCOL.  If PROTOCOL is zero, one is chosen automatically.
+   Returns a file descriptor for the new socket, or -1 for errors.  */
+int
+DEFUN(socket, (domain, type, protocol),
+      int domain AND enum __socket_type type AND int protocol)
+{
+  error_t err;
+  socket_t sock, server;
+
+  /* Find the socket server for DOMAIN.  */
+  server = _hurd_socket_server (domain, 0);
+  if (server == MACH_PORT_NULL)
+    return -1;
+
+  err = __socket_create (server, type, protocol, &sock);
+  if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
+    {
+      /* On the first use of the socket server during the operation,
+	 allow for the old server port dying.  */
+      server = _hurd_socket_server (domain, 1);
+      if (server == MACH_PORT_NULL)
+	return -1;
+      err = __socket_create (server, type, protocol, &sock);
+    }
+
+  if (err)
+    return __hurd_fail (err);
+
+  return _hurd_intern_fd (sock, O_IGNORE_CTTY, 1);
+}
diff --git a/sysdeps/mach/hurd/socketpair.c b/sysdeps/mach/hurd/socketpair.c
new file mode 100644
index 0000000000..c4d09c707a
--- /dev/null
+++ b/sysdeps/mach/hurd/socketpair.c
@@ -0,0 +1,93 @@
+/* Copyright (C) 1992, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <hurd.h>
+#include <hurd/socket.h>
+#include <hurd/fd.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* Create two new sockets, of type TYPE in domain DOMAIN and using
+   protocol PROTOCOL, which are connected to each other, and put file
+   descriptors for them in FDS[0] and FDS[1].  If PROTOCOL is zero,
+   one will be chosen automatically.  Returns 0 on success, -1 for errors.  */
+int
+DEFUN(socketpair, (domain, type, protocol, fds),
+      int domain AND enum __socket_type type AND int protocol AND int fds[2])
+{
+  error_t err;
+  socket_t server, sock1, sock2;
+  int d1, d2;
+
+  if (fds == NULL)
+    return __hurd_fail (EINVAL);
+
+  /* Find the domain's socket server.  */
+  server = _hurd_socket_server (domain, 0);
+  if (server == MACH_PORT_NULL)
+    return -1;
+
+  /* Create two sockets and connect them together.  */
+
+  err = __socket_create (server, type, protocol, &sock1);
+  if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
+    {
+      /* On the first use of the socket server during the operation,
+	 allow for the old server port dying.  */
+      server = _hurd_socket_server (domain, 1);
+      if (server == MACH_PORT_NULL)
+	return -1;
+      err = __socket_create (server, type, protocol, &sock1);
+    }
+  if (err)
+    return __hurd_fail (err);
+  if (err = __socket_create (server, type, protocol, &sock2))
+    {
+      __mach_port_deallocate (__mach_task_self (), sock1);
+      return __hurd_fail (err);
+    }
+  if (err = __socket_connect2 (sock1, sock2))
+    {
+      __mach_port_deallocate (__mach_task_self (), sock1);
+      __mach_port_deallocate (__mach_task_self (), sock2);
+      return __hurd_fail (err);
+    }
+
+  /* Put the sockets into file descriptors.  */
+
+  d1 = _hurd_intern_fd (sock1, O_IGNORE_CTTY, 1);
+  if (d1 < 0)
+    {
+      __mach_port_deallocate (__mach_task_self (), sock2);
+      return -1;
+    }
+  d2 = _hurd_intern_fd (sock2, O_IGNORE_CTTY, 1);
+  if (d2 < 0)
+    {
+      err = errno;
+      (void) close (d1);
+      return __hurd_fail (err);
+    }
+
+  fds[0] = d1;
+  fds[1] = d2;
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/start.c b/sysdeps/mach/hurd/start.c
new file mode 100644
index 0000000000..91be7eaefe
--- /dev/null
+++ b/sysdeps/mach/hurd/start.c
@@ -0,0 +1,316 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <hurd.h>
+#include <hurd/exec.h>
+#include <sysdep.h>
+#include <hurd/threadvar.h>
+#include "set-hooks.h"
+#include "hurdmalloc.h"		/* XXX */
+
+/* The first piece of initialized data.  */
+int __data_start = 0;
+weak_alias (__data_start, data_start)
+
+mach_port_t *_hurd_init_dtable;
+mach_msg_type_number_t _hurd_init_dtablesize;
+
+unsigned int __hurd_threadvar_max;
+unsigned long int __hurd_threadvar_stack_mask;
+unsigned long int __hurd_threadvar_stack_offset;
+
+/* These are set up by _hurdsig_init.  */
+unsigned long int __hurd_sigthread_stack_base;
+unsigned long int __hurd_sigthread_stack_end;
+unsigned long int *__hurd_sigthread_variables;
+
+vm_address_t _hurd_stack_base;
+vm_size_t _hurd_stack_size;
+
+char **__environ;
+weak_alias (__environ, environ)
+
+/* Things that want to be run before _hurd_init or much anything else.
+   Importantly, these are called before anything tries to use malloc.  */
+DEFINE_HOOK (_hurd_preinit_hook, (void));
+
+extern void __mach_init (void);
+extern void __libc_init (int argc, char **argv, char **envp);
+extern int main (int argc, char **argv, char **envp);
+
+void *(*_cthread_init_routine) (void); /* Returns new SP to use.  */
+void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
+
+int _hurd_split_args (char *, size_t, char **);
+
+/* These communicate values from _start to start1,
+   where we cannot use the stack for anything.  */
+static char *args, *env;
+static mach_port_t *portarray;
+static int *intarray;
+static mach_msg_type_number_t argslen, envlen, portarraysize, intarraysize;
+static int flags;
+static char **argv, **envp;
+static int argc;
+
+
+static void start1 (void) __attribute__ ((__noreturn__));
+
+
+/* Entry point.  This is the first thing in the text segment.
+
+   The exec server started the initial thread in our task with this spot the
+   PC, and a stack that is presumably big enough.  We do basic Mach
+   initialization so mig-generated stubs work, and then do an exec_startup
+   RPC on our bootstrap port, to which the exec server responds with the
+   information passed in the exec call, as well as our original bootstrap
+   port, and the base address and size of the preallocated stack.
+
+   If using cthreads, we are given a new stack by cthreads initialization and
+   deallocate the stack set up by the exec server.  On the new stack we call
+   `start1' (above) to do the rest of the startup work.  Since the stack may
+   disappear out from under us in a machine-dependent way, we use a pile of
+   static variables to communicate the information from exec_startup to start1.
+   This is unfortunate but preferable to machine-dependent frobnication to copy
+   the state from the old stack to the new one.  */
+
+#ifndef START_ARGS
+#define START_ARGS void
+#endif
+#ifdef START_MACHDEP
+START_MACHDEP
+#define _start _start0
+#endif
+
+void
+_start (START_ARGS)
+{
+  error_t err;
+  mach_port_t in_bootstrap;
+
+  /* Basic Mach initialization, must be done before RPCs can be done.  */
+  __mach_init ();
+
+  /* Run things that want to do initialization as soon as possible.  We do
+     this before exec_startup so that no out of line data arrives and
+     clutters up the address space before brk initialization.  */
+
+  RUN_HOOK (_hurd_preinit_hook, ());
+
+  if (err = __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT,
+				     &in_bootstrap))
+    LOSE;
+
+  if (in_bootstrap != MACH_PORT_NULL)
+    {
+      /* Call the exec server on our bootstrap port and
+	 get all our standard information from it.  */
+
+      argslen = envlen = 0;
+      _hurd_init_dtablesize = portarraysize = intarraysize = 0;
+
+      err = __exec_startup (in_bootstrap,
+			    &_hurd_stack_base, &_hurd_stack_size,
+			    &flags,
+			    &args, &argslen, &env, &envlen,
+			    &_hurd_init_dtable, &_hurd_init_dtablesize,
+			    &portarray, &portarraysize,
+			    &intarray, &intarraysize);
+      __mach_port_deallocate (__mach_task_self (), in_bootstrap);
+    }
+
+  if (err || in_bootstrap == MACH_PORT_NULL)
+    {
+      /* Either we have no bootstrap port, or the RPC to the exec server
+	 failed.  Try to snarf the args in the canonical Mach way.
+	 Hopefully either they will be on the stack as expected, or the
+	 stack will be zeros so we don't crash.  Set all our other
+	 variables to have empty information.  */
+
+      /* SNARF_ARGS (ARGC, ARGV, ENVP) snarfs the arguments and environment
+	 from the stack, assuming they were put there by the microkernel.  */
+      SNARF_ARGS (argc, argv, envp);
+
+      flags = 0;
+      args = env = NULL;
+      argslen = envlen = 0;
+      _hurd_init_dtable = NULL;
+      _hurd_init_dtablesize = 0;
+      portarray = NULL;
+      portarraysize = 0;
+      intarray = NULL;
+      intarraysize = 0;
+    }
+  else
+    argv = envp = NULL;
+
+
+  /* The user might have defined a value for this, to get more variables.
+     Otherwise it will be zero on startup.  We must make sure it is set
+     properly before before cthreads initialization, so cthreads can know
+     how much space to leave for thread variables.  */
+  if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
+    __hurd_threadvar_max = _HURD_THREADVAR_MAX;
+
+  /* Do cthreads initialization and switch to the cthread stack.  */
+
+  if (_cthread_init_routine != NULL)
+    CALL_WITH_SP (start1, (*_cthread_init_routine) ());
+  else
+    start1 ();
+
+  /* Should never get here.  */
+  LOSE;
+}
+
+
+static void
+start1 (void)
+{
+  register int envc = 0;
+
+  {
+    /* Check if the stack we are now on is different from
+       the one described by _hurd_stack_{base,size}.  */
+
+    char dummy;
+    const vm_address_t newsp = (vm_address_t) &dummy;
+
+    if (_hurd_stack_size != 0 && (newsp < _hurd_stack_base ||
+				  newsp - _hurd_stack_base > _hurd_stack_size))
+      /* The new stack pointer does not intersect with the
+	 stack the exec server set up for us, so free that stack.  */
+      __vm_deallocate (__mach_task_self (),
+		       _hurd_stack_base, _hurd_stack_size);
+  }
+
+  if (__hurd_threadvar_stack_mask == 0)
+    {
+      /* We are not using cthreads, so we will have just a single allocated
+	 area for the per-thread variables of the main user thread.  */
+      unsigned long int i;
+      __hurd_threadvar_stack_offset
+	= (unsigned long int) malloc (__hurd_threadvar_max *
+				      sizeof (unsigned long int));
+      if (__hurd_threadvar_stack_offset == 0)
+	__libc_fatal ("Can't allocate single-threaded per-thread variables.");
+      for (i = 0; i < __hurd_threadvar_max; ++i)
+	((unsigned long int *) __hurd_threadvar_stack_offset)[i] = 0;
+    }
+
+
+  /* Turn the block of null-separated strings we were passed for the
+     arguments and environment into vectors of pointers to strings.  */
+      
+  if (! argv)
+    {
+      if (args)
+	/* Count up the arguments so we can allocate ARGV.  */
+	argc = _hurd_split_args (args, argslen, NULL);
+      if (! args || argc == 0)
+	{
+	  /* No arguments passed; set argv to { NULL }.  */
+	  argc = 0;
+	  args = NULL;
+	  argv = (char **) &args;
+	}
+    }
+
+  if (! envp)
+    {
+      if (env)
+	/* Count up the environment variables so we can allocate ENVP.  */
+	envc = _hurd_split_args (env, envlen, NULL);
+      if (! env || envc == 0)
+	{
+	  /* No environment passed; set __environ to { NULL }.  */
+	  env = NULL;
+	  envp = (char **) &env;
+	}
+    }
+
+  if (! argv)
+    {
+      /* There were some arguments.
+	 Allocate space for the vectors of pointers and fill them in.  */
+      argv = __alloca ((argc + 1) * sizeof (char *));
+      _hurd_split_args (args, argslen, argv);
+    }
+  
+  if (! envp)
+    {
+      /* There was some environment.
+	 Allocate space for the vectors of pointers and fill them in.  */
+      envp = __alloca ((envc + 1) * sizeof (char *));
+      _hurd_split_args (env, envlen, envp);
+    }
+
+  __environ = envp;
+
+  if (portarray || intarray)
+    /* Initialize library data structures, start signal processing, etc.  */
+    _hurd_init (flags, argv, portarray, portarraysize, intarray, intarraysize);
+
+  /* Random library initialization.  These functions may assume that
+     _hurd_init has already run (if it is going to), and POSIX.1 facilities
+     are initialized and available.  */
+  __libc_init (argc, argv, __environ);
+
+  /* Finally, run the user program.  */
+  (_cthread_exit_routine != NULL ? *_cthread_exit_routine : exit)
+    (main (argc, argv, __environ));
+
+  /* Should never get here.  */
+  LOSE;
+}
+
+/* Split ARGSLEN bytes at ARGS into words, breaking at NUL characters.  If
+   ARGV is not a null pointer, store a pointer to the start of each word in
+   ARGV[n], and null-terminate ARGV.  Return the number of words split.  */
+
+int
+_hurd_split_args (char *args, size_t argslen, char **argv)
+{
+  char *p = args;
+  size_t n = argslen;
+  int argc = 0;
+
+  while (n > 0)
+    {
+      char *end = memchr (p, '\0', n);
+
+      if (argv)
+	argv[argc] = p;
+      ++argc;
+
+      if (end == NULL)
+	/* The last argument is unterminated.  */
+	break;
+
+      n -= end + 1 - p;
+      p = end + 1;
+    }
+
+  if (argv)
+    argv[argc] = NULL;
+  return argc;
+}
diff --git a/sysdeps/mach/hurd/stat.c b/sysdeps/mach/hurd/stat.c
new file mode 100644
index 0000000000..e6df5e66eb
--- /dev/null
+++ b/sysdeps/mach/hurd/stat.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <hurd.h>
+
+/* Get file information about FILE in BUF.  */
+int
+DEFUN(__stat, (file, buf), CONST char *file AND struct stat *buf)
+{
+  error_t err;
+  file_t port = __file_name_lookup (file, 0, 0);
+  if (port == MACH_PORT_NULL)
+    return -1;
+  err = __io_stat (port, buf);
+  __mach_port_deallocate (__mach_task_self (), port);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__stat, stat)
diff --git a/sysdeps/mach/hurd/statbuf.h b/sysdeps/mach/hurd/statbuf.h
new file mode 100644
index 0000000000..4d97dc1c55
--- /dev/null
+++ b/sysdeps/mach/hurd/statbuf.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef	_STATBUF_H
+
+#define	_STATBUF_H	1
+
+#include <gnu/types.h>
+
+/* NOTE: The size of this structure (32 ints) is known in
+   <hurd/hurd_types.defs>, since it is used in the `io_stat' RPC.  MiG
+   does not cope at all well with the passed C structure not being of
+   the expected size.  There are some filler words at the end to allow
+   for future expansion.  To increase the size of the structure used
+   in the RPC and retain binary compatibility, we would need to assign
+   a new message number.  */
+
+struct stat
+  {
+    int st_fstype;		/* File system type.  */
+    __fsid_t st_fsid;		/* File system ID.  */
+#define	st_dev	st_fsid
+
+    __ino_t st_ino;		/* File number.  */
+    unsigned int st_gen;	/* To detect reuse of file numbers.  */
+    __dev_t st_rdev;		/* Device if special file.  */
+    __mode_t st_mode;		/* File mode.  */
+    __nlink_t st_nlink;		/* Number of links.  */
+
+    __uid_t st_uid;		/* Owner.  */
+    __gid_t st_gid;		/* Owning group.  */
+
+    __off_t st_size;		/* Size in bytes.  */
+
+    __time_t st_atime;		/* Access time, seconds */
+    unsigned long int st_atime_usec; /* and microseconds.  */
+    __time_t st_mtime;		/* Modification time, seconds */
+    unsigned long int st_mtime_usec; /* and microseconds.  */
+    __time_t st_ctime;		/* Status change time, seconds */
+    unsigned long int st_ctime_usec; /* and microseconds.  */
+
+    unsigned int st_blksize;	/* Optimal size for I/O.  */
+
+#define	_STATBUF_ST_BLKSIZE	/* Tell code we have this member.  */
+
+    unsigned int st_blocks;	/* Number of 512-byte blocks allocated.
+				   Not related to `st_blksize'.  */
+
+    __uid_t st_author;		/* File author.  */
+
+    unsigned int st_flags;	/* User-defined flags.
+				   High 16 bits can be set only by root.  */
+
+    int st_spare[11];		/* Room for future expansion.  */
+  };
+
+/* Encoding of the file mode.  */
+
+#define	__S_IFMT	0170000	/* These bits determine file type.  */
+
+/* File types.  */
+#define	__S_IFDIR	0040000	/* Directory.  */
+#define	__S_IFCHR	0020000	/* Character device.  */
+#define	__S_IFBLK	0060000	/* Block device.  */
+#define	__S_IFREG	0100000	/* Regular file.  */
+#define	__S_IFLNK	0120000	/* Symbolic link.  */
+#define	__S_IFSOCK	0140000	/* Socket.  */
+#define	__S_IFIFO	0010000	/* FIFO.  */
+
+/* Protection bits.  */
+
+#define	__S_ISUID	04000	/* Set user ID on execution.  */
+#define	__S_ISGID	02000	/* Set group ID on execution.  */
+#define	__S_ISVTX	01000	/* Save swapped text after use (sticky).  */
+#define	__S_IREAD	00400	/* Read by owner.  */
+#define	__S_IWRITE	00200	/* Write by owner.  */
+#define	__S_IEXEC	00100	/* Execute by owner.  */
+
+
+#ifdef	__USE_GNU
+/* If set, there is no benefit in caching the contents of this file.  */
+#define S_INOCACHE	000000200000
+
+/* If the S_IUSEUNK bit is set, then the S_IUNKNOWN bits (see below)
+   control access for unknown users.  If S_IUSEUNK is clear, then unknown
+   users are treated as "others" for purposes of access control.  */
+#define S_IUSEUNK	000000400000
+/* Mask of protection bits for unknown users (no effective IDs at all).  */
+#define S_IUNKNOWN      000007000000
+/* Shift S_IREAD, S_IWRITE, S_IEXEC left this many bits to produce the
+   protection bits for unknown users.  */
+#define S_IUNKSHIFT	12
+
+/* All the unused bits.  */
+#define	S_ISPARE	(~(S_IFMT|S_INOCACHE|S_IUNKNOWN|07777))
+#endif
+
+/* Default file creation mask (umask).  */
+#ifdef	__USE_BSD
+#define	CMASK		0022
+#endif
+
+
+#endif /* statbuf.h */
diff --git a/sysdeps/mach/hurd/stdio_init.c b/sysdeps/mach/hurd/stdio_init.c
new file mode 100644
index 0000000000..f083ee85dc
--- /dev/null
+++ b/sysdeps/mach/hurd/stdio_init.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <hurd/fd.h>
+#include <hurd/io.h>
+#include <hurd/term.h>
+
+/* Initialize STREAM as necessary.
+   This may change I/O functions, give a buffer, etc.
+   If no buffer is allocated, but the bufsize is set,
+   the bufsize will be used to allocate the buffer.  */
+void
+DEFUN(__stdio_init_stream, (stream), FILE *stream)
+{
+  struct hurd_fd *const d = stream->__cookie;
+  struct stat statb;
+  error_t err;
+
+  if (stream->__buffer != NULL || stream->__userbuf)
+    /* If's unbuffered by request, we can't do anything useful.  */
+    return;
+
+  /* Find out what sort of file this is.  */
+  if (err = HURD_FD_PORT_USE (d, __io_stat (port, &statb)))
+    return;
+
+  if (S_ISCHR (statb.st_mode))
+    {
+      /* It's a character device.
+	 Make it line-buffered if it's a terminal.  */
+      mach_port_t cttyid;
+      err = HURD_FD_PORT_USE (d, __term_getctty (port, &cttyid));
+      if (! err)
+	{
+	  __mach_port_deallocate (__mach_task_self (), cttyid);
+	  stream->__linebuf = 1;
+	}
+    }
+
+  /* Use the block-size field to determine
+     the system's optimal buffering size.  */
+  stream->__bufsize = statb.st_blksize;
+}
diff --git a/sysdeps/mach/hurd/symlink.c b/sysdeps/mach/hurd/symlink.c
new file mode 100644
index 0000000000..5e67c4e452
--- /dev/null
+++ b/sysdeps/mach/hurd/symlink.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <string.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/paths.h>
+#include <fcntl.h>
+
+/* Make a link to FROM called TO.  */
+int
+DEFUN(__symlink, (from, to), CONST char *from AND CONST char *to)
+{
+  error_t err;
+  file_t dir, node;
+  char *name;
+  const size_t len = strlen (from) + 1;
+  char buf[sizeof (_HURD_SYMLINK) + len];
+
+  /* A symlink is a file whose translator is "/hurd/symlink\0target\0".  */
+
+  memcpy (buf, _HURD_SYMLINK, sizeof (_HURD_SYMLINK));
+  memcpy (&buf[sizeof (_HURD_SYMLINK)], from, len);
+
+  dir = __file_name_split (to, &name);
+  if (dir == MACH_PORT_NULL)
+    return -1;
+
+  /* Create a new, unlinked node in the target directory.  */
+  err = __dir_mkfile (dir, O_WRITE, 0777 & ~_hurd_umask, &node);
+
+  if (! err)
+    /* Set the node's translator to make it a symlink.  */
+    err = __file_set_translator (node, 
+				 FS_TRANS_EXCL|FS_TRANS_SET, 
+				 FS_TRANS_EXCL|FS_TRANS_SET, 0,
+				 buf, sizeof (_HURD_SYMLINK) + len,
+				 MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND);
+
+  if (! err)
+    /* Link the node, now a valid symlink, into the target directory.  */
+    err = __dir_link (node, dir, name);
+
+  __mach_port_deallocate (__mach_task_self (), dir);
+  __mach_port_deallocate (__mach_task_self (), node);
+
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__symlink, symlink)
diff --git a/sysdeps/mach/hurd/sync.c b/sysdeps/mach/hurd/sync.c
new file mode 100644
index 0000000000..af207e6cdf
--- /dev/null
+++ b/sysdeps/mach/hurd/sync.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+
+/* Make all changes done to all files actually appear on disk.  */
+int
+DEFUN_VOID(sync)
+{
+  /* This is not actually synchronous; we don't wait.  */
+  error_t err = __USEPORT (CRDIR, __file_syncfs (port, 0, 1));
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/sys/param.h b/sysdeps/mach/hurd/sys/param.h
new file mode 100644
index 0000000000..79f3b0503a
--- /dev/null
+++ b/sysdeps/mach/hurd/sys/param.h
@@ -0,0 +1,135 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* This file is deprecated and is provided only for compatibility with
+   Unix systems.  It is unwise to include this file on programs which
+   are intended only for GNU systems.
+
+   Parts from:
+
+ * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)param.h	7.23 (Berkeley) 5/6/91
+ */
+
+
+#ifndef	_SYS_PARAM_H
+
+#define	_SYS_PARAM_H	1
+#include <features.h>
+
+#define __need_NULL
+#include <stddef.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <endian.h>
+#include <limits.h>
+#ifdef notyet
+#include <ufs/param.h>
+#endif
+
+
+/* What versions of BSD we are compatible with.  */
+#define	BSD	199306		/* System version (year & month). */
+#define BSD4_3	1
+#define BSD4_4	1
+
+#define	GNU	1994100		/* GNU version (year, month, and release).  */
+
+
+/* BSD names for some <limits.h> values.  We do not define the BSD names
+   for the values which are not statically limited, such as NOFILE.  */
+
+#define	NGROUPS		NGROUPS_MAX
+#define	MAXSYMLINKS	SYMLOOP_MAX
+#define	CANBSIZ		MAX_CANON /* XXX ? */
+
+/* ARG_MAX is unlimited, but we define NCARGS for BSD programs that want to
+   compare against some fixed limit.  */
+#define	NCARGS		INT_MAX
+
+/* There is nothing quite equivalent in GNU to Unix "mounts", but there is
+   no limit on the number of simultaneously attached filesystems.  */
+#define NMOUNT		INT_MAX
+
+
+/* Magical constants.  */
+#define	NOGROUP	65535		/* Marker for empty group set member.  */
+#define	NODEV	((dev_t) -1)	/* Non-existent device.  */
+
+
+/* Bit map related macros.  */
+#define	setbit(a,i)	((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define	clrbit(a,i)	((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define	isset(a,i)	((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define	isclr(a,i)	(((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+
+/* Macros for counting and rounding.  */
+#ifndef howmany
+#define	howmany(x, y)	(((x)+((y)-1))/(y))
+#endif
+#define	roundup(x, y)	((((x)+((y)-1))/(y))*(y))
+#define powerof2(x)	((((x)-1)&(x))==0)
+
+/* Macros for min/max.  */
+#define	MIN(a,b) (((a)<(b))?(a):(b))
+#define	MAX(a,b) (((a)>(b))?(a):(b))
+
+
+/* Scale factor for scaled integers used to count %cpu time and load avgs.
+
+   The number of CPU `tick's that map to a unique `%age' can be expressed
+   by the formula (1 / (2 ^ (FSHIFT - 11))).  The maximum load average that
+   can be calculated (assuming 32 bits) can be closely approximated using
+   the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15).  */
+
+#define	FSHIFT	11		/* Bits to right of fixed binary point.  */
+#define FSCALE	(1<<FSHIFT)
+
+#endif	 /* sys/param.h */
diff --git a/sysdeps/mach/hurd/sysd-stdio.c b/sysdeps/mach/hurd/sysd-stdio.c
new file mode 100644
index 0000000000..85dd04bad4
--- /dev/null
+++ b/sysdeps/mach/hurd/sysd-stdio.c
@@ -0,0 +1,237 @@
+/* Copyright (C) 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <hurd.h>
+#include <fcntl.h>
+#include <hurd/fd.h>
+
+
+/* Check ERR for wanting to generate a signal.  */
+
+int __stdio_fileno (void *);
+
+static inline int
+fd_fail (struct hurd_fd *fd, error_t err)
+{
+  int signo = _hurd_fd_error_signal (err);
+  if (signo)
+    _hurd_raise_signal (NULL, signo, __stdio_fileno (fd), err);
+  errno = err;
+  return -1;
+}
+
+
+/* Read up to N chars into BUF from COOKIE.
+   Return how many chars were read, 0 for EOF or -1 for error.  */
+ssize_t
+DEFUN(__stdio_read, (cookie, buf, n),
+      PTR cookie AND register char *buf AND size_t n)
+{
+  error_t err;
+  struct hurd_fd *fd = cookie;
+
+  if (! fd)
+    return __hurd_fail (EBADF);
+
+  if (err = _hurd_fd_read (fd, buf, &n))
+    return fd_fail (fd, err);
+
+  return n;
+}
+
+/* Write up to N chars from BUF to COOKIE.
+   Return how many chars were written or -1 for error.  */
+ssize_t
+DEFUN(__stdio_write, (cookie, buf, n),
+      PTR cookie AND register CONST char *buf AND size_t n)
+{
+  error_t err;
+  size_t wrote, nleft;
+  struct hurd_fd *fd = cookie;
+
+  if (! fd)
+    return __hurd_fail (EBADF);
+
+  nleft = n;
+  do
+    {
+      wrote = nleft;
+      if (err = _hurd_fd_write (fd, buf, &wrote))
+	return fd_fail (fd, err);
+      buf += wrote;
+      nleft -= wrote;
+    } while (nleft > 0);
+
+  return wrote;
+}
+
+/* Move COOKIE's file position *POS bytes, according to WHENCE.
+   The current file position is stored in *POS.
+   Returns zero if successful, nonzero if not.  */
+int
+DEFUN(__stdio_seek, (cookie, pos, whence),
+      PTR cookie AND fpos_t *pos AND int whence)
+{
+  error_t err;
+  struct hurd_fd *fd = cookie;
+  if (! fd)
+    return __hurd_fail (EBADF);
+  err = HURD_FD_PORT_USE (fd, __io_seek (port, *pos, whence, pos));
+  return err ? fd_fail (fd, err) : 0;
+}
+
+/* Close the file associated with COOKIE.
+   Return 0 for success or -1 for failure.  */
+int
+DEFUN(__stdio_close, (cookie), PTR cookie)
+{
+  error_t error = cookie ? _hurd_fd_close (cookie) : EBADF;
+  return error ? fd_fail (cookie, error) : 0;
+}
+
+
+static inline int
+modeflags (__io_mode m)
+{
+  int flags = 0;
+  if (m.__read)
+    flags |= O_READ;
+  if (m.__write)
+    flags |= O_WRITE;
+  if (m.__append)
+    flags |= O_APPEND;
+  if (m.__create)
+    flags |= O_CREAT;
+  if (m.__truncate)
+    flags |= O_TRUNC;
+  if (m.__exclusive)
+    flags |= O_EXCL;
+  return flags;
+}
+
+/* Open FILENAME with the mode in M.  */
+int
+DEFUN(__stdio_open, (filename, m, cookieptr),
+      CONST char *filename AND __io_mode m AND PTR *cookieptr)
+{
+  int flags;
+  file_t port;
+  struct hurd_fd *d;
+
+  flags = modeflags (m);
+  port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask);
+  if (port == MACH_PORT_NULL)
+    return -1;
+
+  HURD_CRITICAL_BEGIN;
+  d = _hurd_alloc_fd (NULL, 0);
+  if (d != NULL)
+    {
+      _hurd_port2fd (d, port, flags);
+      __spin_unlock (&d->port.lock);
+    }
+  HURD_CRITICAL_END;
+
+  *cookieptr = d;
+  return 0;
+}
+
+
+/* Open FILENAME with the mode in M.  Use the same magic cookie
+   already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN.  */
+int
+DEFUN(__stdio_reopen, (filename, m, cookieptr),
+      CONST char *filename AND __io_mode m AND
+      PTR *cookieptr AND __io_close_fn closefn)
+{
+  int flags;
+  file_t port;
+  struct hurd_fd *d;
+
+  if (closefn != __stdio_close)
+    {
+      /* The old cookie is Not Of The Body.
+	 Just close it and do a normal open.  */
+      (*closefn) (*cookieptr);
+      return __stdio_open (filename, m, cookieptr);
+    }
+
+  /* Open a new port on the file.  */
+  flags = modeflags (m);
+  port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask);
+
+  /* Install the new port in the same file descriptor slot the old cookie
+     points to.  If opening the file failed, PORT will be MACH_PORT_NULL
+     and installing it in the descriptor will have the effect of closing
+     the old descriptor.  */
+
+  d = *cookieptr;
+  HURD_CRITICAL_BEGIN;
+  __spin_lock (&d->port.lock);
+  _hurd_port2fd (d, port, flags);
+  __spin_unlock (&d->port.lock);
+  HURD_CRITICAL_END;
+
+  return port == MACH_PORT_NULL ? -1 : 0;
+}
+
+
+/* Write a message to the error output.
+   Try hard to make it really get out.  */
+void
+DEFUN(__stdio_errmsg, (msg, len), CONST char *msg AND size_t len)
+{
+  io_t server;
+  mach_msg_type_number_t wrote;
+
+  server = __getdport (2);
+  __io_write (server, msg, len, -1, &wrote);
+  __mach_port_deallocate (__mach_task_self (), server);
+}
+
+
+/* Return the POSIX.1 file descriptor associated with COOKIE,
+   or -1 for errors.  If COOKIE does not relate to any POSIX.1 file
+   descriptor, this should return -1 with errno set to EOPNOTSUPP.  */
+int
+DEFUN(__stdio_fileno, (cookie), PTR cookie)
+{
+  int fd;
+
+  if (! cookie)
+    return __hurd_fail (EBADF);
+
+  __mutex_lock (&_hurd_dtable_lock);
+  for (fd = 0; fd < _hurd_dtablesize; ++fd)
+    if (_hurd_dtable[fd] == cookie)
+      {
+	__mutex_unlock (&_hurd_dtable_lock);
+	return fd;
+      }
+  __mutex_unlock (&_hurd_dtable_lock);
+
+  /* This should never happen, because this function should not be
+     installed as a stream's __fileno function unless that stream's cookie
+     points to a file descriptor.  */
+  errno = EGRATUITOUS;
+  return -1;
+}
diff --git a/sysdeps/mach/hurd/telldir.c b/sysdeps/mach/hurd/telldir.c
new file mode 100644
index 0000000000..7ce8d1f061
--- /dev/null
+++ b/sysdeps/mach/hurd/telldir.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Return the current position of DIRP.  */
+off_t
+DEFUN(telldir, (dirp), DIR *dirp)
+{
+  return dirp->__entry_ptr;
+}
diff --git a/sysdeps/mach/hurd/truncate.c b/sysdeps/mach/hurd/truncate.c
new file mode 100644
index 0000000000..7453bfb3a9
--- /dev/null
+++ b/sysdeps/mach/hurd/truncate.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <hurd.h>
+#include <fcntl.h>
+
+/* Truncate FILE_NAME to LENGTH bytes.  */
+int
+DEFUN(truncate, (file_name, length),
+      CONST char *file_name AND off_t length)
+{
+  error_t err;
+  file_t file = __file_name_lookup (file_name, O_WRITE, 0);
+
+  if (file == MACH_PORT_NULL)
+    return -1;
+
+  err = __file_truncate (file, length);
+  __mach_port_deallocate (__mach_task_self (), file);
+
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
diff --git a/sysdeps/mach/hurd/ttyname.c b/sysdeps/mach/hurd/ttyname.c
new file mode 100644
index 0000000000..5b8be3c629
--- /dev/null
+++ b/sysdeps/mach/hurd/ttyname.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/term.h>
+#include <hurd/fd.h>
+
+/* 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.  */
+char *
+ttyname (int fd)
+{
+  error_t err;
+  static char nodename[1024];	/* XXX */
+
+  nodename[0] = '\0';
+  if (err = HURD_DPORT_USE (fd, __term_get_nodename (port, nodename)))
+    return __hurd_dfail (fd, err), NULL;
+
+  return nodename;
+}
diff --git a/sysdeps/mach/hurd/umask.c b/sysdeps/mach/hurd/umask.c
new file mode 100644
index 0000000000..0848dd77cd
--- /dev/null
+++ b/sysdeps/mach/hurd/umask.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991, 1992, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <sys/stat.h>
+#include <hurd.h>
+
+/* Set the file creation mask to MASK, returning the old mask.  */
+mode_t
+DEFUN(__umask, (mask), mode_t mask)
+{
+  mode_t omask;
+  mask &= 0777;
+  omask = _hurd_umask;
+  _hurd_umask = mask;
+  return omask;
+}
+
+weak_alias (__umask, umask)
diff --git a/sysdeps/mach/hurd/uname.c b/sysdeps/mach/hurd/uname.c
new file mode 100644
index 0000000000..74d9d3799f
--- /dev/null
+++ b/sysdeps/mach/hurd/uname.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1992, 1993, 1994 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sys/utsname.h>
+#include <hurd.h>
+#include <hurd/startup.h>
+
+int
+uname (struct utsname *uname)
+{
+  error_t err;
+
+  err = __USEPORT (PROC, __proc_uname (port, uname));
+
+  return err ? __hurd_fail (err) : 0;
+}
diff --git a/sysdeps/mach/hurd/unlink.c b/sysdeps/mach/hurd/unlink.c
new file mode 100644
index 0000000000..b71d7f9f54
--- /dev/null
+++ b/sysdeps/mach/hurd/unlink.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <hurd.h>
+
+
+/* Remove the link named NAME.  */
+int
+DEFUN(__unlink, (name), CONST char *name)
+{
+  error_t err;
+  file_t dir;
+  CONST char *file;
+
+  dir = __file_name_split (name, (char **) &file);
+  if (dir == MACH_PORT_NULL)
+    return -1;
+
+  err = __dir_unlink (dir, file);
+  __mach_port_deallocate (__mach_task_self (), dir);
+
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__unlink, unlink)
diff --git a/sysdeps/mach/hurd/utimes.c b/sysdeps/mach/hurd/utimes.c
new file mode 100644
index 0000000000..f8f042598b
--- /dev/null
+++ b/sysdeps/mach/hurd/utimes.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <stddef.h>
+#include <hurd.h>
+
+/* Change the access time of FILE to TVP[0] and
+   the modification time of FILE to TVP[1].  */
+int
+DEFUN(__utimes, (file, tvp),
+      CONST char *file AND struct timeval tvp[2])
+{
+  error_t err;
+  file_t f = __file_name_lookup (file, 0, 0);
+  if (f == MACH_PORT_NULL)
+    return -1;
+  err = __file_utimes (f,
+		       *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
+  __mach_port_deallocate (__mach_task_self (), f);
+  if (err)
+    return __hurd_fail (err);
+  return 0;
+}
+
+weak_alias (__utimes, utimes)
diff --git a/sysdeps/mach/hurd/wait4.c b/sysdeps/mach/hurd/wait4.c
new file mode 100644
index 0000000000..61e985505e
--- /dev/null
+++ b/sysdeps/mach/hurd/wait4.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <hurd.h>
+#include <hurd/port.h>
+
+pid_t
+__wait4 (pid_t pid, __WAIT_STATUS_DEFN stat_loc,
+	 int options, struct rusage *usage)
+{
+  pid_t dead;
+  error_t err;
+  struct rusage ignored;
+
+  err = __USEPORT (PROC, __proc_wait (port, pid, options, stat_loc,
+				      usage ?: &ignored, &dead));
+
+  return err ? (pid_t) __hurd_fail (err) : dead;
+}
+
+weak_alias (__wait4, wait4)
diff --git a/sysdeps/mach/hurd/write.c b/sysdeps/mach/hurd/write.c
new file mode 100644
index 0000000000..c6c3e6c668
--- /dev/null
+++ b/sysdeps/mach/hurd/write.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995 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 Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <hurd.h>
+#include <hurd/fd.h>
+
+ssize_t
+DEFUN(__write, (fd, buf, nbytes),
+      int fd AND CONST PTR buf AND size_t nbytes)
+{
+  error_t err = HURD_FD_USE (fd, _hurd_fd_write (descriptor, buf, &nbytes));
+  return err ? __hurd_dfail (fd, err) : nbytes;
+}
+
+
+
+weak_alias (__write, write)