summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-05-04 09:46:57 +0000
committerRoland McGrath <roland@gnu.org>1996-05-04 09:46:57 +0000
commit8f0c527e13b836a44fedbf6abc84e1901e2cc10d (patch)
tree2ef83b10742b3fa4e7dd89b7b55229ebf48c6818
parent7a12c6bba750ca500009854db3a0fcdfb1ad61a7 (diff)
downloadglibc-8f0c527e13b836a44fedbf6abc84e1901e2cc10d.tar.gz
glibc-8f0c527e13b836a44fedbf6abc84e1901e2cc10d.tar.xz
glibc-8f0c527e13b836a44fedbf6abc84e1901e2cc10d.zip
Sat May 4 05:44:25 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
	* hurd/hurd-raise.c (_hurd_raise_signal): Pass sigcode in msg_sig_post
	rpc.

	* hurd/hurdmsg.c (_S_msg_set_environment): Use argz.h functions
	instead of _hurd_split_args.
	(_S_msg_*_exec_flags): Functions removed.
	(_S_msg_startup_dosync): Stub removed.

Sat May  4 02:11:55 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>

	* sysdeps/mach/hurd/ptrace.c: Set _hurdsig_traced instead of
	EXEC_TRACED bit in _hurd_exec_flags.
	Pass sigcode arg in msg_sig_post_untraced rpc.

	* sysdeps/mach/hurd/access.c: Don't pass io port in
	auth_user_authenticate rpc.

	* posix/sched.h: Fix typos.

	* sysdeps/mach/hurd/fork.c: Use new critical section lock.
	Clear _hurdsig_traced instead of EXEC_TRACED.

	* sysdeps/stub/nanosleep.c (nanosleep): Fix typo.

	* wcsmbs/wcstol.c: Find strtol.c in ../stdlib.
	* wcsmbs/wcstof.c: Find strtod.c in ../stdlib.
	* wcsmbs/wcstod.c: Likewise.
	* wcsmbs/wcstold.c: Likewise.

	* wcsmbs/wcwidth.h: Find cname-lookup.h in ../wctype.

	* string/envz.c (envz_entry): Use const.
	(envz_get, envz_remove): Likewise.
	(envz_entry): Return char *, not const char *.

	* string/envz.h: Fix decl.

	* string/argz-create.c: Use const in prototype.
	* string/argz-next.c: Likewise.

	* sysdeps/mach/hurd/sigprocmask.c: Pass sigcode arg to msg_sig_post.
	* sysdeps/mach/hurd/i386/sigreturn.c: Likewise.
	* sysdeps/mach/hurd/sigsuspend.c: Likewise.
	* sysdeps/mach/hurd/kill.c: Likewise.

	* hurd/hurdexec.c (_hurd_exec): Use new critical section lock.
	* hurd/catch-exc.c (_S_catch_exception_raise): Likewise.
	* hurd/sigunwind.c (_hurdsig_longjmp_from_handler): Likewise.
	* hurd/thread-cancel.c (hurd_thread_cancel, hurd_check_cancel):
	Likewise.
	* sysdeps/mach/hurd/jmp-unwind.c (_longjmp_unwind): Likewise.
	* sysdeps/mach/hurd/sigaction.c: Likewise.

	* sysdeps/mach/hurd/errnos.awk: Don't use ARGV in comment; it can
	change meaninglessly.

	* hurd/hurd/signal.h (struct hurd_sigstate): Replace critical section
 	flag with a spin lock.
	(_hurd_critical_section_lock): Use spin_try_lock on that to see if we
 	get it.  No need to take SS->lock at all.
	(_hurd_critical_section_unlock): Unlock SS->critical_section_lock
	instead of clearing the old flag member.
	* hurd/hurdsig.c (_hurd_internal_post_signal): Use spin_lock_locked to
	test the critical section state.

	* hurd/hurdinit.c (_hurd_init): Set _hurdsig_traced from the intarray.

	* hurd/hurdkill.c (_hurd_sig_post): Pass 0 sigcode in msg_sig_post.

	* hurd/hurdsig.c (_hurd_internal_post_signal): Test _hurdsig_traced
 	instead of testing (_hurd_exec_flags & EXEC_TRACED).
	(_S_msg_sig_post): Take sigcode arg and pass it through.
	(_S_msg_sig_post_untraced): Likewise.
	(reauth_proc): Don't pass proc port in auth_user_authenticate.

	* hurd/setauth.c (_hurd_setauth): Don't pass object ports in
	auth_user_authenticate RPCs, just the one-off rendezvous port.
	* hurd/dtable.c (reauth_dtable): Likewise.
	* hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Likewise.

	* hurd/hurdexec.c (_hurd_exec): Pass 0 flags to file_exec.
	Pass sigcode arg to msg_sig_post.

	* string/argz.h (argz_create): Use const in prototype.

	* hurd/hurdinit.c (_hurd_proc_init): Test _hurdsig_traced instead of
	testing (_hurd_exec_flags & EXEC_TRACED).
	Pass sigcode arg to msg_sig_post.

	* hurd/hurd.h: Declare _hurdsig_traced.

	* string/argz.h (__argz_next): Cast ENTRY before returning it.

	* hurd/hurd/signal.h (_hurd_critical_section_unlock): Pass sigcode arg
	to msg_sig_post.

	* hurd/path-lookup.c: New file.
	* hurd/Makefile (routines): Add path-lookup.
	* hurd/hurd/lookup.h: Declare file_name_path_scan,
	hurd_file_name_path_lookup.
	* hurd/hurd.h: Declare file_name_path_lookup.

	* sysdeps/mach/hurd/select.c: The io_select rpc no longer has a TAG_ID
	argument.  Instead, use a separate reply port for each RPC and put them
	all in a port set to wait for slow replies.
-rw-r--r--ChangeLog108
-rw-r--r--hurd/Makefile1
-rw-r--r--hurd/catch-exc.c4
-rw-r--r--hurd/dtable.c10
-rw-r--r--hurd/hurd-raise.c4
-rw-r--r--hurd/hurd.h16
-rw-r--r--hurd/hurd/lookup.h31
-rw-r--r--hurd/hurd/signal.h38
-rw-r--r--hurd/hurdexec.c23
-rw-r--r--hurd/hurdinit.c8
-rw-r--r--hurd/hurdkill.c2
-rw-r--r--hurd/hurdlookup.c2
-rw-r--r--hurd/hurdmsg.c53
-rw-r--r--hurd/hurdsig.c18
-rw-r--r--hurd/path-lookup.c120
-rw-r--r--hurd/setauth.c7
-rw-r--r--hurd/sigunwind.c4
-rw-r--r--hurd/thread-cancel.c12
-rw-r--r--posix/sched.h12
-rw-r--r--string/argz-create.c5
-rw-r--r--string/argz-next.c2
-rw-r--r--string/argz.h62
-rw-r--r--string/envz.c12
-rw-r--r--string/envz.h4
-rw-r--r--sysdeps/mach/hurd/access.c5
-rw-r--r--sysdeps/mach/hurd/errnos.awk5
-rw-r--r--sysdeps/mach/hurd/errnos.h2
-rw-r--r--sysdeps/mach/hurd/fork.c6
-rw-r--r--sysdeps/mach/hurd/i386/sigreturn.c2
-rw-r--r--sysdeps/mach/hurd/jmp-unwind.c5
-rw-r--r--sysdeps/mach/hurd/kill.c2
-rw-r--r--sysdeps/mach/hurd/ptrace.c24
-rw-r--r--sysdeps/mach/hurd/select.c189
-rw-r--r--sysdeps/mach/hurd/sigaction.c8
-rw-r--r--sysdeps/mach/hurd/sigprocmask.c4
-rw-r--r--sysdeps/mach/hurd/sigsuspend.c8
-rw-r--r--sysdeps/stub/nanosleep.c2
-rw-r--r--wcsmbs/wcstod.c2
-rw-r--r--wcsmbs/wcstof.c2
-rw-r--r--wcsmbs/wcstol.c2
-rw-r--r--wcsmbs/wcstold.c2
-rw-r--r--wcsmbs/wcwidth.h4
42 files changed, 526 insertions, 306 deletions
diff --git a/ChangeLog b/ChangeLog
index b4b82d9d47..7bb59dbbd6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,113 @@
+Sat May  4 05:44:25 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+	* hurd/hurd-raise.c (_hurd_raise_signal): Pass sigcode in msg_sig_post
+	rpc.
+
+	* hurd/hurdmsg.c (_S_msg_set_environment): Use argz.h functions
+	instead of _hurd_split_args.
+	(_S_msg_*_exec_flags): Functions removed.
+	(_S_msg_startup_dosync): Stub removed.
+
+Sat May  4 02:11:55 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+	* sysdeps/mach/hurd/ptrace.c: Set _hurdsig_traced instead of
+	EXEC_TRACED bit in _hurd_exec_flags.
+	Pass sigcode arg in msg_sig_post_untraced rpc.
+
+	* sysdeps/mach/hurd/access.c: Don't pass io port in
+	auth_user_authenticate rpc.
+
+	* posix/sched.h: Fix typos.
+
+	* sysdeps/mach/hurd/fork.c: Use new critical section lock.
+	Clear _hurdsig_traced instead of EXEC_TRACED.
+
+	* sysdeps/stub/nanosleep.c (nanosleep): Fix typo.
+
+	* wcsmbs/wcstol.c: Find strtol.c in ../stdlib.
+	* wcsmbs/wcstof.c: Find strtod.c in ../stdlib.
+	* wcsmbs/wcstod.c: Likewise.
+	* wcsmbs/wcstold.c: Likewise.
+
+	* wcsmbs/wcwidth.h: Find cname-lookup.h in ../wctype.
+
+	* string/envz.c (envz_entry): Use const.
+	(envz_get, envz_remove): Likewise.
+	(envz_entry): Return char *, not const char *.
+
+	* string/envz.h: Fix decl.
+
+	* string/argz-create.c: Use const in prototype.
+	* string/argz-next.c: Likewise.
+
 Fri May  3 13:32:08 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
 
