summaryrefslogtreecommitdiff
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 */