about summary refs log tree commit diff
path: root/REORG.TODO/hurd/hurd
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/hurd/hurd')
-rw-r--r--REORG.TODO/hurd/hurd/fd.h275
-rw-r--r--REORG.TODO/hurd/hurd/id.h54
-rw-r--r--REORG.TODO/hurd/hurd/ioctl.h81
-rw-r--r--REORG.TODO/hurd/hurd/lookup.h190
-rw-r--r--REORG.TODO/hurd/hurd/port.h158
-rw-r--r--REORG.TODO/hurd/hurd/resource.h51
-rw-r--r--REORG.TODO/hurd/hurd/signal.h364
-rw-r--r--REORG.TODO/hurd/hurd/sigpreempt.h102
-rw-r--r--REORG.TODO/hurd/hurd/threadvar.h116
-rw-r--r--REORG.TODO/hurd/hurd/userlink.h147
-rw-r--r--REORG.TODO/hurd/hurd/xattr.h34
11 files changed, 1572 insertions, 0 deletions
diff --git a/REORG.TODO/hurd/hurd/fd.h b/REORG.TODO/hurd/hurd/fd.h
new file mode 100644
index 0000000000..8954be0d50
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/fd.h
@@ -0,0 +1,275 @@
+/* File descriptors.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_FD_H
+
+#define	_HURD_FD_H	1
+#include <features.h>
+
+#include <cthreads.h>
+
+#include <hurd/hurd_types.h>
+#include <hurd/port.h>
+#include <sys/socket.h>
+
+
+/* Structure representing a file descriptor.  */
+
+struct hurd_fd
+  {
+    struct hurd_port port;	/* io server port.  */
+    int flags;			/* fcntl flags; locked by port.lock.  */
+
+    /* Normal port to the ctty.  When `port' is our ctty, this is a port to
+       the same io object but which never returns EBACKGROUND; when not,
+       this is nil.  */
+    struct hurd_port ctty;
+  };
+
+
+/* Current file descriptor table.  */
+
+extern int _hurd_dtablesize;
+extern struct hurd_fd **_hurd_dtable;
+extern struct mutex _hurd_dtable_lock; /* Locks those two variables.  */
+
+#include <hurd/signal.h>
+
+#ifndef _HURD_FD_H_EXTERN_INLINE
+#define _HURD_FD_H_EXTERN_INLINE __extern_inline
+#endif
+
+/* Returns the descriptor cell for FD.  If FD is invalid or unused, return
+   NULL.  The cell is unlocked; when ready to use it, lock it and check for
+   it being unused.  */
+
+_HURD_FD_H_EXTERN_INLINE struct hurd_fd *
+_hurd_fd_get (int fd)
+{
+  struct hurd_fd *descriptor;
+
+  HURD_CRITICAL_BEGIN;
+  __mutex_lock (&_hurd_dtable_lock);
+  if (fd < 0 || fd >= _hurd_dtablesize)
+    descriptor = NULL;
+  else
+    {
+      struct hurd_fd *cell = _hurd_dtable[fd];
+      if (cell == NULL)
+	/* No descriptor allocated at this index.  */
+	descriptor = NULL;
+      else
+	{
+	  __spin_lock (&cell->port.lock);
+	  if (cell->port.port == MACH_PORT_NULL)
+	    /* The descriptor at this index has no port in it.
+	       This happens if it existed before but was closed.  */
+	    descriptor = NULL;
+	  else
+	    descriptor = cell;
+	  __spin_unlock (&cell->port.lock);
+	}
+    }
+  __mutex_unlock (&_hurd_dtable_lock);
+  HURD_CRITICAL_END;
+
+  return descriptor;
+}
+
+
+/* Evaluate EXPR with the variable `descriptor' bound to a pointer to the
+   file descriptor structure for FD.   */
+
+#define	HURD_FD_USE(fd, expr)						      \
+  ({ struct hurd_fd *descriptor = _hurd_fd_get (fd);			      \
+     descriptor == NULL ? EBADF : (expr); })
+
+/* Evaluate EXPR with the variable `port' bound to the port to FD, and
+   `ctty' bound to the ctty port.  */
+
+#define HURD_DPORT_USE(fd, expr) \
+  HURD_FD_USE ((fd), HURD_FD_PORT_USE (descriptor, (expr)))
+
+/* Likewise, but FD is a pointer to the file descriptor structure.  */
+
+#define	HURD_FD_PORT_USE(fd, expr)					      \
+  ({ error_t __result;							      \
+     struct hurd_fd *const __d = (fd);					      \
+     struct hurd_userlink __ulink, __ctty_ulink;			      \
+     io_t port, ctty;							      \
+     void *crit = _hurd_critical_section_lock ();			      \
+     __spin_lock (&__d->port.lock);					      \
+     if (__d->port.port == MACH_PORT_NULL)				      \
+       {								      \
+	 __spin_unlock (&__d->port.lock);				      \
+	 _hurd_critical_section_unlock (crit);				      \
+	 __result = EBADF;						      \
+       }								      \
+     else								      \
+       {								      \
+	 ctty = _hurd_port_get (&__d->ctty, &__ctty_ulink);		      \
+	 port = _hurd_port_locked_get (&__d->port, &__ulink);		      \
+	 _hurd_critical_section_unlock (crit);				      \
+	 __result = (expr);						      \
+	 _hurd_port_free (&__d->port, &__ulink, port);			      \
+	 if (ctty != MACH_PORT_NULL)					      \
+	   _hurd_port_free (&__d->ctty, &__ctty_ulink, ctty);		      \
+       }								      \
+     __result; })
+
+#include <errno.h>
+
+/* Check if ERR should generate a signal.
+   Returns the signal to take, or zero if none.  */
+
+_HURD_FD_H_EXTERN_INLINE int
+_hurd_fd_error_signal (error_t err)
+{
+  switch (err)
+    {
+    case EMACH_SEND_INVALID_DEST:
+    case EMIG_SERVER_DIED:
+      /* The server has disappeared!  */
+      return SIGLOST;
+    case EPIPE:
+      return SIGPIPE;
+    default:
+      /* Having a default case avoids -Wenum-switch warnings.  */
+      return 0;
+    }
+}
+
+/* Handle an error from an RPC on a file descriptor's port.  You should
+   always use this function to handle errors from RPCs made on file
+   descriptor ports.  Some errors are translated into signals.  */
+
+_HURD_FD_H_EXTERN_INLINE error_t
+_hurd_fd_error (int fd, error_t err)
+{
+  int signo = _hurd_fd_error_signal (err);
+  if (signo)
+    {
+      const struct hurd_signal_detail detail
+	= { code: fd, error: err, exc: 0 };
+      _hurd_raise_signal (NULL, signo, &detail);
+    }
+  return err;
+}
+
+/* Handle error code ERR from an RPC on file descriptor FD's port.
+   Set `errno' to the appropriate error code, and always return -1.  */
+
+_HURD_FD_H_EXTERN_INLINE int
+__hurd_dfail (int fd, error_t err)
+{
+  errno = _hurd_fd_error (fd, err);
+  return -1;
+}
+
+/* Likewise, but do not raise SIGPIPE on EPIPE if flags contain
+   MSG_NOSIGNAL.  */
+
+_HURD_FD_H_EXTERN_INLINE int
+__hurd_sockfail (int fd, int flags, error_t err)
+{
+  if (!(flags & MSG_NOSIGNAL) || err != EPIPE)
+    err = _hurd_fd_error (fd, err);
+  errno = err;
+  return -1;
+}
+
+/* Set up *FD to have PORT its server port, doing appropriate ctty magic.
+   Does no locking or unlocking.  */
+
+extern void _hurd_port2fd (struct hurd_fd *fd, io_t port, int flags);
+
+/* Allocate a new file descriptor and install PORT in it (doing any
+   appropriate ctty magic); consumes a user reference on PORT.  FLAGS are
+   as for `open'; only O_IGNORE_CTTY and O_CLOEXEC are meaningful, but all are
+   saved.
+
+   If the descriptor table is full, set errno, and return -1.
+   If DEALLOC is nonzero, deallocate PORT first.  */
+
+extern int _hurd_intern_fd (io_t port, int flags, int dealloc);
+
+/* Allocate a new file descriptor in the table and return it, locked.  The
+   new descriptor number will be no less than FIRST_FD.  If the table is
+   full, set errno to EMFILE and return NULL.  If FIRST_FD is negative or
+   bigger than the size of the table, set errno to EINVAL and return NULL.  */
+
+extern struct hurd_fd *_hurd_alloc_fd (int *fd_ptr, int first_fd);
+
+/* Allocate a new file descriptor structure and initialize its port cells
+   with PORT and CTTY.  (This does not affect the descriptor table.)  */
+
+extern struct hurd_fd *_hurd_new_fd (io_t port, io_t ctty);
+
+/* Close a file descriptor, making it available for future reallocation.  */
+
+extern error_t _hurd_fd_close (struct hurd_fd *fd);
+
+/* Read and write data from a file descriptor; just like `read' and `write'
+   if OFFSET is -1, or like `pread' and `pwrite' if OFFSET is not -1.
+   If successful, stores the amount actually read or written in *NBYTES.  */
+
+extern error_t _hurd_fd_read (struct hurd_fd *fd,
+			      void *buf, size_t *nbytes, loff_t offset);
+extern error_t _hurd_fd_write (struct hurd_fd *fd,
+			       const void *buf, size_t *nbytes, loff_t offset);
+
+
+/* Call *RPC on PORT and/or CTTY; if a call on CTTY returns EBACKGROUND,
+   generate SIGTTIN/SIGTTOU or EIO as appropriate.  */
+
+extern error_t _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t));
+extern error_t _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t));
+
+
+/* The guts of `select' and `poll'.  Check the first NFDS descriptors
+   either in POLLFDS (if nonnull) or in each of READFDS, WRITEFDS,
+   EXCEPTFDS that is nonnull.  If TIMEOUT is not NULL, time out after
+   waiting the interval specified therein.  If SIGMASK is nonnull,
+   the set of blocked signals is temporarily set to that during this call.
+   Returns the number of ready descriptors, or -1 for errors.  */
+struct pollfd;
+struct timespec;
+extern int _hurd_select (int nfds, struct pollfd *pollfds,
+			 fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+			 const struct timespec *timeout,
+			 const sigset_t *sigmask);
+
+/* Variant of file_name_lookup used in *at function implementations.
+   AT_FLAGS may only contain AT_SYMLINK_FOLLOW or AT_SYMLINK_NOFOLLOW,
+   which will remove and add O_NOLINK from FLAGS respectively.
+   Other bits cause EINVAL.  */
+extern file_t __file_name_lookup_at (int fd, int at_flags,
+				     const char *file_name,
+				     int flags, mode_t mode);
+
+/* Variant of file_name_split used in *at function implementations.  */
+extern file_t __file_name_split_at (int fd, const char *file_name,
+				    char **name);
+
+/* Variant of directory_name_split used in *at function implementations.  */
+extern file_t __directory_name_split_at (int fd, const char *directory_name,
+					 char **name);
+
+
+
+#endif	/* hurd/fd.h */
diff --git a/REORG.TODO/hurd/hurd/id.h b/REORG.TODO/hurd/hurd/id.h
new file mode 100644
index 0000000000..ef1292ebe8
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/id.h
@@ -0,0 +1,54 @@
+/* User and group IDs.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_ID_H
+
+#define	_HURD_ID_H	1
+#include <features.h>
+
+#include <cthreads.h>		/* For `struct mutex'.  */
+
+/* Structure describing authorization data for the process.  */
+
+struct hurd_id_data
+  {
+    struct mutex lock;
+
+    int valid;			/* If following data are up to date.  */
+
+    struct
+      {
+	uid_t *uids;
+	gid_t *gids;
+	mach_msg_type_number_t nuids, ngids;
+      } gen, aux;
+
+    auth_t rid_auth;		/* Cache used by access.  */
+  };
+
+/* Current data.  */
+
+extern struct hurd_id_data _hurd_id;
+
+
+/* Update _hurd_id (caller should be holding the lock).  */
+
+extern error_t _hurd_check_ids (void);
+
+
+#endif	/* hurd/id.h */
diff --git a/REORG.TODO/hurd/hurd/ioctl.h b/REORG.TODO/hurd/hurd/ioctl.h
new file mode 100644
index 0000000000..0423b8cb9f
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/ioctl.h
@@ -0,0 +1,81 @@
+/* User-registered handlers for specific `ioctl' requests.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_IOCTL_H
+#define	_HURD_IOCTL_H	1
+
+#define	__need___va_list
+#include <stdarg.h>
+#include <bits/ioctls.h>
+
+
+/* Type of handler function, called like ioctl to do its entire job.  */
+typedef int (*ioctl_handler_t) (int fd, int request, void *arg);
+
+/* Structure that records an ioctl handler.  */
+struct ioctl_handler
+  {
+    /* Range of handled _IOC_NOTYPE (REQUEST) values.  */
+    int first_request, last_request;
+
+    /* Handler function, called like ioctl to do its entire job.  */
+    ioctl_handler_t handler;
+
+    struct ioctl_handler *next;	/* Next handler.  */
+  };
+
+
+/* Register HANDLER to handle ioctls with REQUEST values between
+   FIRST_REQUEST and LAST_REQUEST inclusive.  Returns zero if successful.
+   Return nonzero and sets `errno' for an error.  */
+
+extern int hurd_register_ioctl_handler (int first_request, int last_request,
+					ioctl_handler_t handler);
+
+
+/* Define a library-internal handler for ioctl commands between FIRST and
+   LAST inclusive.  The last element gratuitously references HANDLER to
+   avoid `defined but not used' warnings.  */
+
+#define	_HURD_HANDLE_IOCTLS_1(handler, first, last, moniker)		      \
+  static const struct ioctl_handler handler##_ioctl_handler##moniker	      \
+	__attribute__ ((__unused__)) =					      \
+    { _IOC_NOTYPE (first), _IOC_NOTYPE (last),				      \
+	(ioctl_handler_t) (handler), NULL };				      \
+  text_set_element (_hurd_ioctl_handler_lists,				      \
+                    handler##_ioctl_handler##moniker)
+#define	_HURD_HANDLE_IOCTLS(handler, first, last)			      \
+  _HURD_HANDLE_IOCTLS_1 (handler, first, last, first##_to_##last)
+
+/* Define a library-internal handler for a single ioctl command.  */
+
+#define _HURD_HANDLE_IOCTL(handler, ioctl) \
+  _HURD_HANDLE_IOCTLS_1 (handler, ioctl, ioctl, ioctl##_only)
+
+
+/* Install a new CTTYID port, atomically updating the dtable appropriately.
+   This consumes the send right passed in.  */
+
+void _hurd_locked_install_cttyid (mach_port_t cttyid);
+
+/* Lookup the handler for the given ioctl request.  */
+
+ioctl_handler_t _hurd_lookup_ioctl_handler (int request);
+
+
+#endif	/* hurd/ioctl.h */
diff --git a/REORG.TODO/hurd/hurd/lookup.h b/REORG.TODO/hurd/hurd/lookup.h
new file mode 100644
index 0000000000..99052994c7
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/lookup.h
@@ -0,0 +1,190 @@
+/* Declarations of file name translation functions for the GNU Hurd.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _HURD_LOOKUP_H
+#define _HURD_LOOKUP_H	1
+
+/* These functions all take two callback functions as the first two arguments.
+   The first callback function USE_INIT_PORT is called as follows:
+
+   error_t use_init_port (int which, error_t (*operate) (mach_port_t));
+
+   WHICH is nonnegative value less than INIT_PORT_MAX, indicating which
+   init port is required.  The callback function should call *OPERATE
+   with a send right to the appropriate init port.  No user reference
+   is consumed; the right will only be used after *OPERATE returns if
+   *OPERATE has added its own user reference.
+
+   LOOKUP is a function to do the actual filesystem lookup.  It is passed the
+   same arguments that the dir_lookup rpc accepts, and if 0, __dir_lookup is
+   used.
+
+   The second callback function GET_DTABLE_PORT should behave like `getdport'.
+
+   All these functions return zero on success or an error code on failure.  */
+
+
+/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>).  If
+   successful, returns zero and store the port to FILE in *PORT; otherwise
+   returns an error code. */
+
+error_t __hurd_file_name_lookup (error_t (*use_init_port)
+				   (int which,
+				    error_t (*operate) (mach_port_t)),
+				 file_t (*get_dtable_port) (int fd),
+				 error_t (*lookup)
+				   (file_t dir, char *name, int flags, mode_t mode,
+				    retry_type *do_retry, string_t retry_name,
+				    mach_port_t *result),
+				 const char *file_name,
+				 int flags, mode_t mode,
+				 file_t *result);
+error_t hurd_file_name_lookup (error_t (*use_init_port)
+			         (int which,
+				  error_t (*operate) (mach_port_t)),
+			       file_t (*get_dtable_port) (int fd),
+			       error_t (*lookup)
+				 (file_t dir, char *name, int flags, mode_t mode,
+				  retry_type *do_retry, string_t retry_name,
+				  mach_port_t *result),
+			       const char *file_name,
+			       int flags, mode_t mode,
+			       file_t *result);
+
+
+/* Split FILE into a directory and a name within the directory.  Look up a
+   port for the directory and store it in *DIR; store in *NAME a pointer
+   into FILE where the name within directory begins.  */
+
+error_t __hurd_file_name_split (error_t (*use_init_port)
+				  (int which,
+				   error_t (*operate) (mach_port_t)),
+				file_t (*get_dtable_port) (int fd),
+				error_t (*lookup) (file_t dir, char *name,
+						   int flags, mode_t mode,
+				   retry_type *do_retry, string_t retry_name,
+				   mach_port_t *result),
+				const char *file_name,
+				file_t *dir, char **name);
+error_t hurd_file_name_split (error_t (*use_init_port)
+			        (int which,
+				 error_t (*operate) (mach_port_t)),
+			      file_t (*get_dtable_port) (int fd),
+			      error_t (*lookup) (file_t dir, char *name,
+						 int flags, mode_t mode,
+				 retry_type *do_retry, string_t retry_name,
+				 mach_port_t *result),
+			      const char *file_name,
+			      file_t *dir, char **name);
+
+/* Split DIRECTORY into a parent directory and a name within the directory.
+   This is the same as hurd_file_name_split, but ignores trailing slashes.  */
+
+error_t __hurd_directory_name_split (error_t (*use_init_port)
+				  (int which,
+				   error_t (*operate) (mach_port_t)),
+				file_t (*get_dtable_port) (int fd),
+				error_t (*lookup) (file_t dir, char *name,
+						   int flags, mode_t mode,
+				   retry_type *do_retry, string_t retry_name,
+				   mach_port_t *result),
+				const char *directory_name,
+				file_t *dir, char **name);
+error_t hurd_directory_name_split (error_t (*use_init_port)
+				   (int which,
+				    error_t (*operate) (mach_port_t)),
+				   file_t (*get_dtable_port) (int fd),
+				   error_t (*lookup) (file_t dir, char *name,
+						      int flags, mode_t mode,
+				    retry_type *do_retry, string_t retry_name,
+				    mach_port_t *result),
+				   const char *directory_name,
+				   file_t *dir, char **name);
+
+
+/* Process the values returned by `dir_lookup' et al, and loop doing
+   `dir_lookup' calls until one returns FS_RETRY_NONE.  The arguments
+   should be those just passed to and/or returned from `dir_lookup',
+   `fsys_getroot', or `file_invoke_translator'.  This function consumes the
+   reference in *RESULT even if it returns an error.  */
+
+error_t __hurd_file_name_lookup_retry (error_t (*use_init_port)
+				         (int which,
+					  error_t (*operate) (mach_port_t)),
+				       file_t (*get_dtable_port) (int fd),
+				       error_t (*lookup)
+				         (file_t dir, char *name,
+					  int flags, mode_t mode,
+					  retry_type *do_retry,
+					  string_t retry_name,
+					  mach_port_t *result),
+				       enum retry_type doretry,
+				       char retryname[1024],
+				       int flags, mode_t mode,
+				       file_t *result);
+error_t hurd_file_name_lookup_retry (error_t (*use_init_port)
+				       (int which,
+					error_t (*operate) (mach_port_t)),
+				     file_t (*get_dtable_port) (int fd),
+				     error_t (*lookup)
+				       (file_t dir, char *name,
+					int flags, mode_t mode,
+					retry_type *do_retry,
+					string_t retry_name,
+					mach_port_t *result),
+				     enum retry_type doretry,
+				     char retryname[1024],
+				     int flags, mode_t mode,
+				     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 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 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),
+				    error_t (*lookup)
+				      (file_t dir, char *name,
+				       int flags, mode_t mode,
+				       retry_type *do_retry,
+				       string_t retry_name,
+				       mach_port_t *result),
+				    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/REORG.TODO/hurd/hurd/port.h b/REORG.TODO/hurd/hurd/port.h
new file mode 100644
index 0000000000..94874f8f25
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/port.h
@@ -0,0 +1,158 @@
+/* Lightweight user references for ports.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_PORT_H
+
+#define	_HURD_PORT_H	1
+#include <features.h>
+
+#include <mach.h>
+#include <hurd/userlink.h>
+#include <spin-lock.h>
+#include <hurd/signal.h>
+
+
+/* Structure describing a cell containing a port.  With the lock held, a
+   user extracts PORT, and attaches his own link (in local storage) to the
+   USERS chain.  PORT can then safely be used.  When PORT is no longer
+   needed, with the lock held, the user removes his link from the chain.
+   If his link is the last, and PORT has changed since he fetched it, the
+   user deallocates the port he used.  See <hurd/userlink.h>.  */
+
+struct hurd_port
+  {
+    spin_lock_t lock;		/* Locks rest.  */
+    struct hurd_userlink *users; /* Chain of users; see below.  */
+    mach_port_t port;		/* Port. */
+  };
+
+
+/* Evaluate EXPR with the variable `port' bound to the port in PORTCELL.  */
+
+#define	HURD_PORT_USE(portcell, expr)					      \
+  ({ struct hurd_port *const __p = (portcell);				      \
+     struct hurd_userlink __link;					      \
+     const mach_port_t port = _hurd_port_get (__p, &__link);		      \
+     __typeof(expr) __result = (expr);					      \
+     _hurd_port_free (__p, &__link, port);				      \
+     __result; })
+
+
+#ifndef _HURD_PORT_H_EXTERN_INLINE
+#define _HURD_PORT_H_EXTERN_INLINE __extern_inline
+#endif
+
+
+/* Initialize *PORT to INIT.  */
+
+_HURD_PORT_H_EXTERN_INLINE void
+_hurd_port_init (struct hurd_port *port, mach_port_t init)
+{
+  __spin_lock_init (&port->lock);
+  port->users = NULL;
+  port->port = init;
+}
+
+
+/* Cleanup function for non-local exits.  */
+extern void _hurd_port_cleanup (void *, jmp_buf, int);
+
+/* Get a reference to *PORT, which is locked.
+   Pass return value and LINK to _hurd_port_free when done.  */
+
+_HURD_PORT_H_EXTERN_INLINE mach_port_t
+_hurd_port_locked_get (struct hurd_port *port,
+		       struct hurd_userlink *link)
+{
+  mach_port_t result;
+  result = port->port;
+  if (result != MACH_PORT_NULL)
+    {
+      link->cleanup = &_hurd_port_cleanup;
+      link->cleanup_data = (void *) result;
+      _hurd_userlink_link (&port->users, link);
+    }
+  __spin_unlock (&port->lock);
+  return result;
+}
+
+/* Same, but locks PORT first.  */
+
+_HURD_PORT_H_EXTERN_INLINE mach_port_t
+_hurd_port_get (struct hurd_port *port,
+		struct hurd_userlink *link)
+{
+  mach_port_t result;
+  HURD_CRITICAL_BEGIN;
+  __spin_lock (&port->lock);
+  result = _hurd_port_locked_get (port, link);
+  HURD_CRITICAL_END;
+  return result;
+}
+
+
+/* Free a reference gotten with `USED_PORT = _hurd_port_get (PORT, LINK);' */
+
+_HURD_PORT_H_EXTERN_INLINE void
+_hurd_port_free (struct hurd_port *port,
+		 struct hurd_userlink *link,
+		 mach_port_t used_port)
+{
+  int dealloc;
+  if (used_port == MACH_PORT_NULL)
+    /* When we fetch an empty port cell with _hurd_port_get,
+       it does not link us on the users chain, since there is
+       no shared resource.  */
+    return;
+  HURD_CRITICAL_BEGIN;
+  __spin_lock (&port->lock);
+  dealloc = _hurd_userlink_unlink (link);
+  __spin_unlock (&port->lock);
+  HURD_CRITICAL_END;
+  if (dealloc)
+    __mach_port_deallocate (__mach_task_self (), used_port);
+}
+
+
+/* Set *PORT's port to NEWPORT.  NEWPORT's reference is consumed by PORT->port.
+   PORT->lock is locked.  */
+
+_HURD_PORT_H_EXTERN_INLINE void
+_hurd_port_locked_set (struct hurd_port *port, mach_port_t newport)
+{
+  mach_port_t old;
+  old = _hurd_userlink_clear (&port->users) ? port->port : MACH_PORT_NULL;
+  port->port = newport;
+  __spin_unlock (&port->lock);
+  if (old != MACH_PORT_NULL)
+    __mach_port_deallocate (__mach_task_self (), old);
+}
+
+/* Same, but locks PORT first.  */
+
+_HURD_PORT_H_EXTERN_INLINE void
+_hurd_port_set (struct hurd_port *port, mach_port_t newport)
+{
+  HURD_CRITICAL_BEGIN;
+  __spin_lock (&port->lock);
+  _hurd_port_locked_set (port, newport);
+  HURD_CRITICAL_END;
+}
+
+
+#endif	/* hurd/port.h */
diff --git a/REORG.TODO/hurd/hurd/resource.h b/REORG.TODO/hurd/hurd/resource.h
new file mode 100644
index 0000000000..c550d04f07
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/resource.h
@@ -0,0 +1,51 @@
+/* Resource limits for the Hurd.
+   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _HURD_RESOURCE_H
+#define _HURD_RESOURCE_H
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <errno.h>
+#include <hurd/process.h>
+
+/* This array contains the current resource limits for the process.  */
+extern struct rlimit _hurd_rlimits[RLIM_NLIMITS];
+extern struct mutex _hurd_rlimit_lock; /* Locks _hurd_rlimits.  */
+
+
+/* Helper function for getpriority and setpriority.  Maps FN over all the
+   processes specified by WHICH and WHO.  PI is non-null if a
+   proc_getprocinfo was already done; FN may use *PI arbitrarily, it is
+   reset on the next call; PI_FLAGS is passed to proc_getprocinfo.  Returns
+   FN's result the first time it returns nonzero.  If FN never returns
+   nonzero, this returns zero.  */
+extern error_t _hurd_priority_which_map (enum __priority_which which, int who,
+					 error_t (*fn) (pid_t pid,
+							struct procinfo *pi),
+					 int pi_flags);
+
+/* Convert between Mach priority values and the priority
+   values used by getpriority, setpriority, and nice.  */
+#define MACH_PRIORITY_TO_NICE(prio) ((prio) - 25)
+#define NICE_TO_MACH_PRIORITY(nice) ((nice) + 25)
+
+
+
+
+#endif
diff --git a/REORG.TODO/hurd/hurd/signal.h b/REORG.TODO/hurd/hurd/signal.h
new file mode 100644
index 0000000000..e03d53e6d7
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/signal.h
@@ -0,0 +1,364 @@
+/* Implementing POSIX.1 signals under the Hurd.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_SIGNAL_H
+
+#define	_HURD_SIGNAL_H	1
+#include <features.h>
+/* Make sure <signal.h> is going to define NSIG.  */
+#ifndef __USE_GNU
+#error "Must have `_GNU_SOURCE' feature test macro to use this file"
+#endif
+
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
+
+#include <mach/mach_types.h>
+#include <mach/port.h>
+#include <mach/message.h>
+#include <hurd/hurd_types.h>
+#include <signal.h>
+#include <errno.h>
+#include <hurd/msg.h>
+
+#include <cthreads.h>		/* For `struct mutex'.  */
+#include <setjmp.h>		/* For `jmp_buf'.  */
+#include <spin-lock.h>
+#include <hurd/threadvar.h>	/* We cache sigstate in a threadvar.  */
+struct hurd_signal_preemptor;	/* <hurd/sigpreempt.h> */
+
+
+/* Full details of a signal.  */
+struct hurd_signal_detail
+  {
+    /* Codes from origination Mach exception_raise message.  */
+    integer_t exc, exc_code, exc_subcode;
+    /* Sigcode as passed or computed from exception codes.  */
+    integer_t code;
+    /* Error code as passed or extracted from exception codes.  */
+    error_t error;
+  };
+
+
+/* Per-thread signal state.  */
+
+struct hurd_sigstate
+  {
+    spin_lock_t critical_section_lock; /* Held 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.  */
+
+    sigset_t blocked;		/* What signals are blocked.  */
+    sigset_t pending;		/* Pending signals, possibly blocked.  */
+    struct sigaction actions[NSIG];
+    stack_t sigaltstack;
+
+    /* Chain of thread-local signal preemptors; see <hurd/sigpreempt.h>.
+       Each element of this chain is in local stack storage, and the chain
+       parallels the stack: the head of this chain is in the innermost
+       stack frame, and each next element in an outermore frame.  */
+    struct hurd_signal_preemptor *preemptors;
+
+    /* For each signal that may be pending, the details to deliver it with.  */
+    struct hurd_signal_detail pending_data[NSIG];
+
+    /* If `suspended' is set when this thread gets a signal,
+       the signal thread sends an empty message to it.  */
+    mach_port_t suspended;
+
+    /* The following members are not locked.  They are used only by this
+       thread, or by the signal thread with this thread suspended.  */
+
+    volatile mach_port_t intr_port; /* Port interruptible RPC was sent on.  */
+
+    /* If this is not null, the thread is in sigreturn awaiting delivery of
+       pending signals.  This context (the machine-dependent portions only)
+       will be passed to sigreturn after running the handler for a pending
+       signal, instead of examining the thread state.  */
+    struct sigcontext *context;
+
+    /* This is the head of the thread's list of active resources; see
+       <hurd/userlink.h> for details.  This member is only used by the
+       thread itself, and always inside a critical section.  */
+    struct hurd_userlink *active_resources;
+
+    /* These are locked normally.  */
+    int cancel;			/* Flag set by hurd_thread_cancel.  */
+    void (*cancel_hook) (void);	/* Called on cancellation.  */
+  };
+
+/* Linked list of states of all threads whose state has been asked for.  */
+
+extern struct hurd_sigstate *_hurd_sigstates;
+
+extern struct mutex _hurd_siglock; /* Locks _hurd_sigstates.  */
+
+/* Get the sigstate of a given thread, taking its lock.  */
+
+extern struct hurd_sigstate *_hurd_thread_sigstate (thread_t);
+
+/* Get the sigstate of the current thread.
+   This uses a per-thread variable to optimize the lookup.  */
+
+extern struct hurd_sigstate *_hurd_self_sigstate (void)
+     /* This declaration tells the compiler that the value is constant.
+	We assume this won't be called twice from the same stack frame
+	by different threads.  */
+     __attribute__ ((__const__));
+
+#ifndef _HURD_SIGNAL_H_EXTERN_INLINE
+#define _HURD_SIGNAL_H_EXTERN_INLINE __extern_inline
+#endif
+
+_HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate *
+_hurd_self_sigstate (void)
+{
+  struct hurd_sigstate **location = (struct hurd_sigstate **)
+    (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE);
+  if (*location == NULL)
+    *location = _hurd_thread_sigstate (__mach_thread_self ());
+  return *location;
+}
+
+/* Thread listening on our message port; also called the "signal thread".  */
+
+extern thread_t _hurd_msgport_thread;
+
+/* Our message port.  We hold the receive right and _hurd_msgport_thread
+   listens for messages on it.  We also hold a send right, for convenience.  */
+
+extern mach_port_t _hurd_msgport;
+
+
+/* Thread to receive process-global signals.  */
+
+extern thread_t _hurd_sigthread;
+
+
+/* Resource limit on core file size.  Enforced by hurdsig.c.  */
+extern int _hurd_core_limit;
+
+/* Critical sections.
+
+   A critical section is a section of code which cannot safely be interrupted
+   to run a signal handler; for example, code that holds any lock cannot be
+   interrupted lest the signal handler try to take the same lock and
+   deadlock result.  */
+
+_HURD_SIGNAL_H_EXTERN_INLINE void *
+_hurd_critical_section_lock (void)
+{
+  struct hurd_sigstate **location = (struct hurd_sigstate **)
+    (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.  */
+      ss = *location = _hurd_thread_sigstate (__mach_thread_self ());
+    }
+
+  if (! __spin_try_lock (&ss->critical_section_lock))
+    /* We are already in a critical section, so do nothing.  */
+    return NULL;
+
+  /* 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;
+}
+
+_HURD_SIGNAL_H_EXTERN_INLINE void
+_hurd_critical_section_unlock (void *our_lock)
+{
+  if (our_lock == NULL)
+    /* The critical section lock was held when we began.  Do nothing.  */
+    return;
+  else
+    {
+      /* It was us who acquired the critical section lock.  Unlock it.  */
+      struct hurd_sigstate *ss = (struct hurd_sigstate *) our_lock;
+      sigset_t pending;
+      __spin_lock (&ss->lock);
+      __spin_unlock (&ss->critical_section_lock);
+      pending = ss->pending & ~ss->blocked;
+      __spin_unlock (&ss->lock);
+      if (! __sigisemptyset (&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, 0, __mach_task_self ());
+    }
+}
+
+/* Convenient macros for simple uses of critical sections.
+   These two must be used as a pair at the same C scoping level.  */
+
+#define HURD_CRITICAL_BEGIN \
+  { void *__hurd_critical__ = _hurd_critical_section_lock ()
+#define HURD_CRITICAL_END \
+      _hurd_critical_section_unlock (__hurd_critical__); } while (0)
+
+/* Initialize the signal code, and start the signal thread.
+   Arguments give the "init ints" from exec_startup.  */
+
+extern void _hurdsig_init (const int *intarray, size_t intarraysize);
+
+/* Initialize proc server-assisted fault recovery for the signal thread.  */
+
+extern void _hurdsig_fault_init (void);
+
+/* Raise a signal as described by SIGNO an DETAIL, on the thread whose
+   sigstate SS points to.  If SS is a null pointer, this instead affects
+   the calling thread.  */
+
+extern int _hurd_raise_signal (struct hurd_sigstate *ss, int signo,
+			       const struct hurd_signal_detail *detail);
+
+/* Translate a Mach exception into a signal (machine-dependent).  */
+
+extern void _hurd_exception2signal (struct hurd_signal_detail *detail,
+				    int *signo);
+
+
+/* Make the thread described by SS take the signal described by SIGNO and
+   DETAIL.  If the process is traced, this will in fact stop with a SIGNO
+   as the stop signal unless UNTRACED is nonzero.  When the signal can be
+   considered delivered, sends a sig_post reply message on REPLY_PORT
+   indicating success.  SS is not locked.  */
+
+extern void _hurd_internal_post_signal (struct hurd_sigstate *ss,
+					int signo,
+					struct hurd_signal_detail *detail,
+					mach_port_t reply_port,
+					mach_msg_type_name_t reply_port_type,
+					int untraced);
+
+/* Set up STATE and SS to handle signal SIGNO by running HANDLER.  If
+   RPC_WAIT is nonzero, the thread needs to wait for a pending RPC to
+   finish before running the signal handler.  The handler is passed SIGNO,
+   SIGCODE, and the returned `struct sigcontext' (which resides on the
+   stack the handler will use, and which describes the state of the thread
+   encoded in STATE before running the handler).  */
+
+struct machine_thread_all_state;
+extern struct sigcontext *
+_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+			int signo, struct hurd_signal_detail *detail,
+			int rpc_wait, struct machine_thread_all_state *state);
+
+/* Function run by the signal thread to receive from the signal port.  */
+
+extern void _hurd_msgport_receive (void);
+
+/* Set up STATE with a thread state that, when resumed, is
+   like `longjmp (_hurd_sigthread_fault_env, 1)'.  */
+
+extern void _hurd_initialize_fault_recovery_state (void *state);
+
+/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'.  */
+
+extern void _hurd_longjmp_thread_state (void *state, jmp_buf env, int value);
+
+/* Function run for SIGINFO when its action is SIG_DFL and the current
+   process is the session leader.  */
+
+extern void _hurd_siginfo_handler (int);
+
+/* Replacement for mach_msg used in RPCs to provide Hurd interruption
+   semantics.  Args are all the same as for mach_msg.  intr-rpc.h arranges
+   for this version to be used automatically by the RPC stubs the library
+   builds in place of the normal mach_msg. */
+error_t _hurd_intr_rpc_mach_msg (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);
+
+
+/* Milliseconds to wait for an interruptible RPC to return after
+   `interrupt_operation'.  */
+
+extern mach_msg_timeout_t _hurd_interrupted_rpc_timeout;
+
+
+/* Mask of signals that cannot be caught, blocked, or ignored.  */
+#define	_SIG_CANT_MASK	(__sigmask (SIGSTOP) | __sigmask (SIGKILL))
+
+/* Do an RPC to a process's message port.
+
+   Each argument is an expression which returns an error code; each
+   expression may be evaluated several times.  FETCH_MSGPORT_EXPR should
+   fetch the appropriate message port and store it in the local variable
+   `msgport'; it will be deallocated after use.  FETCH_REFPORT_EXPR should
+   fetch the appropriate message port and store it in the local variable
+   `refport' (if no reference port is needed in the call, then
+   FETCH_REFPORT_EXPR should be simply KERN_SUCCESS or 0); if
+   DEALLOC_REFPORT evaluates to nonzero it will be deallocated after use,
+   otherwise the FETCH_REFPORT_EXPR must take care of user references to
+   `refport'.  RPC_EXPR should perform the desired RPC operation using
+   `msgport' and `refport'.
+
+   The reason for the complexity is that a process's message port and
+   reference port may change between fetching those ports and completing an
+   RPC using them (usually they change only when a process execs).  The RPC
+   will fail with MACH_SEND_INVALID_DEST if the msgport dies before we can
+   send the RPC request; or with MIG_SERVER_DIED if the msgport was
+   destroyed after we sent the RPC request but before it was serviced.  In
+   either of these cases, we retry the entire operation, discarding the old
+   message and reference ports and fetch them anew.  */
+
+#define HURD_MSGPORT_RPC(fetch_msgport_expr,				      \
+			 fetch_refport_expr, dealloc_refport,		      \
+			 rpc_expr) 					      \
+({									      \
+    error_t __err;							      \
+    mach_port_t msgport, refport = MACH_PORT_NULL;			      \
+    do									      \
+      {									      \
+	/* Get the message port.  */					      \
+	__err = (error_t) (fetch_msgport_expr);				      \
+	if (__err)							      \
+	  break;							      \
+	/* Get the reference port.  */					      \
+	__err = (error_t) (fetch_refport_expr);				      \
+	if (__err)							      \
+	  {								      \
+	    /* Couldn't get it; deallocate MSGPORT and fail.  */	      \
+	    __mach_port_deallocate (__mach_task_self (), msgport);	      \
+	    break;							      \
+	  }								      \
+	__err = (error_t) (rpc_expr);					      \
+	__mach_port_deallocate (__mach_task_self (), msgport);		      \
+	if ((dealloc_refport) && refport != MACH_PORT_NULL)		      \
+	  __mach_port_deallocate (__mach_task_self (), refport);    	      \
+      } while (__err == MACH_SEND_INVALID_DEST ||			      \
+	       __err == MIG_SERVER_DIED);				      \
+    __err;								      \
+})
+
+
+#endif	/* hurd/signal.h */
diff --git a/REORG.TODO/hurd/hurd/sigpreempt.h b/REORG.TODO/hurd/hurd/sigpreempt.h
new file mode 100644
index 0000000000..406f0f58fa
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/sigpreempt.h
@@ -0,0 +1,102 @@
+/* Preemption of Hurd signals before POSIX.1 semantics take over.
+   Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_SIGPREEMPT_H
+
+#define	_HURD_SIGPREEMPT_H	1
+#include <errno.h>
+#include <signal.h>		/* For sigset_t, sighandler_t, SIG_ERR.  */
+struct hurd_sigstate;		/* <hurd/signal.h> */
+struct hurd_signal_detail;	/* <hurd/signal.h> */
+
+struct hurd_signal_preemptor
+  {
+    /* These members select which signals this structure will apply to.
+       The rest of the structure is only consulted if these match.  */
+    sigset_t signals;		/* Signals preempted.  */
+    unsigned long int first, last; /* Range of sigcode values preempted.  */
+
+    /* This function will be called (with SS->lock held) to decide what to
+       do with the signal described.  It may modify the codes of the signal
+       passed.  If the return value is SIG_ERR, the next matching preemptor
+       is tried, or the normal handling is done for the signal (which may
+       have been changed by the preemptor function).  Otherwise, the signal
+       is processed as if the return value were its handler setting.  */
+    sighandler_t (*preemptor) (struct hurd_signal_preemptor *preemptor,
+			       struct hurd_sigstate *ss,
+			       int *signo, struct hurd_signal_detail *detail);
+    /* If PREEMPTOR is null, act as if it returned HANDLER.  */
+    sighandler_t handler;
+
+    struct hurd_signal_preemptor *next;	/* List structure.  */
+  };
+
+#define HURD_PREEMPT_SIGNAL_P(preemptor, signo, sigcode) \
+  (((preemptor)->signals & sigmask (signo)) && \
+   (sigcode) >= (preemptor)->first && (sigcode) <= (preemptor)->last)
+
+
+/* Signal preemptors applying to all threads; locked by _hurd_siglock.  */
+extern struct hurd_signal_preemptor *_hurdsig_preemptors;
+extern sigset_t _hurdsig_preempted_set;
+
+
+/* The caller must initialize all members of *PREEMPTOR except `next'.
+   The preemptor is registered on the global list.  */
+void hurd_preempt_signals (struct hurd_signal_preemptor *preemptor);
+
+/* Remove a preemptor registered with hurd_preempt_signals.  */
+void hurd_unpreempt_signals (struct hurd_signal_preemptor *preemptor);
+
+
+/* Call *OPERATE and return its value.  If a signal in SIGSET with a sigcode
+   in the range [FIRST,LAST] arrives during the call, catch it.  If HANDLER
+   is a function, it handles the signal in the normal way (i.e. it should
+   longjmp unless it can restart the insn on return).  If it is SIG_ERR,
+   hurd_catch_signal returns the sc_error value from the signal (or
+   EGRATUITOUS if that is zero).
+
+   The preemptor structure is passed to *OPERATE, which may modify its
+   sigcode range or functions at any time during which it is guaranteed no
+   signal in SIGSET will arrive.  */
+
+error_t hurd_catch_signal (sigset_t sigset,
+			   unsigned long int first, unsigned long int last,
+			   error_t (*operate) (struct hurd_signal_preemptor *),
+			   sighandler_t handler);
+
+
+/* Convenience functions using `hurd_catch_signal'.  */
+
+
+/* Like `memset', but catch faults in DEST.  */
+error_t hurd_safe_memset (void *dest, int byte, size_t nbytes);
+
+/* Like `memcpy', but catch faults in SRC.  */
+error_t hurd_safe_copyin (void *dest, const void *src, size_t nbytes);
+
+/* Like `memcpy', but catch faults in DEST.  */
+error_t hurd_safe_copyout (void *dest, const void *src, size_t nbytes);
+
+/* Like `memmove', but catch faults in SRC or DEST.
+   If only one region is expected to fault, it is more efficient
+   to use `hurd_safe_copyin' or `hurd_safe_copyout' as appropriate.  */
+error_t hurd_safe_memmove (void *dest, const void *src, size_t nbytes);
+
+
+#endif	/* hurd/sigpreempt.h */
diff --git a/REORG.TODO/hurd/hurd/threadvar.h b/REORG.TODO/hurd/hurd/threadvar.h
new file mode 100644
index 0000000000..72982e1744
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/threadvar.h
@@ -0,0 +1,116 @@
+/* Internal per-thread variables for the Hurd.
+   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _HURD_THREADVAR_H
+#define	_HURD_THREADVAR_H
+
+#include <features.h>
+
+/* The per-thread variables are found by ANDing this mask
+   with the value of the stack pointer and then adding this offset.
+
+   In the multi-threaded case, cthreads initialization sets
+   __hurd_threadvar_stack_mask to ~(cthread_stack_size - 1), a mask which
+   finds the base of the fixed-size cthreads stack; and
+   __hurd_threadvar_stack_offset to a small offset that skips the data
+   cthreads itself maintains at the base of each thread's stack.
+
+   In the single-threaded case, __hurd_threadvar_stack_mask is zero, so the
+   stack pointer is ignored; and __hurd_threadvar_stack_offset gives the
+   address of a small allocated region which contains the variables for the
+   single thread.  */
+
+extern unsigned long int __hurd_threadvar_stack_mask;
+extern unsigned long int __hurd_threadvar_stack_offset;
+
+/* A special case must always be made for the signal thread.  Even when there
+   is only one user thread and an allocated region can be used for the user
+   thread's variables, the signal thread needs to have its own location for
+   per-thread variables.  The variables __hurd_sigthread_stack_base and
+   __hurd_sigthread_stack_end define the bounds of the stack used by the
+   signal thread, so that thread can always be specifically identified.  */
+
+extern unsigned long int __hurd_sigthread_stack_base;
+extern unsigned long int __hurd_sigthread_stack_end;
+extern unsigned long int *__hurd_sigthread_variables;
+
+
+/* At the location described by the two variables above,
+   there are __hurd_threadvar_max `unsigned long int's of per-thread data.  */
+extern unsigned int __hurd_threadvar_max;
+
+/* These values are the indices for the standard per-thread variables.  */
+enum __hurd_threadvar_index
+  {
+    _HURD_THREADVAR_MIG_REPLY,	/* Reply port for MiG user stub functions.  */
+    _HURD_THREADVAR_ERRNO,	/* `errno' value for this thread.  */
+    _HURD_THREADVAR_SIGSTATE,	/* This thread's `struct hurd_sigstate'.  */
+    _HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables.  */
+    _HURD_THREADVAR_MALLOC,	/* For use of malloc.  */
+    _HURD_THREADVAR_DL_ERROR,	/* For use of -ldl and dynamic linker.  */
+    _HURD_THREADVAR_RPC_VARS,	/* For state of RPC functions.  */
+    _HURD_THREADVAR_LOCALE,	/* For thread-local locale setting.  */
+    _HURD_THREADVAR_CTYPE_B,	/* Cache of thread-local locale data.  */
+    _HURD_THREADVAR_CTYPE_TOLOWER, /* Cache of thread-local locale data.  */
+    _HURD_THREADVAR_CTYPE_TOUPPER, /* Cache of thread-local locale data.  */
+    _HURD_THREADVAR_MAX		/* Default value for __hurd_threadvar_max.  */
+  };
+
+
+#ifndef _HURD_THREADVAR_H_EXTERN_INLINE
+#define _HURD_THREADVAR_H_EXTERN_INLINE __extern_inline
+#endif
+
+/* Return the location of the value for the per-thread variable with index
+   INDEX used by the thread whose stack pointer is SP.  */
+
+extern unsigned long int *__hurd_threadvar_location_from_sp
+  (enum __hurd_threadvar_index __index, void *__sp);
+_HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
+__hurd_threadvar_location_from_sp (enum __hurd_threadvar_index __index,
+				   void *__sp)
+{
+  unsigned long int __stack = (unsigned long int) __sp;
+  return &((__stack >= __hurd_sigthread_stack_base &&
+	    __stack < __hurd_sigthread_stack_end)
+	   ? __hurd_sigthread_variables
+	   : (unsigned long int *) ((__stack & __hurd_threadvar_stack_mask) +
+				    __hurd_threadvar_stack_offset))[__index];
+}
+
+#include <machine-sp.h>		/* Define __thread_stack_pointer.  */
+
+/* Return the location of the current thread's value for the
+   per-thread variable with index INDEX.  */
+
+extern unsigned long int *
+__hurd_threadvar_location (enum __hurd_threadvar_index __index) __THROW
+     /* This declaration tells the compiler that the value is constant
+	given the same argument.  We assume this won't be called twice from
+	the same stack frame by different threads.  */
+     __attribute__ ((__const__));
+
+_HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
+__hurd_threadvar_location (enum __hurd_threadvar_index __index)
+{
+  return __hurd_threadvar_location_from_sp (__index,
+					    __thread_stack_pointer ());
+}
+
+
+#endif	/* hurd/threadvar.h */
diff --git a/REORG.TODO/hurd/hurd/userlink.h b/REORG.TODO/hurd/hurd/userlink.h
new file mode 100644
index 0000000000..4946402df5
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/userlink.h
@@ -0,0 +1,147 @@
+/* Support for chains recording users of a resource; `struct hurd_userlink'.
+   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_USERLINK_H
+
+#define	_HURD_USERLINK_H	1
+#include <features.h>
+
+#define __need_NULL
+#include <stddef.h>
+
+#include <hurd/signal.h>
+#include <setjmp.h>
+
+
+/* This structure records a link in two doubly-linked lists.
+   We call these the per-resource user list and the per-thread
+   active-resource list.
+
+   Users of a given resource are recorded by their presence in a list
+   associated with that resource.  A user attaches his own link (in local
+   storage on his stack) to a shared chain at the time he begins using some
+   resource.  When finished with that resource, the user removes his link
+   from the chain.  If his link is the last (there are no other users of
+   the resource), and his chain has been detached from the shared cell (the
+   resource in the cell has been replaced), then the user deallocates the
+   resource that he used.
+
+   All uses of shared resources by a single thread are linked together by
+   its `active-resource' list; the head of this list is stored in the
+   per-thread sigstate structure.  When the thread makes a non-local exit
+   (i.e. longjmp), it will examine its active-resource list, and each link
+   residing in a stack frame being jumped out of will be unlinked from both
+   the resource's user list and the thread's active-resource list, and
+   deallocate the resource if that was the last user link for that resource.
+
+   NOTE: Access to a thread's active-resource list must always be done
+   inside a signal-proof critical section; the functions in this file
+   assume they are called inside a critical section, and do no locking of
+   their own.  Also important: the longjmp cleanup relies on all userlink
+   structures residing on the stack of the using thread.  */
+
+struct hurd_userlink
+  {
+    struct
+      {
+	struct hurd_userlink *next, **prevp;
+      } resource, thread;
+
+    /* This function is called when a non-local exit
+       unwinds the frame containing this link.  */
+    void (*cleanup) (void *cleanup_data, jmp_buf env, int val);
+    void *cleanup_data;
+  };
+
+
+#ifndef _HURD_USERLINK_H_EXTERN_INLINE
+#define _HURD_USERLINK_H_EXTERN_INLINE __extern_inline
+#endif
+
+
+/* Attach LINK to the chain of users at *CHAINP.  */
+
+_HURD_USERLINK_H_EXTERN_INLINE void
+_hurd_userlink_link (struct hurd_userlink **chainp,
+		     struct hurd_userlink *link)
+{
+  struct hurd_userlink **thread_chainp;
+
+  link->resource.next = *chainp;
+  if (link->resource.next)
+    link->resource.next->resource.prevp = &link->resource.next;
+  link->resource.prevp = chainp;
+  *chainp = link;
+
+  /* Also chain it on the current thread's list of active resources.  */
+  thread_chainp = &_hurd_self_sigstate ()->active_resources;
+  link->thread.next = *thread_chainp;
+  if (link->thread.next)
+    link->thread.next->thread.prevp = &link->thread.next;
+  link->thread.prevp = thread_chainp;
+  *thread_chainp = link;
+}
+
+
+/* Detach LINK from its chain.  Returns nonzero iff this was the
+   last user of the resource and it should be deallocated.  */
+
+_HURD_USERLINK_H_EXTERN_INLINE int
+_hurd_userlink_unlink (struct hurd_userlink *link)
+{
+  /* We should deallocate the resource used if this chain has been detached
+     from the cell (and thus has a nil `prevp'), and there is no next link
+     representing another user reference to the same resource. */
+  int dealloc = ! link->resource.next && ! link->resource.prevp;
+
+  /* Remove our link from the chain of current users.  */
+  if (link->resource.prevp)
+    *link->resource.prevp = link->resource.next;
+  if (link->resource.next)
+    link->resource.next->resource.prevp = link->resource.prevp;
+
+  /* Remove our link from the chain of currently active resources
+     for this thread.  */
+  *link->thread.prevp = link->thread.next;
+  if (link->thread.next)
+    link->thread.next->thread.prevp = link->thread.prevp;
+
+  return dealloc;
+}
+
+
+/* Clear all users from *CHAINP.  Call this when the resource *CHAINP
+   protects is changing.  If the return value is nonzero, no users are on
+   the chain and the caller should deallocate the resource.  If the return
+   value is zero, someone is still using the resource and they will
+   deallocate it when they are finished.  */
+
+_HURD_USERLINK_H_EXTERN_INLINE int
+_hurd_userlink_clear (struct hurd_userlink **chainp)
+{
+  if (*chainp == NULL)
+    return 1;
+
+  /* Detach the chain of current users from the cell.  The last user to
+     remove his link from that chain will deallocate the old resource.  */
+  (*chainp)->resource.prevp = NULL;
+  *chainp = NULL;
+  return 0;
+}
+
+#endif	/* hurd/userlink.h */
diff --git a/REORG.TODO/hurd/hurd/xattr.h b/REORG.TODO/hurd/hurd/xattr.h
new file mode 100644
index 0000000000..bc4c2ce451
--- /dev/null
+++ b/REORG.TODO/hurd/hurd/xattr.h
@@ -0,0 +1,34 @@
+/* Access to extended attributes on files for GNU/Hurd.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_HURD_XATTR_H
+#define	_HURD_XATTR_H	1
+
+#include <sys/xattr.h>		/* This defines the XATTR_* flags.  */
+
+/* These are the internal versions of getxattr/setxattr/listxattr.  */
+extern error_t _hurd_xattr_get (io_t port, const char *name,
+				void *value, size_t *size);
+extern error_t _hurd_xattr_set (io_t port, const char *name,
+				const void *value, size_t size, int flags);
+extern error_t _hurd_xattr_remove (io_t port, const char *name);
+extern error_t _hurd_xattr_list (io_t port, void *buffer, size_t *size);
+
+
+
+#endif	/* hurd/xattr.h */