+	* sysdeps/mach/hurd/sigprocmask.c: Pass sigcode arg to msg_sig_post.
+	* sysdeps/mach/hurd/i386/sigreturn.c: Likewise.
+	* sysdeps/mach/hurd/sigsuspend.c: Likewise.
+	* sysdeps/mach/hurd/kill.c: Likewise.
+
+	* hurd/hurdexec.c (_hurd_exec): Use new critical section lock.
+	* hurd/catch-exc.c (_S_catch_exception_raise): Likewise.
+	* hurd/sigunwind.c (_hurdsig_longjmp_from_handler): Likewise.
+	* hurd/thread-cancel.c (hurd_thread_cancel, hurd_check_cancel):
+	Likewise.
+	* sysdeps/mach/hurd/jmp-unwind.c (_longjmp_unwind): Likewise.
+	* sysdeps/mach/hurd/sigaction.c: Likewise.
+
+	* sysdeps/mach/hurd/errnos.awk: Don't use ARGV in comment; it can
+	change meaninglessly.
+
+	* hurd/hurd/signal.h (struct hurd_sigstate): Replace critical section
+ 	flag with a spin lock.
+	(_hurd_critical_section_lock): Use spin_try_lock on that to see if we
+ 	get it.  No need to take SS->lock at all.
+	(_hurd_critical_section_unlock): Unlock SS->critical_section_lock
+	instead of clearing the old flag member.
+	* hurd/hurdsig.c (_hurd_internal_post_signal): Use spin_lock_locked to
+	test the critical section state.
+
+	* hurd/hurdinit.c (_hurd_init): Set _hurdsig_traced from the intarray.
+
+	* hurd/hurdkill.c (_hurd_sig_post): Pass 0 sigcode in msg_sig_post.
+
+	* hurd/hurdsig.c (_hurd_internal_post_signal): Test _hurdsig_traced
+ 	instead of testing (_hurd_exec_flags & EXEC_TRACED).
+	(_S_msg_sig_post): Take sigcode arg and pass it through.
+	(_S_msg_sig_post_untraced): Likewise.
+	(reauth_proc): Don't pass proc port in auth_user_authenticate.
+
+	* hurd/setauth.c (_hurd_setauth): Don't pass object ports in
+	auth_user_authenticate RPCs, just the one-off rendezvous port.
+	* hurd/dtable.c (reauth_dtable): Likewise.
+	* hurd/hurdlookup.c (__hurd_file_name_lookup_retry): Likewise.
+
+	* hurd/hurdexec.c (_hurd_exec): Pass 0 flags to file_exec.
+	Pass sigcode arg to msg_sig_post.
+
+	* string/argz.h (argz_create): Use const in prototype.
+
+	* hurd/hurdinit.c (_hurd_proc_init): Test _hurdsig_traced instead of
+	testing (_hurd_exec_flags & EXEC_TRACED).
+	Pass sigcode arg to msg_sig_post.
+
+	* hurd/hurd.h: Declare _hurdsig_traced.
+
+	* string/argz.h (__argz_next): Cast ENTRY before returning it.
+
+	* hurd/hurd/signal.h (_hurd_critical_section_unlock): Pass sigcode arg
+	to msg_sig_post.
+
+	* hurd/path-lookup.c: New file.
+	* hurd/Makefile (routines): Add path-lookup.
+	* hurd/hurd/lookup.h: Declare file_name_path_scan,
+	hurd_file_name_path_lookup.
+	* hurd/hurd.h: Declare file_name_path_lookup.
+
+	* sysdeps/mach/hurd/select.c: The io_select rpc no longer has a TAG_ID
+	argument.  Instead, use a separate reply port for each RPC and put them
+	all in a port set to wait for slow replies.
+
 	* intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in
 	LOCALE_ALIAS_PATH.
 
diff --git a/hurd/Makefile b/hurd/Makefile
index af3ba2dad1..3a9d08e4a4 100644
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -42,6 +42,7 @@ server-interfaces	:= hurd/msg
 
 routines = hurdstartup hurdinit \
 	   hurdid hurdlookup hurdpid hurdrlimit hurdprio hurdexec \
+	   path-lookup \
 	   setauth \
 	   pid2task task2pid \
 	   getuids setuids getumask fchroot \
diff --git a/hurd/catch-exc.c b/hurd/catch-exc.c
index 72e06db1d3..8ab38a2a61 100644
--- a/hurd/catch-exc.c
+++ b/hurd/catch-exc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1995, 1996 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
@@ -64,7 +64,7 @@ _S_catch_exception_raise (mach_port_t port,
 	 no code should do anything that can fault while holding the
 	 sigstate lock.  */
 
-      ss->critical_section = 0;
+      __spin_unlock (&ss->critical_section_lock);
       ss->context = NULL;
       __spin_unlock (&ss->lock);
     }
diff --git a/hurd/dtable.c b/hurd/dtable.c
index ea683d0b0d..d1ee999857 100644
--- a/hurd/dtable.c
+++ b/hurd/dtable.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 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
@@ -173,7 +173,7 @@ static void
 ctty_new_pgrp (void)
 {
   int i;
-  
+
   HURD_CRITICAL_BEGIN;
   __mutex_lock (&_hurd_dtable_lock);
 
@@ -226,7 +226,7 @@ reauth_dtable (void)
     {
       struct hurd_fd *const d = _hurd_dtable[i];
       mach_port_t new, newctty, ref;
-      
+
       if (d == NULL)
 	/* Nothing to do for an unused descriptor cell.  */
 	continue;
@@ -235,14 +235,13 @@ reauth_dtable (void)
 
       /* Take the descriptor cell's lock.  */
       __spin_lock (&d->port.lock);
-      
+
       /* Reauthenticate the descriptor's port.  */
       if (d->port.port != MACH_PORT_NULL &&
 	  ! __io_reauthenticate (d->port.port,
 				 ref, MACH_MSG_TYPE_MAKE_SEND) &&
 	  ! __USEPORT (AUTH, __auth_user_authenticate
 		       (port,
-			d->port.port,
 			ref, MACH_MSG_TYPE_MAKE_SEND,
 			&new)))
 	{
@@ -254,7 +253,6 @@ reauth_dtable (void)
 				     ref, MACH_MSG_TYPE_MAKE_SEND) &&
 	      ! __USEPORT (AUTH, __auth_user_authenticate
 			   (port,
-			    d->ctty.port,
 			    ref, MACH_MSG_TYPE_MAKE_SEND,
 			    &newctty)))
 	    _hurd_port_set (&d->ctty, newctty);
diff --git a/hurd/hurd-raise.c b/hurd/hurd-raise.c
index ad01ab9f89..59179da5f6 100644
--- a/hurd/hurd-raise.c
+++ b/hurd/hurd-raise.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1995, 1996 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
@@ -44,5 +44,5 @@ _hurd_raise_signal (struct hurd_sigstate *ss,
 
   /* 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 ());
+  __msg_sig_post (_hurd_msgport, signo, sigcode, __mach_task_self ());
 }
diff --git a/hurd/hurd.h b/hurd/hurd.h
index 55be1579fb..212db45753 100644
--- a/hurd/hurd.h
+++ b/hurd/hurd.h
@@ -76,6 +76,7 @@ extern int _hurd_exec_flags;	/* Flags word passed in exec_startup.  */
 extern struct hurd_port *_hurd_ports;
 extern unsigned int _hurd_nports;
 extern volatile mode_t _hurd_umask;
+extern sigset_t _hurdsig_traced;
 
 /* Shorthand macro for internal library code referencing _hurd_ports (see
    <hurd/port.h>).  */
@@ -183,6 +184,21 @@ extern file_t file_name_lookup_under (file_t startdir, const char *file,
 				      int flags, mode_t mode);
 
 
+/* Lookup FILE_NAME and return the node opened with FLAGS & MODE
+   (see hurd_file_name_lookup for details), but a simple file name (without
+   any directory prefixes) will be consecutively prefixed with the pathnames
+   in the `:' separated list PATH until one succeeds in a successful lookup.
+   If none succeed, then the first error that wasn't ENOENT is returned, or
+   ENOENT if no other errors were returned.  If PREFIXED_NAME is non-NULL,
+   then if the result is looked up directly, *PREFIXED_NAME is set to NULL, and
+   if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
+   malloc'd storage containing the prefixed name.  */
+extern file_t file_name_path_lookup (const char *file_name, const char *path,
+				     int flags, mode_t mode,
+				     char **prefixed_name);
+
+
+
 /* Open a file descriptor on a port.  FLAGS are as for `open'; flags
    affected by io_set_openmodes are not changed by this.  If successful,
    this consumes a user reference for PORT (which will be deallocated on
diff --git a/hurd/hurd/lookup.h b/hurd/hurd/lookup.h
index 6911b8f5b9..565ab317c8 100644
--- a/hurd/hurd/lookup.h
+++ b/hurd/hurd/lookup.h
@@ -1,5 +1,5 @@
 /* Declarations of file name translation functions for the GNU Hurd.
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 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
@@ -98,4 +98,33 @@ error_t hurd_file_name_lookup_retry (error_t (*use_init_port)
 				     file_t *result);
 
 
+/* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and
+   return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to
+   NULL).  Otherwise, call FUN repeatedly with FILE_NAME prefixed with each
+   successive `:' separated element of PATH, returning whenever FUN returns
+   0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting
+   prefixed path).  If FUN never returns 0, return the first non-ENOENT
+   return value, or ENOENT if there is none.  */
+error_t file_name_path_scan (const char *file_name, const char *path,
+			     error_t (*fun)(const char *name),
+			     char **prefixed_name);
+
+/* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result
+   (see hurd_file_name_lookup for details), but a simple filename (without
+   any directory prefixes) will be consectutively prefixed with the pathnames
+   in the `:' separated list PATH until one succeeds in a successful lookup.
+   If none succeed, then the first error that wasn't ENOENT is returned, or
+   ENOENT if no other errors were returned.  If PREFIXED_NAME is non-NULL,
+   then if RESULT is looked up directly, *PREFIXED_NAME is set to NULL, and
+   if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
+   malloced storage containing the prefixed name.  */
+error_t hurd_file_name_path_lookup (error_t (*use_init_port)
+				    (int which,
+				     error_t (*operate) (mach_port_t)),
+				    file_t (*get_dtable_port) (int fd),
+				    const char *file_name, const char *path,
+				    int flags, mode_t mode,
+				    file_t *result, char **prefixed_name);
+
+
 #endif	/* hurd/lookup.h */
diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
index 1973bcdb3c..fdaafdf459 100644
--- a/hurd/hurd/signal.h
+++ b/hurd/hurd/signal.h
@@ -47,9 +47,9 @@ struct hurd_signal_preempter;	/* <hurd/sigpreempt.h> */
 
 struct hurd_sigstate
   {
-    spin_lock_t lock;		/* Locks most of the rest of the structure.  */
+    spin_lock_t critical_section_lock; /* Held if in critical section.  */
 
-    int critical_section;	/* Nonzero if in critical section.  */
+    spin_lock_t lock;		/* Locks most of the rest of the structure.  */
 
     thread_t thread;
     struct hurd_sigstate *next; /* Linked-list of thread sigstates.  */
@@ -159,27 +159,22 @@ _hurd_critical_section_lock (void)
     (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
   struct hurd_sigstate *ss = *location;
   if (ss == NULL)
-    /* The thread variable is unset; this must be the first time we've
-       asked for it.  In this case, the critical section flag cannot
-       possible already be set.  Look up our sigstate structure the slow
-       way; this locks the sigstate lock.  */
-    ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
-  else
-    __spin_lock (&ss->lock);
-
-  if (ss->critical_section)
     {
-      /* We are already in a critical section, so do nothing.  */
+      /* The thread variable is unset; this must be the first time we've
+	 asked for it.  In this case, the critical section flag cannot
+	 possible already be set.  Look up our sigstate structure the slow
+	 way; this locks the sigstate lock.  */
+      ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
       __spin_unlock (&ss->lock);
-      return NULL;
     }
 
-  /* Set the critical section flag so no signal handler will run.  */
-  ss->critical_section = 1;
-  __spin_unlock (&ss->lock);
+  if (! __spin_try_lock (&ss->critical_section_lock))
+    /* We are already in a critical section, so do nothing.  */
+    return NULL;
 
-  /* Return our sigstate pointer; this will be passed to
-     _hurd_critical_section_unlock to clear the critical section flag. */
+  /* With the critical section lock held no signal handler will run.
+     Return our sigstate pointer; this will be passed to
+     _hurd_critical_section_unlock to unlock it.  */
   return ss;
 }
 
@@ -191,19 +186,18 @@ _hurd_critical_section_unlock (void *our_lock)
     return;
   else
     {
-      /* It was us who acquired the critical section lock.  Clear the
-	 critical section flag.  */
+      /* It was us who acquired the critical section lock.  Unlock it.  */
       struct hurd_sigstate *ss = our_lock;
       sigset_t pending;
       __spin_lock (&ss->lock);
-      ss->critical_section = 0;
+      __spin_unlock (&ss->critical_section_lock);
       pending = ss->pending & ~ss->blocked;
       __spin_unlock (&ss->lock);
       if (pending)
 	/* There are unblocked signals pending, which weren't
 	   delivered because we were in the critical section.
 	   Tell the signal thread to deliver them now.  */
-	__msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+	__msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
     }
 }
 
diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c
index 7893c9177b..4c0d8ae5e5 100644
--- a/hurd/hurdexec.c
+++ b/hurd/hurdexec.c
@@ -25,6 +25,7 @@ Cambridge, MA 02139, USA.  */
 #include <hurd.h>
 #include <hurd/fd.h>
 #include <hurd/signal.h>
+#include <assert.h>
 #include <argz.h>
 
 /* Overlay TASK, executing FILE with arguments ARGV and environment ENVP.
@@ -35,7 +36,7 @@ _hurd_exec (task_t task, file_t file,
 	    char *const argv[], char *const envp[])
 {
   error_t err;
-  char *args, *env, *ap;
+  char *args, *env;
   size_t argslen, envlen;
   int ints[INIT_INT_MAX];
   mach_port_t ports[_hurd_nports];
@@ -44,10 +45,10 @@ _hurd_exec (task_t task, file_t file,
   unsigned int dtablesize, i;
   struct hurd_port **dtable_cells;
   struct hurd_userlink *ulink_dtable;
-  char *const *p;
   struct hurd_sigstate *ss;
   mach_port_t *please_dealloc, *pdp;
 
+  /* XXX needs to be hurdmalloc XXX */
   if (err = __argz_create (argv, &args, &argslen))
     return err;
   if (err = __argz_create (envp, &env, &envlen))
@@ -89,6 +90,10 @@ _hurd_exec (task_t task, file_t file,
       }
 
   ss = _hurd_self_sigstate ();
+
+  assert (! __spin_lock_locked (&ss->critical_section_lock));
+  __spin_lock (&ss->critical_section_lock);
+
   __spin_lock (&ss->lock);
   ints[INIT_SIGMASK] = ss->blocked;
   ints[INIT_SIGPENDING] = ss->pending;
@@ -105,7 +110,6 @@ _hurd_exec (task_t task, file_t file,
      critical section flag avoids anything we call trying to acquire the
      sigstate lock.  */
 
-  ss->critical_section = 1;
   __spin_unlock (&ss->lock);
 
   /* Pack up the descriptor table to give the new program.  */
@@ -192,8 +196,7 @@ _hurd_exec (task_t task, file_t file,
 	  *pdp++ = dtable[i];
       }
 
-    err = __file_exec (file, task,
-		       _hurd_exec_flags & EXEC_INHERITED,
+    err = __file_exec (file, task, 0,
 		       args, argslen, env, envlen,
 		       dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
 		       ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
@@ -219,15 +222,7 @@ _hurd_exec (task_t task, file_t file,
   __mutex_unlock (&_hurd_dtable_lock);
 
   /* Safe to let signals happen now.  */
-  {
-    sigset_t pending;
-    __spin_lock (&ss->lock);
-    ss->critical_section = 0;
-    pending = ss->pending & ~ss->blocked;
-    __spin_unlock (&ss->lock);
-    if (pending)
-      __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
-  }
+  _hurd_critical_section_unlock (ss);
 
  outargs:
   free (args);
diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c
index e7558c3ef7..cd37065f93 100644
--- a/hurd/hurdinit.c
+++ b/hurd/hurdinit.c
@@ -30,6 +30,7 @@ int _hurd_exec_flags;
 struct hurd_port *_hurd_ports;
 unsigned int _hurd_nports;
 mode_t _hurd_umask;
+sigset_t _hurdsig_traced;
 
 error_t
 _hurd_ports_use (int which, error_t (*operate) (mach_port_t))
@@ -78,6 +79,9 @@ _hurd_init (int flags, char **argv,
   else
     _hurd_umask = CMASK;
 
+  if (intarraysize > INIT_TRACEMASK)
+    _hurdsig_traced = intarray[INIT_TRACEMASK];
+
   /* All done with init ints and ports.  */
   __vm_deallocate (__mach_task_self (),
 		   (vm_address_t) intarray,
@@ -147,11 +151,11 @@ _hurd_proc_init (char **argv)
      here, like _hurd_pid, are already initialized.  */
   RUN_HOOK (_hurd_proc_subinit, ());
 
-  if (_hurd_exec_flags & EXEC_TRACED)
+  if (_hurdsig_traced)
     /* This process is "traced", meaning it should stop on signals or exec.
        We are all set up now to handle signals.  Stop ourselves, to inform
        our parent (presumably a debugger) that the exec has completed.  */
-    __msg_sig_post (_hurd_msgport, SIGTRAP, __mach_task_self ());
+    __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ());
 }
 
 /* Called when we get a message telling us to change our proc server port.  */
diff --git a/hurd/hurdkill.c b/hurd/hurdkill.c
index a8f101d768..4fab0346f6 100644
--- a/hurd/hurdkill.c
+++ b/hurd/hurdkill.c
@@ -42,7 +42,7 @@ _hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport)
 			      (refport = arg_refport, 0), 0,
 			      /* If no message port we cannot send signals.  */
 			      msgport == MACH_PORT_NULL ? EPERM :
-			      __msg_sig_post (msgport, sig, refport));
+			      __msg_sig_post (msgport, sig, 0, refport));
       if (! err)
 	delivered = 1;
     }
diff --git a/hurd/hurdlookup.c b/hurd/hurdlookup.c
index 41ea32774e..a5a114aa44 100644
--- a/hurd/hurdlookup.c
+++ b/hurd/hurdlookup.c
@@ -100,7 +100,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
       mach_port_t ref = __mach_reply_port ();
       error_t reauth (auth_t auth)
 	{
-	  return __auth_user_authenticate (auth, unauth, ref,
+	  return __auth_user_authenticate (auth, ref,
 					   MACH_MSG_TYPE_MAKE_SEND,
 					   result);
 	}
diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
index acec1f5fdf..32d1a5c975 100644
--- a/hurd/hurdmsg.c
+++ b/hurd/hurdmsg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -22,6 +22,7 @@ Cambridge, MA 02139, USA.  */
 #include <unistd.h>
 #include <limits.h>
 #include <string.h>
+#include <argz.h>
 
 
 #define AUTHCHECK \
@@ -377,57 +378,15 @@ _S_msg_set_environment (mach_port_t msgport, mach_port_t auth,
 
   AUTHCHECK;
 
-  envc = _hurd_split_args (data, datalen, NULL);
+  envc = __argz_count (data, datalen);
   envp = malloc ((envc + 1) * sizeof (char *));
   if (envp == NULL)
     return errno;
-  _hurd_split_args (data, datalen, envp);
+  __argz_extract (data, datalen, envp);
   __environ = envp;		/* XXX cooperate with loadenv et al */
   return 0;
 }
 
-/* Get and frob the exec flags.  */
-
-kern_return_t
-_S_msg_get_exec_flags (mach_port_t process, mach_port_t auth,
-		       int *flags)
-{
-  AUTHCHECK;
-
-  *flags = _hurd_exec_flags;
-  return 0;
-}
-
-kern_return_t
-_S_msg_set_all_exec_flags (mach_port_t process, mach_port_t auth,
-			   int flags)
-{
-  AUTHCHECK;
-
-  _hurd_exec_flags = flags;
-  return 0;
-}
-
-kern_return_t
-_S_msg_set_some_exec_flags (mach_port_t process, mach_port_t auth,
-			    int flags)
-{
-  AUTHCHECK;
-
-  _hurd_exec_flags |= flags;
-  return 0;
-}
-
-kern_return_t
-_S_msg_clear_some_exec_flags (mach_port_t process, mach_port_t auth,
-			      int flags)
-{
-  AUTHCHECK;
-
-  _hurd_exec_flags &= ~flags;
-  return 0;
-}
-
 
 /* XXX */
 
@@ -445,7 +404,3 @@ _S_msg_set_dtable (mach_port_t process,
 		   portarray_t dtable,
 		   mach_msg_type_number_t dtableCnt)
 { return EOPNOTSUPP; }
-
-kern_return_t
-_S_msg_startup_dosync (mach_port_t process)
-{ return EOPNOTSUPP; }
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index a84e7bc54e..b1a551d7f3 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -564,7 +564,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
     {
       /* No preemption.  Do normal handling.  */
 
-      if (!untraced && (_hurd_exec_flags & EXEC_TRACED))
+      if (!untraced && __sigismember (&_hurdsig_traced, signo))
 	{
 	  /* We are being traced.  Stop to tell the debugger of the signal.  */
 	  if (_hurd_stopped)
@@ -785,7 +785,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	    /* The thread was in sigreturn, not in any interruptible RPC.  */
 	    wait_for_reply = 0;
 
-	    assert (! ss->critical_section);
+	    assert (! __spin_lock_locked (&ss->critical_section_lock));
 	  }
 	else
 	  {
@@ -795,7 +795,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 				      &reply)
 		 != MACH_PORT_NULL);
 
-	    if (ss->critical_section)
+	    if (__spin_lock_locked (&ss->critical_section_lock))
 	      {
 		/* The thread is in a critical section.  Mark the signal as
 		   pending.  When it finishes the critical section, it will
@@ -883,7 +883,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
        thread finishes its critical section.  */
     inline int signals_pending (void)
       {
-	if (_hurd_stopped || ss->critical_section)
+	if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
 	  return 0;
 	return pending = ss->pending & ~ss->blocked;
       }
@@ -1057,7 +1057,7 @@ signal_allowed (int signo, mach_port_t refport)
 kern_return_t
 _S_msg_sig_post (mach_port_t me,
 		 mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
-		 int signo,
+		 int signo, natural_t sigcode,
 		 mach_port_t refport)
 {
   error_t err;
@@ -1068,7 +1068,7 @@ _S_msg_sig_post (mach_port_t me,
   /* Post the signal to the designated signal-receiving thread.  This will
      reply when the signal can be considered delivered.  */
   _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
-			      signo, 0, 0, reply_port, reply_port_type,
+			      signo, sigcode, 0, reply_port, reply_port_type,
 			      0); /* Stop if traced.  */
 
   return MIG_NO_REPLY;		/* Already replied.  */
@@ -1081,7 +1081,7 @@ kern_return_t
 _S_msg_sig_post_untraced (mach_port_t me,
 			  mach_port_t reply_port,
 			  mach_msg_type_name_t reply_port_type,
-			  int signo,
+			  int signo, natural_t sigcode,
 			  mach_port_t refport)
 {
   error_t err;
@@ -1092,7 +1092,7 @@ _S_msg_sig_post_untraced (mach_port_t me,
   /* Post the signal to the designated signal-receiving thread.  This will
      reply when the signal can be considered delivered.  */
   _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
-			      signo, 0, 0, reply_port, reply_port_type,
+			      signo, sigcode, 0, reply_port, reply_port_type,
 			      1); /* Untraced flag. */
 
   return MIG_NO_REPLY;		/* Already replied.  */
@@ -1170,7 +1170,7 @@ reauth_proc (mach_port_t new)
   if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
 		       __proc_reauthenticate (port, ref,
 					      MACH_MSG_TYPE_MAKE_SEND) ||
-		       __auth_user_authenticate (new, port, ref,
+		       __auth_user_authenticate (new, ref,
 						 MACH_MSG_TYPE_MAKE_SEND,
 						 &ignore))
       && ignore != MACH_PORT_NULL)
diff --git a/hurd/path-lookup.c b/hurd/path-lookup.c
new file mode 100644
index 0000000000..9e0fff4927
--- /dev/null
+++ b/hurd/path-lookup.c
@@ -0,0 +1,120 @@
+/* Filename lookup using a search path
+
+   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+   Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <string.h>
+#include <hurd.h>
+#include <hurd/lookup.h>
+
+/* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and
+   return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to
+   NULL).  Otherwise, call FUN repeatedly with FILE_NAME prefixed with each
+   successive `:' separated element of PATH, returning whenever FUN returns
+   0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting
+   prefixed path).  If FUN never returns 0, return the first non-ENOENT
+   return value, or ENOENT if there is none.  */
+error_t
+file_name_path_scan (const char *file_name, const char *path,
+		     error_t (*fun)(const char *name),
+		     char **prefixed_name)
+{
+  if (path == NULL || index (file_name, '/'))
+    {
+      if (prefixed_name)
+	*prefixed_name = 0;
+      return (*fun)(file_name);
+    }
+  else
+    {
+      error_t real_err = 0;
+      size_t file_name_len = strlen (file_name);
+
+      for (;;)
+	{
+	  error_t err;
+	  const char *next = index (path, ':') ?: path + strlen (path);
+	  size_t pfx_len = next - path;
+	  char pfxed_name[pfx_len + 2 + file_name_len + 1];
+
+	  if (pfx_len == 0)
+	    pfxed_name[pfx_len++] = '.';
+	  else
+	    bcopy (path, pfxed_name, pfx_len);
+	  if (pfxed_name[pfx_len - 1] != '/')
+	    pfxed_name[pfx_len++] = '/';
+	  bcopy (file_name, pfxed_name + pfx_len, file_name_len + 1);
+
+	  err = (*fun)(pfxed_name);
+	  if (err == 0)
+	    {
+	      if (prefixed_name)
+		*prefixed_name = strdup (pfxed_name);
+	      return 0;
+	    }
+	  if (!real_err && err != ENOENT)
+	    real_err = err;
+
+	  if (*next == '\0')
+	    return real_err ?: ENOENT;
+	  else
+	    path = next + 1;
+	}
+    }
+}
+
+/* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result
+   (see hurd_file_name_lookup for details), but a simple filename (without
+   any directory prefixes) will be consectutively prefixed with the pathnames
+   in the `:' separated list PATH until one succeeds in a successful lookup.
+   If none succeed, then the first error that wasn't ENOENT is returned, or
+   ENOENT if no other errors were returned.  If PREFIXED_NAME is non-NULL,
+   then if RESULT is looked up directly, *PREFIXED_NAME is set to NULL, and
+   if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
+   malloced storage containing the prefixed name.  */
+error_t
+hurd_file_name_path_lookup (error_t (*use_init_port)
+			    (int which,
+			     error_t (*operate) (mach_port_t)),
+			    file_t (*get_dtable_port) (int fd),
+			    const char *file_name, const char *path,
+			    int flags, mode_t mode,
+			    file_t *result, char **prefixed_name)
+{
+  error_t lookup (const char *name)
+    {
+      return
+	__hurd_file_name_lookup (use_init_port, get_dtable_port,
+				 name, flags, mode, result);
+    }
+  return file_name_path_scan (file_name, path, lookup, prefixed_name);
+}
+
+file_t
+file_name_path_lookup (const char *file_name, const char *path,
+		       int flags, mode_t mode, char **prefixed_name)
+{
+  error_t err;
+  file_t result;
+
+  err = hurd_file_name_path_lookup (&_hurd_ports_use, &__getdport,
+				    file_name, path, flags, mode,
+				    &result, prefixed_name);
+
+  return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
+}
diff --git a/hurd/setauth.c b/hurd/setauth.c
index 34ce7f63bb..3591968978 100644
--- a/hurd/setauth.c
+++ b/hurd/setauth.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 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
@@ -73,7 +73,6 @@ _hurd_setauth (auth_t new)
 	      ! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH],
 			       __auth_user_authenticate
 			       (port,
-				_hurd_init_dtable[d],
 				ref, MACH_MSG_TYPE_MAKE_SEND,
 				&new)))
 	    {
@@ -88,7 +87,7 @@ _hurd_setauth (auth_t new)
   if (__USEPORT (CRDIR,
 		 ! __io_reauthenticate (port,
 					ref, MACH_MSG_TYPE_MAKE_SEND) &&
-		 ! __auth_user_authenticate (new, port,
+		 ! __auth_user_authenticate (new,
 					     ref, MACH_MSG_TYPE_MAKE_SEND,
 					     &newport)))
     _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport);
@@ -98,7 +97,7 @@ _hurd_setauth (auth_t new)
   if (__USEPORT (CWDIR,
 		 ! __io_reauthenticate (port,
 					ref, MACH_MSG_TYPE_MAKE_SEND) &&
-		 ! __auth_user_authenticate (new, port,
+		 ! __auth_user_authenticate (new,
 					     ref, MACH_MSG_TYPE_MAKE_SEND,
 					     &newport)))
     _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport);
diff --git a/hurd/sigunwind.c b/hurd/sigunwind.c
index f6d29e1ab0..28c0d941b5 100644
--- a/hurd/sigunwind.c
+++ b/hurd/sigunwind.c
@@ -56,7 +56,7 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val)
   __spin_lock (&ss->lock);
   /* We should only ever be called from _longjmp_unwind (in jmp-unwind.c),
      which calls us inside a critical section.  */
-  assert (ss->critical_section);
+  assert (__spin_lock_locked (&ss->critical_section_lock));
   /* Are we on the alternate signal stack now?  */
   onstack = (ss->sigaltstack.ss_flags & SA_ONSTACK);
   __spin_unlock (&ss->lock);
@@ -122,7 +122,7 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val)
 	 having run all the unwind forms back to ENV's frame, but our SP is
 	 still inside those unwound frames.  */
       __spin_lock (&ss->lock);
-      ss->critical_section = 0;
+      __spin_unlock (&ss->critical_section_lock);
       ss->blocked = ~(sigset_t) 0 & ~_SIG_CANT_MASK;
       __spin_unlock (&ss->lock);
 
diff --git a/hurd/thread-cancel.c b/hurd/thread-cancel.c
index 81828457d5..85ba010407 100644
--- a/hurd/thread-cancel.c
+++ b/hurd/thread-cancel.c
@@ -1,5 +1,5 @@
 /* Thread cancellation support.
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 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
@@ -25,7 +25,7 @@ Cambridge, MA 02139, USA.  */
 
 /* See hurdsig.c.  */
 extern mach_port_t _hurdsig_abort_rpcs (struct hurd_sigstate *ss,
-					int signo, int sigthread, 
+					int signo, int sigthread,
 					struct machine_thread_all_state *,
 					int *state_change,
 					mach_port_t *reply_port,
@@ -45,9 +45,9 @@ hurd_thread_cancel (thread_t thread)
   if (ss == _hurd_self_sigstate ())
     return EINTR;		/* Bozo.  */
 
+  assert (! __spin_lock_locked (&ss->critical_section_lock));
+  __spin_lock (&ss->critical_section_lock);
   __spin_lock (&ss->lock);
-  assert (! ss->critical_section);
-  ss->critical_section = 1;
   err = __thread_suspend (thread);
   __spin_unlock (&ss->lock);
 
@@ -59,7 +59,7 @@ hurd_thread_cancel (thread_t thread)
       /* Interrupt any interruptible RPC now in progress.  */
       state.set = 0;
       _hurdsig_abort_rpcs (ss, 0, 0, &state, &state_change, NULL, 0, 0);
-      if (state_change) 
+      if (state_change)
 	err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
 				  (natural_t *) &state.basic,
 				  MACHINE_THREAD_STATE_COUNT);
@@ -85,7 +85,7 @@ hurd_check_cancel (void)
   int cancel;
 
   __spin_lock (&ss->lock);
-  assert (! ss->critical_section);
+  assert (! __spin_lock_locked (&ss->critical_section_lock));
   cancel = ss->cancel;
   ss->cancel = 0;
   __spin_unlock (&ss->lock);
diff --git a/posix/sched.h b/posix/sched.h
index 026a5e2f20..11f5740bac 100644
--- a/posix/sched.h
+++ b/posix/sched.h
@@ -33,19 +33,19 @@ __BEGIN_DECLS
 
 /* Set scheduling parameters for a process.  */
 extern int __sched_setparam __P ((__pid_t __pid,
-				  __const struct sched_param *__param));
+				  __const struct sched_params *__param));
 extern int sched_setparam __P ((__pid_t __pid,
-				__const struct sched_param *__param));
+				__const struct sched_params *__param));
 
 /* Retrieve scheduling parameters for a particular process.  */
-extern int __sched_getparam __P ((__pid_t __pid, struct sched_param *__param));
-extern int sched_getparam __P ((__pid_t __pid, struct sched_param *__param));
+extern int __sched_getparam __P ((__pid_t __pid, struct sched_params *__param));
+extern int sched_getparam __P ((__pid_t __pid, struct sched_params *__param));
 
 /* Set scheduling algorithm and/or parameters for a process.  */
 extern int __sched_setscheduler __P ((__pid_t __pid, int __policy,
-				      __const struct sched_param *__param));
+				      __const struct sched_params *__param));
 extern int sched_setscheduler __P ((__pid_t __pid, int __policy,
-				    __const struct sched_param *__param));
+				    __const struct sched_params *__param));
 
 /* Retrieve scheduling algorithm for a particular purpose.  */
 extern int __sched_getscheduler __P ((__pid_t __pid));
diff --git a/string/argz-create.c b/string/argz-create.c
index fab3222cb3..2eea91162e 100644
--- a/string/argz-create.c
+++ b/string/argz-create.c
@@ -26,11 +26,12 @@
    ARGZ, and the total length in LEN.  If a memory allocation error occurs,
    ENOMEM is returned, otherwise 0.  */
 error_t
-__argz_create (char **argv, char **argz, size_t *len)
+__argz_create (char *const argv[], char **argz, size_t *len)
 {
   int argc;
   size_t tlen = 0;
-  char *p, **ap;
+  char *const *ap;
+  char *p;
 
   for (argc = 0; argv[argc] != NULL; ++argc)
     tlen += strlen (argv[argc]);
diff --git a/string/argz-next.c b/string/argz-next.c
index 6149c7ee51..416b982306 100644
--- a/string/argz-next.c
+++ b/string/argz-next.c
@@ -28,7 +28,7 @@ __argz_next (char *argz, size_t argz_len, const char *entry)
       if (entry < argz + argz_len)
 	entry = strchr (entry, '\0') + 1;
 
-      return entry >= argz + argz_len ? NULL : entry;
+      return entry >= argz + argz_len ? NULL : (char *) entry;
     }
   else
     if (argz_len > 0)
diff --git a/string/argz.h b/string/argz.h
index 733d06cca8..c2a3139dbb 100644
--- a/string/argz.h
+++ b/string/argz.h
@@ -32,47 +32,47 @@ __BEGIN_DECLS
 /* Make a '\0' separated arg vector from a unix argv vector, returning it in
    ARGZ, and the total length in LEN.  If a memory allocation error occurs,
    ENOMEM is returned, otherwise 0.  The result can be destroyed using free. */
-error_t __argz_create __P ((char **__argv, char **__argz, size_t *__len));
-error_t argz_create __P ((char **__argv, char **__argz, size_t *__len));
+error_t __argz_create __P ((char *const argv[], char **argz, size_t *len));
+error_t argz_create __P ((char *const *argv[], char **argz, size_t *len));
 
 /* Make a '\0' separated arg vector from a SEP separated list in
    STRING, returning it in ARGZ, and the total length in LEN.  If a
    memory allocation error occurs, ENOMEM is returned, otherwise 0.
    The result can be destroyed using free.  */
-error_t __argz_create_sep __P ((__const char *__string, int __sep,
-				char **__argz, size_t *__len));
-error_t argz_create_sep __P ((__const char *__string, int __sep,
-			      char **__argz, size_t *__len));
+error_t __argz_create_sep __P ((__const char *string, int sep,
+				char **argz, size_t *len));
+error_t argz_create_sep __P ((__const char *string, int sep,
+			      char **argz, size_t *len));
 
 /* Returns the number of strings in ARGZ.  */
-size_t __argz_count __P ((__const char *__argz, size_t __len));
-size_t argz_count __P ((__const char *__argz, size_t __len));
+size_t __argz_count __P ((__const char *argz, size_t len));
+size_t argz_count __P ((__const char *argz, size_t len));
 
 /* Puts pointers to each string in ARGZ into ARGV, which must be large enough
    to hold them all.  */
-void __argz_extract __P ((__const char *__argz, size_t __len, char **__argv));
-void argz_extract __P ((__const char *__argz, size_t __len, char **__argv));
+void __argz_extract __P ((__const char *argz, size_t len, char **argv));
+void argz_extract __P ((__const char *argz, size_t len, char **argv));
 
 /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
    except the last into the character SEP.  */
-void __argz_stringify __P ((char *__argz, size_t __len, int __sep));
-void argz_stringify __P ((char *__argz, size_t __len, int __sep));
+void __argz_stringify __P ((char *argz, size_t len, int sep));
+void argz_stringify __P ((char *argz, size_t len, int sep));
 
 /* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN.  */
-error_t __argz_append __P ((char **__argz, size_t *__argz_len,
-			    __const char *__buf, size_t __buf_len));
-error_t argz_append __P ((char **__argz, size_t *__argz_len,
-			  __const char *__buf, size_t __buf_len));
+error_t __argz_append __P ((char **argz, size_t *argz_len,
+			    __const char *buf, size_t buf_len));
+error_t argz_append __P ((char **argz, size_t *argz_len,
+			  __const char *buf, size_t buf_len));
 
 /* Append STR to the argz vector in ARGZ & ARGZ_LEN.  */
-error_t __argz_add __P ((char **__argz, size_t *__argz_len,
-			 __const char *__str));
-error_t argz_add __P ((char **__argz, size_t *__argz_len,
-		       __const char *__str));
+error_t __argz_add __P ((char **argz, size_t *argz_len,
+			 __const char *str));
+error_t argz_add __P ((char **argz, size_t *argz_len,
+		       __const char *str));
 
 /* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there.  */
-void __argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
-void argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
+void __argz_delete __P ((char **argz, size_t *argz_len, char *entry));
+void argz_delete __P ((char **argz, size_t *argz_len, char *entry));
 
 /* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
    existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
@@ -80,10 +80,10 @@ void argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
    ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ.  If BEFORE is not
    in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
    ARGZ, ENOMEM is returned, else 0.  */
-error_t __argz_insert __P ((char **__argz, size_t *__argz_len,
-			    char *__before, __const char *__entry));
-error_t argz_insert __P ((char **__argz, size_t *__argz_len,
-			  char *__before, __const char *__entry));
+error_t __argz_insert __P ((char **argz, size_t *argz_len,
+			    char *before, __const char *entry));
+error_t argz_insert __P ((char **argz, size_t *argz_len,
+			  char *before, __const char *entry));
 
 /* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
    are no more.  If entry is NULL, then the first entry is returned.  This
@@ -99,10 +99,10 @@ error_t argz_insert __P ((char **__argz, size_t *__argz_len,
     for (entry = argz; entry; entry = argz_next (argz, argz_len, entry))
       ...;
 */
-extern char *__argz_next __P ((char *__argz, size_t __argz_len,
-			       __const char *__entry));
-extern char *argz_next __P ((char *__argz, size_t __argz_len,
-			     __const char *__entry));
+extern char *__argz_next __P ((char *argz, size_t __argz_len,
+			       __const char *entry));
+extern char *argz_next __P ((char *argz, size_t __argz_len,
+			     __const char *entry));
 
 #if defined (__OPTIMIZE__) && __GNUC__ >= 2
 extern inline char *
@@ -113,7 +113,7 @@ __argz_next (char *argz, size_t argz_len, const char *entry)
       if (entry < argz + argz_len)
 	entry = strchr (entry, '\0') + 1;
 
-      return entry >= argz + argz_len ? NULL : entry;
+      return entry >= argz + argz_len ? NULL : (char *) entry;
     }
   else
     if (argz_len > 0)
diff --git a/string/envz.c b/string/envz.c
index e751eccb8f..447b9e03b1 100644
--- a/string/envz.c
+++ b/string/envz.c
@@ -29,13 +29,13 @@
 /* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.
    If NAME contains the separator character, only the portion before it is
    used in the comparison.  */
-const char *
+char *
 envz_entry (const char *envz, size_t envz_len, const char *name)
 {
   while (envz_len)
     {
-      char *p = name;
-      char *entry = envz;	/* Start of this entry. */
+      const char *p = name;
+      const char *entry = envz;	/* Start of this entry. */
 
       /* See how far NAME and ENTRY match.  */
       while (envz_len && *p == *envz && *p && *p != SEP)
@@ -43,7 +43,7 @@ envz_entry (const char *envz, size_t envz_len, const char *name)
 
       if ((*envz == '\0' || *envz == SEP) && (*p == '\0' || *p == SEP))
 	/* Bingo! */
-	return entry;
+	return (char *) entry;
 
       /* No match, skip to the next entry.  */
       while (envz_len && *envz)
@@ -60,7 +60,7 @@ envz_entry (const char *envz, size_t envz_len, const char *name)
 const char *
 envz_get (const char *envz, size_t envz_len, const char *name)
 {
-  char *entry = envz_entry (envz, envz_len, name);
+  const char *entry = envz_entry (envz, envz_len, name);
   if (entry)
     {
       while (*entry && *entry != SEP)
@@ -75,7 +75,7 @@ envz_get (const char *envz, size_t envz_len, const char *name)
 
 /* Remove the entry for NAME from ENVZ & ENVZ_LEN, if any.  */
 void
-envz_remove (char **envz, size_t *envz_len, char *name)
+envz_remove (char **envz, size_t *envz_len, const char *name)
 {
   char *entry = envz_entry (*envz, *envz_len, name);
   if (entry)
diff --git a/string/envz.h b/string/envz.h
index dad2d281f4..bb907d7589 100644
--- a/string/envz.h
+++ b/string/envz.h
@@ -28,8 +28,8 @@
 #include <argz.h>
 
 /* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.  */
-const char *envz_entry __P ((__const char *__envz, size_t __envz_len,
-			     __const char *__name));
+char *envz_entry __P ((__const char *__envz, size_t __envz_len,
+		       __const char *__name));
 
 /* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0
    if there is none.  */
diff --git a/sysdeps/mach/hurd/access.c b/sysdeps/mach/hurd/access.c
index 98e2bba3b0..eb57d92f27 100644
--- a/sysdeps/mach/hurd/access.c
+++ b/sysdeps/mach/hurd/access.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 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
@@ -44,7 +44,6 @@ DEFUN(__access, (file, type), CONST char *file AND int type)
 	   err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
 	   if (!err)
 	     err = __auth_user_authenticate (_hurd_id.rid_auth,
-					     port,
 					     ref, MACH_MSG_TYPE_MAKE_SEND,
 					     result);
 	   err;
@@ -106,7 +105,7 @@ DEFUN(__access, (file, type), CONST char *file AND int type)
 					    &_hurd_id.rid_auth)))
 	goto lose;
     }
-  
+
   if (!err)
     /* Look up the file name using the modified init ports.  */
     err = __hurd_file_name_lookup (&init_port, &__getdport,
diff --git a/sysdeps/mach/hurd/errnos.awk b/sysdeps/mach/hurd/errnos.awk
index 95cfe10da6..e3ff7a843b 100644
--- a/sysdeps/mach/hurd/errnos.awk
+++ b/sysdeps/mach/hurd/errnos.awk
@@ -23,10 +23,7 @@
 # @comment errno 123
 
 BEGIN {
-    printf "/* This file generated by";
-    for (i = 0; i < ARGC; ++i)
-      printf " %s", ARGV[i];
-    printf ".  */\n";
+    print "/* This file generated by errnos.awk.  */";
     print "";
     print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */";
     print "#ifndef _HURD_ERRNO";
diff --git a/sysdeps/mach/hurd/errnos.h b/sysdeps/mach/hurd/errnos.h
index 31aa3104a5..2ec061596a 100644
--- a/sysdeps/mach/hurd/errnos.h
+++ b/sysdeps/mach/hurd/errnos.h
@@ -1,4 +1,4 @@
-/* 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.  */
+/* This file generated by errnos.awk.  */
 
 /* The Hurd uses Mach error system 0x10, currently only subsystem 0. */
 #ifndef _HURD_ERRNO
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index 5814cc2db2..234e377609 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -61,9 +61,7 @@ __fork (void)
   struct hurd_sigstate *volatile ss;
 
   ss = _hurd_self_sigstate ();
-  __spin_lock (&ss->lock);
-  ss->critical_section = 1;
-  __spin_unlock (&ss->lock);
+  __spin_lock (&ss->critical_section_lock);
 
 #undef	LOSE
 #define LOSE assert_perror (err) /* XXX */
@@ -606,7 +604,7 @@ __fork (void)
 					     &_hurd_orphaned));
 
       /* Forking clears the trace flag.  */
-      _hurd_exec_flags &= ~EXEC_TRACED;
+      __sigemptyset (&_hurdsig_traced);
 
       /* Run things that want to run in the child task to set up.  */
       RUN_HOOK (_hurd_fork_child_hook, ());
diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c
index d47b863fe1..7adcadfb52 100644
--- a/sysdeps/mach/hurd/i386/sigreturn.c
+++ b/sysdeps/mach/hurd/i386/sigreturn.c
@@ -58,7 +58,7 @@ __sigreturn (struct sigcontext *scp)
 	 arrange to have us called over again in the new reality.  */
       ss->context = scp;
       __spin_unlock (&ss->lock);
-      __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+      __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
       /* If a pending signal was handled, sig_post never returned.
 	 If it did return, the pending signal didn't run a handler;
 	 proceed as usual.  */
diff --git a/sysdeps/mach/hurd/jmp-unwind.c b/sysdeps/mach/hurd/jmp-unwind.c
index 20ca5f8aa6..fcb09119ce 100644
--- a/sysdeps/mach/hurd/jmp-unwind.c
+++ b/sysdeps/mach/hurd/jmp-unwind.c
@@ -41,14 +41,15 @@ _longjmp_unwind (jmp_buf env, int val)
   /* All access to SS->active_resources must take place inside a critical
      section where signal handlers cannot run.  */
   __spin_lock (&ss->lock);
-  assert (! ss->critical_section);
-  ss->critical_section = 1;
+  assert (! __spin_lock_locked (&ss->critical_section_lock));
+  __spin_lock (&ss->critical_section_lock);
 
   /* Remove local signal preempters being unwound past.  */
   while (ss->preempters &&
 	 _JMPBUF_UNWINDS (env[0].__jmpbuf, ss->preempters))
     ss->preempters = ss->preempters->next;
 
+  __spin_unlock (&ss->critical_section_lock);
   __spin_unlock (&ss->lock);
 
   /* Iterate over the current thread's list of active resources.
diff --git a/sysdeps/mach/hurd/kill.c b/sysdeps/mach/hurd/kill.c
index 1f10613b09..6dcc5b530f 100644
--- a/sysdeps/mach/hurd/kill.c
+++ b/sysdeps/mach/hurd/kill.c
@@ -65,7 +65,7 @@ __kill (pid_t pid, int sig)
 	    {
 	      if (msgport != MACH_PORT_NULL)
 		/* Send a signal message to his message port.  */
-		return __msg_sig_post (msgport, sig, refport);
+		return __msg_sig_post (msgport, sig, 0, refport);
 
 	      /* The process has no message port.  Perhaps try direct
 		 frobnication of the task.  */
diff --git a/sysdeps/mach/hurd/ptrace.c b/sysdeps/mach/hurd/ptrace.c
index f68d3b41ed..24cf9469d5 100644
--- a/sysdeps/mach/hurd/ptrace.c
+++ b/sysdeps/mach/hurd/ptrace.c
@@ -1,5 +1,5 @@
 /* Process tracing interface `ptrace' for GNU Hurd.
-Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
+Copyright (C) 1991, 1992, 1993, 1995, 1996 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
@@ -93,7 +93,7 @@ ptrace (enum __ptrace_request request, ... )
     {
     case PTRACE_TRACEME:
       /* Make this process be traced.  */
-      _hurd_exec_flags |= EXEC_TRACED;
+      __sigfillset (&_hurdsig_traced);
       __USEPORT (PROC, __proc_mark_traced (port));
       break;
 
@@ -144,7 +144,7 @@ ptrace (enum __ptrace_request request, ... )
 	      /* Tell the process to take the signal (or just resume if 0).  */
 	      err = HURD_MSGPORT_RPC
 		(__USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)),
-		 0, 0, __msg_sig_post_untraced (msgport, data, task));
+		 0, 0, __msg_sig_post_untraced (msgport, data, 0, task));
 	  }
 	__mach_port_deallocate (__mach_task_self (), task);
 	return err ? __hurd_fail (err) : 0;
@@ -178,25 +178,17 @@ ptrace (enum __ptrace_request request, ... )
 	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
+	    err = __msg_set_init_int (msgport, task, INIT_TRACEMASK,
+				      request == PTRACE_DETACH ? 0 :
+				      ~(sigset_t) 0);
 	    if (! err)
 	      {
 		if (request == PTRACE_ATTACH)
 		  /* Now stop the process.  */
-		  err = __msg_sig_post (msgport, SIGSTOP, task);
+		  err = __msg_sig_post (msgport, SIGSTOP, 0, task);
 		else
 		  /* Resume the process from tracing stop.  */
-		  err = __msg_sig_post_untraced (msgport, 0, task);
+		  err = __msg_sig_post_untraced (msgport, 0, 0, task);
 	      }
 	    __mach_port_deallocate (__mach_task_self (), msgport);
 	  }
diff --git a/sysdeps/mach/hurd/select.c b/sysdeps/mach/hurd/select.c
index 8e78adb1bc..188f65b3c0 100644
--- a/sysdeps/mach/hurd/select.c
+++ b/sysdeps/mach/hurd/select.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -22,6 +22,7 @@ Cambridge, MA 02139, USA.  */
 #include <hurd/fd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 /* All user select types.  */
 #define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG)
@@ -41,12 +42,8 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
       fd_set *exceptfds AND struct timeval *timeout)
 {
   int i;
-  mach_port_t port;
+  mach_port_t portset;
   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;
@@ -54,6 +51,14 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
 			   (timeout->tv_sec * 1000 +
 			    timeout->tv_usec / 1000) :
 			   0);
+  struct
+    {
+      struct hurd_userlink ulink;
+      struct hurd_fd *cell;
+      mach_port_t io_port;
+      int type;
+      mach_port_t reply_port;
+    } d[nfds];
 
   /* Use local copies so we can't crash from user bogosity.  */
   if (readfds == NULL)
@@ -76,10 +81,6 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
     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)
     {
@@ -90,16 +91,16 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
 	type |= SELECT_WRITE;
       if (exceptfds != NULL && FD_ISSET (i, &xfds))
 	type |= SELECT_URG;
-      types[i] = type;
+      d[i].type = type;
       if (type)
 	{
-	  cells[i] = _hurd_dtable[i];
-	  ports[i] = _hurd_port_get (&cells[i]->port, &ulink[i]);
-	  if (ports[i] == MACH_PORT_NULL)
+	  d[i].cell = _hurd_dtable[i];
+	  d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
+	  if (d[i].io_port == MACH_PORT_NULL)
 	    {
 	      /* If one descriptor is bogus, we fail completely.  */
 	      while (i-- > 0)
-		_hurd_port_free (&cells[i]->port, &ulink[i], ports[i]);
+		_hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port);
 	      errno = EBADF;
 	      break;
 	    }
@@ -115,58 +116,63 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
   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;
+  got = 0;
+  portset = MACH_PORT_NULL;
   for (i = firstfd; i <= lastfd; ++i)
-    if (types[i])
+    if (d[i].type)
       {
-	if (!err)
+	int type = d[i].type;
+	d[i].reply_port = __mach_reply_port ();
+	err = __io_select (d[i].io_port, d[i].reply_port,
+			   /* Poll for each but the last.  */
+			   (i == lastfd && got == 0) ? to : 0,
+			   &type);
+	switch (err)
 	  {
-	    int tag = i;
-	    int type = types[i];
-	    err = __io_select (ports[i], port,
-			       /* Poll for each but the last.  */
-			       (i == lastfd && got == 0) ? to : 0,
-			       &type, &tag);
-	    switch (err)
+	  case MACH_RCV_TIMED_OUT:
+	    /* No immediate response.  This is normal.  */
+	    err = 0;
+	    if (got == 0)
 	      {
-	      case MACH_RCV_TIMED_OUT:
-		/* No immediate response.  This is normal.  */
-		err = 0;
-		break;
-
-	      case 0:
-		/* We got an answer.  This is not necessarily the answer to
-                   the query we sent just now.  It may correspond to any
-                   prior query which timed out before its answer arrived.  */
-		if (tag < 0 || tag > i || (type & SELECT_ALL) == 0)
-		  /* This is not a proper answer to any query we have yet
-                     made.  */
-		  err = EGRATUITOUS;
-		else
-		  {
-		    /* Some port is ready.  TAG tells us which.  */
-		    types[tag] &= type;
-		    types[tag] |= SELECT_RETURNED;
-		    ++got;
-		  }
-		break;
-
-	      default:
-		/* Any other error kills us.
-		   But we must continue to loop to free the ports.  */
-		break;
+		/* We will wait again for a reply later.  */
+		if (portset == MACH_PORT_NULL)
+		  /* Create the portset to receive all the replies on.  */
+		  err = __mach_port_allocate (__mach_task_self (),
+					      MACH_PORT_RIGHT_PORT_SET,
+					      &portset);
+		if (! err)
+		  /* Put this reply port in the port set.  */
+		  __mach_port_move_member (__mach_task_self (),
+					   d[i].reply_port, portset);
 	      }
+	    break;
+
+	  default:
+	    /* No other error should happen.  Callers of select don't
+	       expect to see errors, so we simulate readiness of the erring
+	       object and the next call hopefully will get the error again.  */
+	    type = SELECT_ALL;
+	    /* FALLTHROUGH */
+
+	  case 0:
+	    /* We got an answer.  */
+	    if ((type & SELECT_ALL) == 0)
+	      /* Bogus answer; treat like an error, as a fake positive.  */
+	      type = SELECT_ALL;
+
+	    /* This port is already ready already.  */
+	    d[i].type &= type;
+	    d[i].type |= SELECT_RETURNED;
+	    ++got;
+	    break;
 	  }
-	_hurd_port_free (&cells[i]->port, &ulink[i], ports[i]);
+	_hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port);
       }
 
   /* Now wait for reply messages.  */
-  if (!err && got == 0 && port != MACH_PORT_NULL)
+  if (!err && got == 0)
     {
       /* Now wait for io_select_reply messages on PORT,
 	 timing out as appropriate.  */
@@ -187,15 +193,13 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
 	      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,
-				   0, sizeof msg, port, to,
+				   0, sizeof msg, portset, to,
 				   MACH_PORT_NULL)) == MACH_MSG_SUCCESS)
 	{
 	  /* We got a message.  Decode it.  */
@@ -209,34 +213,45 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
 	    {
 	      /* This is a properly formatted message so far.
 		 See if it is a success or a failure.  */
-	      if (msg.error.err)
+	      if (msg.error.err == EINTR &&
+		  msg.head.msgh_size == sizeof msg.error)
 		{
-		  err = msg.error.err;
-		  if (msg.head.msgh_size != sizeof msg.error)
-		    __mach_msg_destroy (&msg);
+		  /* EINTR response; poll for further responses
+		     and then return quickly.  */
+		  err = EINTR;
+		  goto poll;
 		}
-	      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_ALL) == 0 ||
-		       msg.success.tag < firstfd || msg.success.tag > lastfd)
-		err = EGRATUITOUS;
-	      else
+	      if (msg.error.err ||
+		  msg.head.msgh_size != sizeof msg.success ||
+		  *(int *) &msg.success.result_type != *(int *) &inttype ||
+		  (msg.success.result & SELECT_ALL) == 0)
 		{
-		  /* This is a winning io_select_reply message!
-		     Record the readiness it indicates and send a reply.  */
-		  types[msg.success.tag] &= msg.success.result;
-		  types[msg.success.tag] |= SELECT_RETURNED;
-		  ++got;
+		  /* Error or bogus reply.  Simulate readiness.  */
+		  __mach_msg_destroy (&msg);
+		  msg.success.result = SELECT_ALL;
 		}
+
+	      /* Look up the respondant's reply port and record its
+                 readiness.  */
+	      {
+		int had = got;
+		for (i = firstfd; i <= lastfd; ++i)
+		  if (d[i].type && d[i].reply_port == msg.head.msgh_local_port)
+		    {
+		      d[i].type &= msg.success.result;
+		      d[i].type |= SELECT_RETURNED;
+		      ++got;
+		    }
+		assert (got > had);
+	      }
 	    }
 
 	  if (msg.head.msgh_remote_port != MACH_PORT_NULL)
 	    __mach_port_deallocate (__mach_task_self (),
 				    msg.head.msgh_remote_port);
 
-	  if (got || err == EINTR)
+	  if (got)
+	  poll:
 	    {
 	      /* Poll for another message.  */
 	      to = 0;
@@ -252,19 +267,17 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
 	   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.  */
+      if (got)
+	/* 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);
+  for (i = firstfd; i <= lastfd; ++i)
+    if (d[i].type)
+      __mach_port_destroy (__mach_task_self (), d[i].reply_port);
+  if (portset != MACH_PORT_NULL)
+    __mach_port_destroy (__mach_task_self (), portset);
 
   if (err)
     return __hurd_fail (err);
@@ -277,7 +290,7 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
      ones are initially set.  */
   for (i = firstfd; i <= lastfd; ++i)
     {
-      int type = types[i];
+      int type = d[i].type;
 
       if ((type & SELECT_RETURNED) == 0)
 	type = 0;
diff --git a/sysdeps/mach/hurd/sigaction.c b/sysdeps/mach/hurd/sigaction.c
index 957068b168..ebe70664be 100644
--- a/sysdeps/mach/hurd/sigaction.c
+++ b/sysdeps/mach/hurd/sigaction.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -47,6 +47,7 @@ DEFUN(__sigaction, (sig, act, oact),
 
   ss = _hurd_self_sigstate ();
 
+  __spin_lock (&ss->critical_section_lock);
   __spin_lock (&ss->lock);
   old = ss->actions[sig];
   if (act != NULL)
@@ -55,7 +56,6 @@ DEFUN(__sigaction, (sig, act, oact),
   if (act != NULL && sig == SIGCHLD &&
       (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP))
     {
-      ss->critical_section = 1;
       __spin_unlock (&ss->lock);
 
       /* Inform the proc server whether or not it should send us SIGCHLD for
@@ -65,16 +65,16 @@ DEFUN(__sigaction, (sig, act, oact),
 		 __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);
+  __spin_unlock (&ss->critical_section_lock);
 
   if (pending)
-    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+    __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
 
   if (oact != NULL)
     *oact = old;
diff --git a/sysdeps/mach/hurd/sigprocmask.c b/sysdeps/mach/hurd/sigprocmask.c
index bae3266708..36edd2bfd5 100644
--- a/sysdeps/mach/hurd/sigprocmask.c
+++ b/sysdeps/mach/hurd/sigprocmask.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 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
@@ -79,7 +79,7 @@ DEFUN(__sigprocmask, (how, set, oset),
   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 ());
+    __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
 
   return 0;
 }
diff --git a/sysdeps/mach/hurd/sigsuspend.c b/sysdeps/mach/hurd/sigsuspend.c
index aa0b2876a4..d8ac97032d 100644
--- a/sysdeps/mach/hurd/sigsuspend.c
+++ b/sysdeps/mach/hurd/sigsuspend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 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
@@ -57,7 +57,7 @@ DEFUN(sigsuspend, (set), CONST sigset_t *set)
 
   if (pending)
     /* Tell the signal thread to check for pending signals.  */
-    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
+    __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
 
   /* Wait for the signal thread's message.  */
   __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
@@ -71,8 +71,8 @@ DEFUN(sigsuspend, (set), CONST sigset_t *set)
 
   if (pending)
     /* Tell the signal thread to check for pending signals.  */
-    __msg_sig_post (_hurd_msgport, 0, __mach_task_self ());
-    
+    __msg_sig_post (_hurd_msgport, 0, 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.  */
diff --git a/sysdeps/stub/nanosleep.c b/sysdeps/stub/nanosleep.c
index 7728bf2a42..97cdd50da0 100644
--- a/sysdeps/stub/nanosleep.c
+++ b/sysdeps/stub/nanosleep.c
@@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Pause execution for a number of nanoseconds.  */
 int
-nanosleep (const struct timespec *requested_time, struct time_spec *remaining)
+nanosleep (const struct timespec *requested_time, struct timespec *remaining)
 {
   errno = ENOSYS;
   return -1;
diff --git a/wcsmbs/wcstod.c b/wcsmbs/wcstod.c
index 9a77c8c7b0..05440d4ad3 100644
--- a/wcsmbs/wcstod.c
+++ b/wcsmbs/wcstod.c
@@ -22,4 +22,4 @@ Boston, MA 02111-1307, USA.  */
 
 #define	USE_WIDE_CHAR	1
 
-#include "strtod.c"
+#include "../stdlib/strtod.c"
diff --git a/wcsmbs/wcstof.c b/wcsmbs/wcstof.c
index 4cccdf0c69..4448e8831c 100644
--- a/wcsmbs/wcstof.c
+++ b/wcsmbs/wcstof.c
@@ -28,4 +28,4 @@ Boston, MA 02111-1307, USA.  */
 #define	FLOAT_HUGE_VAL	HUGE_VALf
 #define	USE_WIDE_CHAR	1
 
-#include "strtod.c"
+#include "../stdlib/strtod.c"
diff --git a/wcsmbs/wcstol.c b/wcsmbs/wcstol.c
index a1d877ea87..fc071b2ac4 100644
--- a/wcsmbs/wcstol.c
+++ b/wcsmbs/wcstol.c
@@ -19,4 +19,4 @@ Boston, MA 02111-1307, USA.  */
 
 #define	USE_WIDE_CHAR	1
 
-#include "strtol.c"
+#include "../stdlib/strtol.c"
diff --git a/wcsmbs/wcstold.c b/wcsmbs/wcstold.c
index b19a48eb7c..c8b807d501 100644
--- a/wcsmbs/wcstold.c
+++ b/wcsmbs/wcstold.c
@@ -28,4 +28,4 @@ Boston, MA 02111-1307, USA.  */
 #define	FLOAT_HUGE_VAL	HUGE_VALl
 #define	USE_WIDE_CHAR	1
 
-#include "strtod.c"
+#include "../stdlib/strtod.c"
diff --git a/wcsmbs/wcwidth.h b/wcsmbs/wcwidth.h
index 3e60d49fad..d596c8ca59 100644
--- a/wcsmbs/wcwidth.h
+++ b/wcsmbs/wcwidth.h
@@ -1,7 +1,7 @@
 /* Internal header containing implementation of wcwidth() function.
 Copyright (C) 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edi>, 1996.
+Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
 
 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
@@ -19,7 +19,7 @@ not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 #include <wchar.h>
-#include "cname-lookup.h"
+#include "../wctype/cname-lookup.h"
 
 /* Array containing width information.  */
 extern unsigned char *__ctype_width;