diff options
Diffstat (limited to 'hurd')
90 files changed, 0 insertions, 12098 deletions
diff --git a/hurd/Depend b/hurd/Depend deleted file mode 100644 index b108b245b8..0000000000 --- a/hurd/Depend +++ /dev/null @@ -1,9 +0,0 @@ -# This file says that the mach subdirectory should appear before this one. -# The mach and hurd subdirectories have many generated header files which -# much of the rest of the library depends on, so it is best to build them -# first (and mach before hurd, at that). The before-compile additions in -# sysdeps/{mach,hurd}/Makefile should make it reliably work for these files -# not to exist when making in other directories, but it will be slower that -# way with more somewhat expensive `make' invocations. - -mach diff --git a/hurd/Makefile b/hurd/Makefile deleted file mode 100644 index 9205822b24..0000000000 --- a/hurd/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (C) 1991-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/>. - -subdir := hurd - -include ../Makeconfig - -headers = hurd.h $(interface-headers) \ - $(addprefix hurd/,fd.h id.h port.h signal.h sigpreempt.h ioctl.h\ - userlink.h resource.h threadvar.h lookup.h) - -inline-headers = hurd.h $(addprefix hurd/,fd.h signal.h \ - userlink.h threadvar.h port.h) - -# The RPC interfaces go in a separate library. -interface-library := libhurduser -user-interfaces := $(addprefix hurd/,\ - auth startup \ - process process_request \ - msg msg_reply msg_request \ - exec exec_startup crash interrupt \ - fs fsys io term tioctl socket ifsock \ - login password pfinet \ - ) -server-interfaces := hurd/msg faultexc - -routines = hurdstartup hurdinit \ - hurdid hurdpid hurdrlimit hurdprio hurdexec hurdselect \ - hurdlookup lookup-retry lookup-at \ - get-host set-host \ - path-lookup \ - setauth \ - pid2task task2pid \ - geteuids seteuids getumask fchroot \ - hurdsock hurdauth \ - hurdchdir hurdfchdir \ - privports \ - msgportdemux \ - fopenport \ - vpprintf \ - ports-get ports-set hurdports hurdmsg \ - errno-loc \ - $(sig) $(dtable) $(inlines) port-cleanup report-wait xattr -sig = hurdsig hurdfault siginfo hurd-raise preempt-sig \ - trampoline longjmp-ts catch-exc exc2signal hurdkill sigunwind \ - thread-self thread-cancel intr-msg catch-signal -dtable = dtable port2fd new-fd alloc-fd intern-fd \ - getdport openport \ - fd-close fd-read fd-write hurdioctl ctty-input ctty-output -inlines = $(inline-headers:%.h=%-inlines) - -# XXX this is a temporary hack; see hurdmalloc.h -routines += hurdmalloc - -# Binary compatibility for libc.so.0.2[GLIBC_2.0]. -ifeq ($(build-shared),yes) -routines += compat-20 -endif - -shared-only-routines = compat-20 - -# For each of the $(inline-headers), generate a trivial source -# file that will #include it to define its inline functions as real functions. -$(inlines:%=$(objpfx)%.c): $(objpfx)%-inlines.c: %.h - (h="`echo $(subst /,_,$*) | tr '[a-z]' '[A-Z]'`"; \ - echo "#define _$${h}_H_EXTERN_INLINE /* Define real function. */"; \ - echo '#include "$<"') > $@-new - mv -f $@-new $@ -generated += $(inlines:=.c) - -include ../mach/Machrules -include ../Rules - -# intr-rpc.defs defines the INTR_INTERFACE macro to make the generated RPC -# stubs import <hurd/signal.h> and #define __mach_msg to -# _hurd_intr_rpc_mach_msg. -user-MIGFLAGS += -imacros intr-rpc.defs - -# The special exc server for sigthread faults uses a special prefix. -MIGFLAGS-faultexc = -prefix _hurdsig_fault_ - -# We need this static dependency to get faultexc.h generated the first time. -$(objpfx)hurdfault.o $(objpfx)hurdfault.d: \ - $(objpfx)faultexc_server.h $(objpfx)faultexc_server.c diff --git a/hurd/Notes b/hurd/Notes deleted file mode 100644 index 9052f29096..0000000000 --- a/hurd/Notes +++ /dev/null @@ -1,37 +0,0 @@ -The library pays attention to some envariables: - -CORESERVER -- Name of core server naming point; falls back to /servers/core -COREFILE -- Name of file to write core dump in; falls back to core -GNUTARGET -- Passed to core server to specify flavor of core dump format - -New functions: - -int openport (io_t port); -FILE *fopenport (mach_port_t, const char *mode); -file_t getdport (int fd); - -task_t pid2task (pid_t); -pid_t task2pid (task_t); - -int fchroot (int fd); -mode_t getumask (void); - -int getuids (int n, uid_t *uidset); - -error_t hurd_path_lookup (file_t root, file_t cwd, - const char *path, int flags, mode_t mode, - file_t *port); -error_t hurd_path_split (file_t root, file_t cwd, - const char *path, - file_t *dir, char **name); -file_t path_lookup (const char *path, int flags, mode_t mode); -file_t path_split (const char *path, char **name); - -process_t getproc (void); -int setproc (process_t); -file_t getcrdir (void); -int setcrdir (file_t); -file_t getcwdir (void); -int setcwdir (file_t); -auth_t getauth (void); -int setauth (auth_t); /* Reauthenticates all library ports. */ diff --git a/hurd/Versions b/hurd/Versions deleted file mode 100644 index 77f5b4271e..0000000000 --- a/hurd/Versions +++ /dev/null @@ -1,144 +0,0 @@ -libc { - GLIBC_2.0 { - # necessary for the Hurd brk implementation - _end; - - # variables used in macros & inline functions - __hurd_sigthread_stack_base; __hurd_sigthread_stack_end; - __hurd_sigthread_variables; - __hurd_threadvar_max; - __hurd_threadvar_stack_mask; __hurd_threadvar_stack_offset; - - # functions used in macros & inline functions - __hurd_errno_location; - - # functions used in libmachuser and libhurduser - _S_catch_exception_raise; - _S_catch_exception_raise_state; - _S_catch_exception_raise_state_identity; - _S_msg_add_auth; _S_msg_del_auth; - _S_msg_describe_ports; - _S_msg_get_dtable; _S_msg_set_dtable; - _S_msg_get_env_variable; _S_msg_set_env_variable; - _S_msg_get_environment; _S_msg_set_environment; - _S_msg_get_fd; _S_msg_set_fd; - _S_msg_get_init_int; _S_msg_set_init_int; - _S_msg_get_init_ints; _S_msg_set_init_ints; - _S_msg_get_init_port; _S_msg_set_init_port; - _S_msg_get_init_ports; _S_msg_set_init_ports; - _S_msg_proc_newids; _S_msg_report_wait; - _S_msg_sig_post; _S_msg_sig_post_untraced; - _hurd_intr_rpc_mach_msg; - _hurdsig_fault_catch_exception_raise; - _hurdsig_fault_catch_exception_raise_state; - _hurdsig_fault_catch_exception_raise_state_identity; - - # "quasi-internal" variables - _hurd_device_master; - _hurd_dtable; _hurd_dtablesize; _hurd_dtable_lock; - _hurd_host_priv; - _hurd_msgport; - _hurd_ports; - - # "quasi-internal" functions - _hurd_canonicalize_directory_name_internal; - _hurd_critical_section_lock; - _hurd_critical_section_unlock; - _hurd_exception2signal; - _hurd_exec; - _hurd_fd_get; - _hurd_init; - _hurd_intern_fd; - _hurd_port_cleanup; - _hurd_port_free; - _hurd_port_get; - _hurd_port_locked_get; - _hurd_ports_use; - _hurd_thread_sigstate; - - # functions in normal name space - - # f* - file_name_lookup; file_name_lookup_under; file_name_path_lookup; - file_name_split; - fopenport; - - # g* - get_privileged_ports; - getauth; getcrdir; getcwdir; getcttyid; getdport; getproc; getumask; - - # h* - hurd_catch_signal; - hurd_check_cancel; - hurd_file_name_lookup; hurd_file_name_lookup_retry; - hurd_file_name_path_lookup; hurd_file_name_split; - hurd_preempt_signals; - hurd_safe_copyin; hurd_safe_copyout; - hurd_safe_memmove; hurd_safe_memset; - hurd_sig_post; - hurd_thread_cancel; hurd_thread_self; - hurd_unpreempt_signals; - - # o* - openport; - - # p* - pid2task; - - # s* - setauth; setcrdir; setcwdir; setproc; setcttyid; - - # t* - task2pid; - - # v* - vpprintf; - } - GLIBC_2.1 { - # "quasi-internal" functions - _hurd_proc_init; - - # g* - geteuids; - - # s* - seteuids; - } - GLIBC_2.1.3 { - # d* - directory_name_split; - - # h* - hurd_directory_name_split; - } - GLIBC_2.2.5 { - # These always existed as inlines but the real functions were not exported. - __hurd_fail; - _hurd_self_sigstate; - - # Same for these "quasi-internal" functions - _hurd_port_init; - _hurd_port_set; - - # internal symbols used by other libraries (e.g. librt) - _hurd_raise_signal; - _hurdsig_interrupt_timeout; - _hurdsig_fault_preemptor; _hurdsig_fault_env; - } - GLIBC_2.2.6 { - # functions used in macros & inline functions - __errno_location; - } - - HURD_CTHREADS_0.3 { - # weak refs to libthreads functions that libc calls iff libthreads in use - cthread_fork; cthread_detach; - - # variables used for detecting cthreads - _cthread_exit_routine; _cthread_init_routine; - - # cthreads functions with stubs in libc - cthread_keycreate; cthread_getspecific; cthread_setspecific; - __libc_getspecific; - } -} diff --git a/hurd/alloc-fd.c b/hurd/alloc-fd.c deleted file mode 100644 index 18e542ce5f..0000000000 --- a/hurd/alloc-fd.c +++ /dev/null @@ -1,140 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/fd.h> -#include <hurd/resource.h> -#include <stdlib.h> -#include "hurdmalloc.h" /* XXX */ - -/* Allocate a new file descriptor 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. */ - -struct hurd_fd * -_hurd_alloc_fd (int *fd, int first_fd) -{ - int i; - void *crit; - long int rlimit; - - if (first_fd < 0) - { - errno = EINVAL; - return NULL; - } - - crit = _hurd_critical_section_lock (); - - __mutex_lock (&_hurd_dtable_lock); - - search: - for (i = first_fd; i < _hurd_dtablesize; ++i) - { - struct hurd_fd *d = _hurd_dtable[i]; - if (d == NULL) - { - /* Allocate a new descriptor structure for this slot, - initializing its port cells to nil. The test below will catch - and return this descriptor cell after locking it. */ - d = _hurd_new_fd (MACH_PORT_NULL, MACH_PORT_NULL); - if (d == NULL) - { - __mutex_unlock (&_hurd_dtable_lock); - _hurd_critical_section_unlock (crit); - return NULL; - } - _hurd_dtable[i] = d; - } - - __spin_lock (&d->port.lock); - if (d->port.port == MACH_PORT_NULL) - { - __mutex_unlock (&_hurd_dtable_lock); - _hurd_critical_section_unlock (crit); - if (fd != NULL) - *fd = i; - return d; - } - else - __spin_unlock (&d->port.lock); - } - - __mutex_lock (&_hurd_rlimit_lock); - rlimit = _hurd_rlimits[RLIMIT_OFILE].rlim_cur; - __mutex_unlock (&_hurd_rlimit_lock); - - if (first_fd < rlimit) - { - /* The descriptor table is full. Check if we have reached the - resource limit, or only the allocated size. */ - if (_hurd_dtablesize < rlimit) - { - /* Enlarge the table. */ - int save = errno; - struct hurd_fd **new; - /* Try to double the table size, but don't exceed the limit, - and make sure it exceeds FIRST_FD. */ - int size = _hurd_dtablesize * 2; - if (size > rlimit) - size = rlimit; - else if (size <= first_fd) - size = first_fd + 1; - - if (size * sizeof (*_hurd_dtable) < size) - { - /* Integer overflow! */ - errno = ENOMEM; - goto out; - } - - /* If we fail to allocate that, decrement the desired size - until we succeed in allocating it. */ - do - new = realloc (_hurd_dtable, size * sizeof (*_hurd_dtable)); - while (new == NULL && size-- > first_fd); - - if (new != NULL) - { - /* We managed to allocate a new table. Now install it. */ - errno = save; - if (first_fd < _hurd_dtablesize) - first_fd = _hurd_dtablesize; - /* Initialize the new slots. */ - for (i = _hurd_dtablesize; i < size; ++i) - new[i] = NULL; - _hurd_dtablesize = size; - _hurd_dtable = new; - /* Go back to the loop to initialize the first new slot. */ - goto search; - } - else - errno = ENOMEM; - } - else - errno = EMFILE; - } - else - errno = EINVAL; /* Bogus FIRST_FD value. */ - - out: - __mutex_unlock (&_hurd_dtable_lock); - _hurd_critical_section_unlock (crit); - - return NULL; -} diff --git a/hurd/catch-exc.c b/hurd/catch-exc.c deleted file mode 100644 index 1a4fa95c9f..0000000000 --- a/hurd/catch-exc.c +++ /dev/null @@ -1,131 +0,0 @@ -/* 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/>. */ - -#include <mach/exc_server.h> -#include <hurd/signal.h> -#include <assert.h> - -/* Called by the microkernel when a thread gets an exception. */ - -kern_return_t -_S_catch_exception_raise (mach_port_t port, - thread_t thread, - task_t task, -#ifdef EXC_MASK_ALL /* New interface flavor. */ - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt -#else /* Vanilla Mach 3.0 interface. */ - integer_t exception, - integer_t code, integer_t subcode -#endif - ) -{ - struct hurd_sigstate *ss; - int signo; - struct hurd_signal_detail d; - - if (task != __mach_task_self ()) - /* The sender wasn't the kernel. */ - return EPERM; - - d.exc = exception; -#ifdef EXC_MASK_ALL - assert (codeCnt >= 2); - d.exc_code = code[0]; - d.exc_subcode = code[1]; -#else - d.exc_code = code; - d.exc_subcode = subcode; -#endif - - /* Call the machine-dependent function to translate the Mach exception - codes into a signal number and subcode. */ - _hurd_exception2signal (&d, &signo); - - /* Find the sigstate structure for the faulting thread. */ - __mutex_lock (&_hurd_siglock); - for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) - if (ss->thread == thread) - break; - __mutex_unlock (&_hurd_siglock); - if (ss == NULL) - ss = _hurd_thread_sigstate (thread); /* Allocate a fresh one. */ - - if (__spin_lock_locked (&ss->lock)) - { - /* Loser. The thread faulted with its sigstate lock held. Its - sigstate data is now suspect. So we reset the parts of it which - could cause trouble for the signal thread. Anything else - clobbered therein will just hose this user thread, but it's - faulting already. - - This is almost certainly a library bug: unless random memory - clobberation caused the sigstate lock to gratuitously appear held, - no code should do anything that can fault while holding the - sigstate lock. */ - - __spin_unlock (&ss->critical_section_lock); - ss->context = NULL; - __spin_unlock (&ss->lock); - } - - /* Post the signal. */ - _hurd_internal_post_signal (ss, signo, &d, - MACH_PORT_NULL, MACH_MSG_TYPE_PORT_SEND, - 0); - - return KERN_SUCCESS; -} - -#ifdef EXC_MASK_ALL -/* XXX New interface flavor has additional RPCs that we could be using - instead. These RPCs roll a thread_get_state/thread_set_state into - the message, so the signal thread ought to use these to save some calls. - */ -kern_return_t -_S_catch_exception_raise_state (mach_port_t port, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt) -{ - abort (); - return KERN_FAILURE; -} - -kern_return_t -_S_catch_exception_raise_state_identity (mach_port_t exception_port, - thread_t thread, - task_t task, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt) -{ - abort (); - return KERN_FAILURE; -} -#endif diff --git a/hurd/catch-signal.c b/hurd/catch-signal.c deleted file mode 100644 index 1d606ecaf0..0000000000 --- a/hurd/catch-signal.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Convenience function to catch expected signals during an operation. - 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/>. */ - -#include <hurd/signal.h> -#include <hurd/sigpreempt.h> -#include <string.h> -#include <assert.h> - -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) -{ - /* We need to restore the signal mask, because otherwise the - signal-handling code will have blocked the caught signal and for - instance calling hurd_catch_signal again would then dump core. */ - sigjmp_buf buf; - void throw (int signo, long int sigcode, struct sigcontext *scp) - { siglongjmp (buf, scp->sc_error ?: EGRATUITOUS); } - - struct hurd_signal_preemptor preemptor = - { - sigset, first, last, - NULL, handler == SIG_ERR ? (sighandler_t) &throw : handler, - }; - - struct hurd_sigstate *const ss = _hurd_self_sigstate (); - error_t error; - - if (handler != SIG_ERR) - /* Not our handler; don't bother saving state. */ - error = 0; - else - /* This returns again with nonzero value when we preempt a signal. */ - error = sigsetjmp (buf, 1); - - if (error == 0) - { - /* Install a signal preemptor for the thread. */ - __spin_lock (&ss->lock); - preemptor.next = ss->preemptors; - ss->preemptors = &preemptor; - __spin_unlock (&ss->lock); - - /* Try the operation that might crash. */ - (*operate) (&preemptor); - } - - /* Either FUNCTION completed happily and ERROR is still zero, or it hit - an expected signal and `throw' made setjmp return the signal error - code in ERROR. Now we can remove the preemptor and return. */ - - __spin_lock (&ss->lock); - assert (ss->preemptors == &preemptor); - ss->preemptors = preemptor.next; - __spin_unlock (&ss->lock); - - return error; -} - - -error_t -hurd_safe_memset (void *dest, int byte, size_t nbytes) -{ - error_t operate (struct hurd_signal_preemptor *preemptor) - { - memset (dest, byte, nbytes); - return 0; - } - return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV), - (vm_address_t) dest, (vm_address_t) dest + nbytes, - &operate, SIG_ERR); -} - - -error_t -hurd_safe_copyout (void *dest, const void *src, size_t nbytes) -{ - error_t operate (struct hurd_signal_preemptor *preemptor) - { - memcpy (dest, src, nbytes); - return 0; - } - return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV), - (vm_address_t) dest, (vm_address_t) dest + nbytes, - &operate, SIG_ERR); -} - -error_t -hurd_safe_copyin (void *dest, const void *src, size_t nbytes) -{ - error_t operate (struct hurd_signal_preemptor *preemptor) - { - memcpy (dest, src, nbytes); - return 0; - } - return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV), - (vm_address_t) src, (vm_address_t) src + nbytes, - &operate, SIG_ERR); -} - -error_t -hurd_safe_memmove (void *dest, const void *src, size_t nbytes) -{ - jmp_buf buf; - void throw (int signo, long int sigcode, struct sigcontext *scp) - { longjmp (buf, scp->sc_error ?: EGRATUITOUS); } - - struct hurd_signal_preemptor src_preemptor = - { - sigmask (SIGBUS) | sigmask (SIGSEGV), - (vm_address_t) src, (vm_address_t) src + nbytes, - NULL, (sighandler_t) &throw, - }; - struct hurd_signal_preemptor dest_preemptor = - { - sigmask (SIGBUS) | sigmask (SIGSEGV), - (vm_address_t) dest, (vm_address_t) dest + nbytes, - NULL, (sighandler_t) &throw, - &src_preemptor - }; - - struct hurd_sigstate *const ss = _hurd_self_sigstate (); - error_t error; - - /* This returns again with nonzero value when we preempt a signal. */ - error = setjmp (buf); - - if (error == 0) - { - /* Install a signal preemptor for the thread. */ - __spin_lock (&ss->lock); - src_preemptor.next = ss->preemptors; - ss->preemptors = &dest_preemptor; - __spin_unlock (&ss->lock); - - /* Do the copy; it might fault. */ - memmove (dest, src, nbytes); - } - - /* Either memmove completed happily and ERROR is still zero, or it hit - an expected signal and `throw' made setjmp return the signal error - code in ERROR. Now we can remove the preemptor and return. */ - - __spin_lock (&ss->lock); - assert (ss->preemptors == &dest_preemptor); - ss->preemptors = src_preemptor.next; - __spin_unlock (&ss->lock); - - return error; -} diff --git a/hurd/compat-20.c b/hurd/compat-20.c deleted file mode 100644 index 0fd1701b26..0000000000 --- a/hurd/compat-20.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Old-versioned functions for binary compatibility with glibc-2.0. - Copyright (C) 1998-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/>. */ - -#include <hurd.h> - -/* This file provides definitions for binary compatibility with - the GLIBC_2.0 version set for the libc.so.0.2 soname. - - These definitions can be removed when the soname changes. */ - -#include <shlib-compat.h> -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) - -void -attribute_compat_text_section -_hurd_proc_init_compat_20 (char **argv) -{ - _hurd_proc_init (argv, NULL, 0); -} -compat_symbol (libc, _hurd_proc_init_compat_20, _hurd_proc_init, GLIBC_2_0); - -#endif diff --git a/hurd/ctty-input.c b/hurd/ctty-input.c deleted file mode 100644 index 826d78bed8..0000000000 --- a/hurd/ctty-input.c +++ /dev/null @@ -1,79 +0,0 @@ -/* _hurd_ctty_input -- Do an input RPC and generate SIGTTIN if necessary. - 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/>. */ - -#include <hurd.h> -#include <hurd/signal.h> - -/* Call *RPC on PORT and/or CTTY. If a call on CTTY returns EBACKGROUND, - generate SIGTTIN or EIO as appropriate. */ - -error_t -_hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t)) -{ - error_t err; - - if (ctty == MACH_PORT_NULL) - return (*rpc) (port); - - do - { - err = (*rpc) (ctty); - if (err == EBACKGROUND) - { - /* We are a background job and tried to read from the tty. - We should probably get a SIGTTIN signal. */ - if (_hurd_orphaned) - /* Our process group is orphaned. Don't stop; just fail. */ - err = EIO; - else - { - struct hurd_sigstate *ss = _hurd_self_sigstate (); - __spin_lock (&ss->lock); - if (__sigismember (&ss->blocked, SIGTTIN) || - ss->actions[SIGTTIN].sa_handler == SIG_IGN) - /* We are blocking or ignoring SIGTTIN. Just fail. */ - err = EIO; - __spin_unlock (&ss->lock); - - if (err == EBACKGROUND) - { - /* Send a SIGTTIN signal to our process group. - - We must remember here not to clobber ERR, since - the loop condition below uses it to recall that - we should retry after a stop. */ - - __USEPORT (CTTYID, _hurd_sig_post (0, SIGTTIN, port)); - /* XXX what to do if error here? */ - - /* At this point we should have just run the handler for - SIGTTIN or resumed after being stopped. Now this is - still a "system call", so check to see if we should - restart it. */ - __spin_lock (&ss->lock); - if (!(ss->actions[SIGTTIN].sa_flags & SA_RESTART)) - err = EINTR; - __spin_unlock (&ss->lock); - } - } - } - /* If the last RPC generated a SIGTTIN, loop to try it again. */ - } while (err == EBACKGROUND); - - return err; -} diff --git a/hurd/ctty-output.c b/hurd/ctty-output.c deleted file mode 100644 index 357adb6563..0000000000 --- a/hurd/ctty-output.c +++ /dev/null @@ -1,84 +0,0 @@ -/* _hurd_ctty_output -- Do an output RPC and generate SIGTTOU if necessary. - 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/>. */ - -#include <hurd.h> -#include <hurd/signal.h> - -/* Call *RPC on PORT and/or CTTY. If a call on CTTY returns EBACKGROUND, - generate SIGTTOU if appropriate. */ - -error_t -_hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t)) -{ - if (ctty == MACH_PORT_NULL) - return (*rpc) (port); - else - { - struct hurd_sigstate *ss = _hurd_self_sigstate (); - error_t err; - - do - { - /* Don't use the ctty io port if we are blocking or ignoring - SIGTTOU. We redo this check at the top of the loop in case - the signal handler changed the state. */ - __spin_lock (&ss->lock); - if (__sigismember (&ss->blocked, SIGTTOU) || - ss->actions[SIGTTOU].sa_handler == SIG_IGN) - err = EIO; - else - err = 0; - __spin_unlock (&ss->lock); - - if (err) - return (*rpc) (port); - - err = (*rpc) (ctty); - if (err == EBACKGROUND) - { - if (_hurd_orphaned) - /* Our process group is orphaned, so we never generate a - signal; we just fail. */ - err = EIO; - else - { - /* Send a SIGTTOU signal to our process group. - - We must remember here not to clobber ERR, since - the loop condition below uses it to recall that - we should retry after a stop. */ - - __USEPORT (CTTYID, _hurd_sig_post (0, SIGTTOU, port)); - /* XXX what to do if error here? */ - - /* At this point we should have just run the handler for - SIGTTOU or resumed after being stopped. Now this is - still a "system call", so check to see if we should - restart it. */ - __spin_lock (&ss->lock); - if (!(ss->actions[SIGTTOU].sa_flags & SA_RESTART)) - err = EINTR; - __spin_unlock (&ss->lock); - } - } - /* If the last RPC generated a SIGTTOU, loop to try it again. */ - } while (err == EBACKGROUND); - - return err; - } -} diff --git a/hurd/dtable.c b/hurd/dtable.c deleted file mode 100644 index 46bad42c3c..0000000000 --- a/hurd/dtable.c +++ /dev/null @@ -1,304 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> -#include <hurd/term.h> -#include <hurd/fd.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <limits.h> -#include <cthreads.h> /* For `struct mutex'. */ -#include "set-hooks.h" -#include "hurdmalloc.h" /* XXX */ - - -struct mutex _hurd_dtable_lock = MUTEX_INITIALIZER; /* XXX ld bug; must init */ -struct hurd_fd **_hurd_dtable; -int _hurd_dtablesize; - - -DEFINE_HOOK (_hurd_fd_subinit, (void)); - -/* Initialize the file descriptor table at startup. */ - -static void -init_dtable (void) -{ - int i; - - __mutex_init (&_hurd_dtable_lock); - - /* The initial size of the descriptor table is that of the passed-in - table. It will be expanded as necessary up to _hurd_dtable_rlimit. */ - _hurd_dtablesize = _hurd_init_dtablesize; - - /* Allocate the vector of pointers. */ - _hurd_dtable = malloc (_hurd_dtablesize * sizeof (*_hurd_dtable)); - if (_hurd_dtablesize != 0 && _hurd_dtable == NULL) - __libc_fatal ("hurd: Can't allocate file descriptor table\n"); - - /* Initialize the descriptor table. */ - for (i = 0; (unsigned int) i < _hurd_init_dtablesize; ++i) - { - if (_hurd_init_dtable[i] == MACH_PORT_NULL) - /* An unused descriptor is marked by a null pointer. */ - _hurd_dtable[i] = NULL; - else - { - /* Allocate a new file descriptor structure. */ - struct hurd_fd *new = malloc (sizeof (struct hurd_fd)); - if (new == NULL) - __libc_fatal ("hurd: Can't allocate initial file descriptors\n"); - - /* Initialize the port cells. */ - _hurd_port_init (&new->port, MACH_PORT_NULL); - _hurd_port_init (&new->ctty, MACH_PORT_NULL); - - /* Install the port in the descriptor. - This sets up all the ctty magic. */ - _hurd_port2fd (new, _hurd_init_dtable[i], 0); - - _hurd_dtable[i] = new; - } - } - - /* Clear out the initial descriptor table. - Everything must use _hurd_dtable now. */ - __vm_deallocate (__mach_task_self (), - (vm_address_t) _hurd_init_dtable, - _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0])); - _hurd_init_dtable = NULL; - _hurd_init_dtablesize = 0; - - /* Initialize the remaining empty slots in the table. */ - for (; i < _hurd_dtablesize; ++i) - _hurd_dtable[i] = NULL; - - /* Run things that want to run after the file descriptor table - is initialized. */ - RUN_HOOK (_hurd_fd_subinit, ()); - - (void) &init_dtable; /* Avoid "defined but not used" warning. */ -} - -text_set_element (_hurd_subinit, init_dtable); - -/* XXX when the linker supports it, the following functions should all be - elsewhere and just have text_set_elements here. */ - -/* Called by `getdport' to do its work. */ - -static file_t -get_dtable_port (int fd) -{ - struct hurd_fd *d = _hurd_fd_get (fd); - file_t dport; - - if (!d) - return __hurd_fail (EBADF), MACH_PORT_NULL; - - HURD_CRITICAL_BEGIN; - - dport = HURD_PORT_USE (&d->port, - ({ - error_t err; - mach_port_t outport; - err = __mach_port_mod_refs (__mach_task_self (), - port, - MACH_PORT_RIGHT_SEND, - 1); - if (err) - { - errno = err; - outport = MACH_PORT_NULL; - } - else - outport = port; - outport; - })); - - HURD_CRITICAL_END; - - return dport; -} - -file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port; - -#include <hurd/signal.h> - -/* We are in the child fork; the dtable lock is still held. - The parent has inserted send rights for all the normal io ports, - but we must recover ctty-special ports for ourselves. */ -static error_t -fork_child_dtable (void) -{ - error_t err; - int i; - - err = 0; - - for (i = 0; !err && i < _hurd_dtablesize; ++i) - { - struct hurd_fd *d = _hurd_dtable[i]; - if (d == NULL) - continue; - - /* No other thread is using the send rights in the child task. */ - d->port.users = d->ctty.users = NULL; - - if (d->ctty.port != MACH_PORT_NULL) - { - /* There was a ctty-special port in the parent. - We need to get one for ourselves too. */ - __mach_port_deallocate (__mach_task_self (), d->ctty.port); - err = __term_open_ctty (d->port.port, _hurd_pid, _hurd_pgrp, - &d->ctty.port); - if (err) - d->ctty.port = MACH_PORT_NULL; - } - - /* XXX for each fd with a cntlmap, reauth and re-map_cntl. */ - } - return err; - - (void) &fork_child_dtable; /* Avoid "defined but not used" warning. */ -} - -data_set_element (_hurd_fork_locks, _hurd_dtable_lock); /* XXX ld bug: bss */ -text_set_element (_hurd_fork_child_hook, fork_child_dtable); - -/* Called when our process group has changed. */ - -static void -ctty_new_pgrp (void) -{ - int i; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_dtable_lock); - - if (__USEPORT (CTTYID, port == MACH_PORT_NULL)) - { - /* We have no controlling terminal. If we haven't had one recently, - but our pgrp is being pointlessly diddled anyway, then we will - have nothing to do in the loop below because no fd will have a - ctty port at all. - - More likely, a setsid call is responsible both for the change - in pgrp and for clearing the cttyid port. In that case, setsid - held the dtable lock while updating the dtable to clear all the - ctty ports, and ergo must have finished doing so before we run here. - So we can be sure, again, that the loop below has no work to do. */ - } - else - for (i = 0; i < _hurd_dtablesize; ++i) - { - struct hurd_fd *const d = _hurd_dtable[i]; - struct hurd_userlink ulink, ctty_ulink; - io_t port, ctty; - - if (d == NULL) - /* Nothing to do for an unused descriptor cell. */ - continue; - - port = _hurd_port_get (&d->port, &ulink); - ctty = _hurd_port_get (&d->ctty, &ctty_ulink); - - if (ctty != MACH_PORT_NULL) - { - /* This fd has a ctty-special port. We need a new one, to tell - the io server of our different process group. */ - io_t new; - if (__term_open_ctty (port, _hurd_pid, _hurd_pgrp, &new)) - new = MACH_PORT_NULL; - _hurd_port_set (&d->ctty, new); - } - - _hurd_port_free (&d->port, &ulink, port); - _hurd_port_free (&d->ctty, &ctty_ulink, ctty); - } - - __mutex_unlock (&_hurd_dtable_lock); - HURD_CRITICAL_END; - - (void) &ctty_new_pgrp; /* Avoid "defined but not used" warning. */ -} - -text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp); - -/* Called to reauthenticate the dtable when the auth port changes. */ - -static void -reauth_dtable (void) -{ - int i; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_dtable_lock); - - for (i = 0; i < _hurd_dtablesize; ++i) - { - struct hurd_fd *const d = _hurd_dtable[i]; - mach_port_t new, newctty, ref; - - if (d == NULL) - /* Nothing to do for an unused descriptor cell. */ - continue; - - ref = __mach_reply_port (); - - /* Take the descriptor cell's lock. */ - __spin_lock (&d->port.lock); - - /* Reauthenticate the descriptor's port. */ - if (d->port.port != MACH_PORT_NULL && - ! __io_reauthenticate (d->port.port, - ref, MACH_MSG_TYPE_MAKE_SEND) && - ! __USEPORT (AUTH, __auth_user_authenticate - (port, - ref, MACH_MSG_TYPE_MAKE_SEND, - &new))) - { - /* Replace the port in the descriptor cell - with the newly reauthenticated port. */ - - if (d->ctty.port != MACH_PORT_NULL && - ! __io_reauthenticate (d->ctty.port, - ref, MACH_MSG_TYPE_MAKE_SEND) && - ! __USEPORT (AUTH, __auth_user_authenticate - (port, - ref, MACH_MSG_TYPE_MAKE_SEND, - &newctty))) - _hurd_port_set (&d->ctty, newctty); - - _hurd_port_locked_set (&d->port, new); - } - else - /* Lost. Leave this descriptor cell alone. */ - __spin_unlock (&d->port.lock); - - __mach_port_destroy (__mach_task_self (), ref); - } - - __mutex_unlock (&_hurd_dtable_lock); - HURD_CRITICAL_END; - - (void) &reauth_dtable; /* Avoid "defined but not used" warning. */ -} - -text_set_element (_hurd_reauth_hook, reauth_dtable); diff --git a/hurd/exc2signal.c b/hurd/exc2signal.c deleted file mode 100644 index 3b9df0cca8..0000000000 --- a/hurd/exc2signal.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Translate Mach exception codes into signal numbers. Stub version. - Copyright (C) 1991-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/>. */ - -#include <hurd.h> -#include <hurd/signal.h> - -/* This file must be modified with machine-dependent details. */ -#error "need to write sysdeps/mach/hurd/MACHINE/exc2signal.c" - -/* Translate the Mach exception codes, as received in an `exception_raise' RPC, - into a signal number and signal subcode. */ - -void -_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo) -{ - detail->error = 0; - - switch (detail->exc) - { - default: - *signo = SIGIOT; - detail->code = detail->exc; - break; - - case EXC_BAD_ACCESS: - if (detail->exc_code == KERN_PROTECTION_FAILURE) - *signo = SIGSEGV; - else - *signo = SIGBUS; - detail->code = detail->exc_subcode; - detail->error = detail->exc_code; - break; - - case EXC_BAD_INSTRUCTION: - *signo = SIGILL; - detail->code = 0; - break; - - case EXC_ARITHMETIC: - *signo = SIGFPE; - detail->code = 0; - break; - - case EXC_EMULATION: - case EXC_SOFTWARE: - *signo = SIGEMT; - detail->code = 0; - break; - - case EXC_BREAKPOINT: - *signo = SIGTRAP; - detail->code = 0; - break; - } -} diff --git a/hurd/faultexc.defs b/hurd/faultexc.defs deleted file mode 100644 index fe7f02a4cc..0000000000 --- a/hurd/faultexc.defs +++ /dev/null @@ -1,5 +0,0 @@ -/* This file is processed by mig with -prefix _hurdsig_fault_ - to create the special exception server used for signal thread - fault recovery. */ - -#include <mach/exc.defs> diff --git a/hurd/fchroot.c b/hurd/fchroot.c deleted file mode 100644 index 877a3e9ea6..0000000000 --- a/hurd/fchroot.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 1999-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/>. */ - -#include <unistd.h> - -#include <hurd.h> -#include <hurd/fd.h> -#include <hurd/port.h> - -/* Change the current root directory to FD. */ -int -fchroot (int fd) -{ - error_t err; - file_t dir; - - err = HURD_DPORT_USE (fd, - ({ - dir = __file_name_lookup_under (port, ".", 0, 0); - dir == MACH_PORT_NULL ? errno : 0; - })); - - if (! err) - { - file_t root; - - /* Prevent going through DIR's .. */ - err = __file_reparent (dir, MACH_PORT_NULL, &root); - __mach_port_deallocate (__mach_task_self (), dir); - if (! err) - _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], root); - } - - return err ? __hurd_fail (err) : 0; -} diff --git a/hurd/fd-close.c b/hurd/fd-close.c deleted file mode 100644 index 2024517705..0000000000 --- a/hurd/fd-close.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 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/>. */ - -#include <hurd/fd.h> - -error_t -_hurd_fd_close (struct hurd_fd *fd) -{ - error_t err; - - HURD_CRITICAL_BEGIN; - - __spin_lock (&fd->port.lock); - if (fd->port.port == MACH_PORT_NULL) - { - __spin_unlock (&fd->port.lock); - err = EBADF; - } - else - { - /* Clear the descriptor's port cells. - This deallocates the ports if noone else is still using them. */ - _hurd_port_set (&fd->ctty, MACH_PORT_NULL); - _hurd_port_locked_set (&fd->port, MACH_PORT_NULL); - err = 0; - } - - HURD_CRITICAL_END; - - return err; -} diff --git a/hurd/fd-read.c b/hurd/fd-read.c deleted file mode 100644 index 361b96f969..0000000000 --- a/hurd/fd-read.c +++ /dev/null @@ -1,54 +0,0 @@ -/* 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/>. */ - -#include <errno.h> -#include <unistd.h> -#include <hurd.h> -#include <hurd/fd.h> -#include <string.h> - -error_t -_hurd_fd_read (struct hurd_fd *fd, void *buf, size_t *nbytes, loff_t offset) -{ - error_t err; - char *data; - mach_msg_type_number_t nread; - - error_t readfd (io_t port) - { - return __io_read (port, &data, &nread, offset, *nbytes); - } - - data = buf; - nread = *nbytes; - if (err = HURD_FD_PORT_USE (fd, _hurd_ctty_input (port, ctty, readfd))) - return err; - - if (data != buf) - { - if (nread > *nbytes) /* Sanity check for bogus server. */ - { - __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread); - return EGRATUITOUS; - } - memcpy (buf, data, nread); - __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread); - } - - *nbytes = nread; - return 0; -} diff --git a/hurd/fd-write.c b/hurd/fd-write.c deleted file mode 100644 index 8ab9bbd43b..0000000000 --- a/hurd/fd-write.c +++ /dev/null @@ -1,42 +0,0 @@ -/* _hurd_fd_write -- write to a file descriptor; handles job control et al. - 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/>. */ - -#include <errno.h> -#include <unistd.h> -#include <hurd.h> -#include <hurd/fd.h> - -error_t -_hurd_fd_write (struct hurd_fd *fd, - const void *buf, size_t *nbytes, loff_t offset) -{ - error_t err; - mach_msg_type_number_t wrote; - - error_t writefd (io_t port) - { - return __io_write (port, buf, *nbytes, offset, &wrote); - } - - err = HURD_FD_PORT_USE (fd, _hurd_ctty_output (port, ctty, writefd)); - - if (! err) - *nbytes = wrote; - - return err; -} diff --git a/hurd/fopenport.c b/hurd/fopenport.c deleted file mode 100644 index 42be313e6a..0000000000 --- a/hurd/fopenport.c +++ /dev/null @@ -1,132 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <stdio.h> -#include <fcntl.h> -#include <string.h> - -/* Read up to N chars into BUF from COOKIE. - Return how many chars were read, 0 for EOF or -1 for error. */ -static ssize_t -readio (void *cookie, char *buf, size_t n) -{ - mach_msg_type_number_t nread; - error_t err; - char *bufp = buf; - - nread = n; - if (err = __io_read ((io_t) cookie, &bufp, &nread, -1, n)) - return __hurd_fail (err); - - if (bufp != buf) - { - memcpy (buf, bufp, nread); - __vm_deallocate (__mach_task_self (), - (vm_address_t) bufp, (vm_size_t) nread); - } - - return nread; -} - -/* Write up to N chars from BUF to COOKIE. - Return how many chars were written or -1 for error. */ -static ssize_t -writeio (void *cookie, const char *buf, size_t n) -{ - mach_msg_type_number_t wrote; - error_t err; - - if (err = __io_write ((io_t) cookie, buf, n, -1, &wrote)) - return __hurd_fail (err); - - return wrote; -} - -/* Move COOKIE's file position *POS bytes, according to WHENCE. - The current file position is stored in *POS. - Returns zero if successful, nonzero if not. */ -static int -seekio (void *cookie, - _IO_off64_t *pos, - int whence) -{ - error_t err = __io_seek ((file_t) cookie, *pos, whence, pos); - return err ? __hurd_fail (err) : 0; -} - -/* Close the file associated with COOKIE. - Return 0 for success or -1 for failure. */ -static int -closeio (void *cookie) -{ - error_t error = __mach_port_deallocate (__mach_task_self (), - (mach_port_t) cookie); - if (error) - return __hurd_fail (error); - return 0; -} - -#include "../libio/libioP.h" -#define fopencookie _IO_fopencookie -static const cookie_io_functions_t funcsio = -{ readio, writeio, seekio, closeio }; - - -/* Open a stream on PORT. MODE is as for fopen. */ - -FILE * -__fopenport (mach_port_t port, const char *mode) -{ - int pflags; - int needflags; - error_t err; - - const char *m = mode; - - switch (*m++) - { - case 'r': - needflags = O_READ; - break; - case 'w': - needflags = O_WRITE; - break; - case 'a': - needflags = O_WRITE|O_APPEND; - break; - default: - return NULL; - } - if (m[0] == '+' || (m[0] == 'b' && m[1] == '+')) - needflags |= O_RDWR; - - /* Verify the PORT is valid allows the access MODE specifies. */ - - if (err = __io_get_openmodes (port, &pflags)) - return __hurd_fail (err), NULL; - - /* Check the access mode. */ - if ((pflags & needflags) != needflags) - { - errno = EBADF; - return NULL; - } - - return fopencookie ((void *) port, mode, funcsio); -} -weak_alias (__fopenport, fopenport) diff --git a/hurd/get-host.c b/hurd/get-host.c deleted file mode 100644 index be8345fbf9..0000000000 --- a/hurd/get-host.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Get a host configuration item kept as the whole contents of a file. - 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/>. */ - -#include <fcntl.h> -#include <hurd.h> -#include <hurd/lookup.h> -#include "hurdhost.h" -#include <string.h> - -ssize_t -_hurd_get_host_config (const char *item, char *buf, size_t buflen) -{ - error_t err; - char *data; - mach_msg_type_number_t nread, more; - file_t config; - - err = __hurd_file_name_lookup (&_hurd_ports_use, &__getdport, 0, - item, O_RDONLY, 0, &config); - switch (err) - { - case 0: /* Success; read file contents below. */ - break; - - case ENOENT: /* ? Others? All errors? */ - /* The file does not exist, so no value has been set. Rather than - causing gethostname et al to fail with ENOENT, give an empty value - as other systems do before sethostname has been called. */ - if (buflen != 0) - *buf = '\0'; - return 0; - - default: - return __hurd_fail (err); - } - - data = buf; - nread = buflen; - err = __io_read (config, &data, &nread, -1, buflen); - if (! err) - /* Check if there is more in the file we didn't read. */ - err = __io_readable (config, &more); - __mach_port_deallocate (__mach_task_self (), config); - if (err) - return __hurd_fail (err); - if (data != buf) - { - memcpy (buf, data, nread); - __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread); - } - - /* If the file is empty, give an empty value. */ - if (nread == 0) - { - if (buflen != 0) - *buf = '\0'; - return 0; - } - - /* Remove newlines in case someone wrote the file by hand. */ - while (nread > 0 && buf[nread - 1] == '\n') - buf[--nread] = '\0'; - - /* Null-terminate the result if there is enough space. */ - if (nread < buflen) - buf[nread] = '\0'; - else - if (buf[nread - 1] != '\0') - more = 1; - - if (more) - /* If we didn't read the whole file, tell the caller to use a bigger - buffer next time. */ - return __hurd_fail (ENAMETOOLONG); - - return nread; -} diff --git a/hurd/getdport.c b/hurd/getdport.c deleted file mode 100644 index d400a9f62d..0000000000 --- a/hurd/getdport.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> - -/* This is initialized in dtable.c when that gets linked in. - If dtable.c is not linked in, it will be zero. */ -static file_t (*_default_hurd_getdport_fn) (int fd) = 0; -weak_alias (_default_hurd_getdport_fn, _hurd_getdport_fn) - -file_t -__getdport (int fd) -{ - if (_hurd_getdport_fn) - /* dtable.c has defined the function to fetch a port from the real file - descriptor table. */ - return (*_hurd_getdport_fn) (fd); - - /* getdport is the only use of file descriptors, - so we don't bother allocating a real table. */ - - if (_hurd_init_dtable == NULL) - { - /* Never had a descriptor table. */ - errno = EBADF; - return MACH_PORT_NULL; - } - - if (fd < 0 || (unsigned int) fd > _hurd_init_dtablesize || - _hurd_init_dtable[fd] == MACH_PORT_NULL) - { - errno = EBADF; - return MACH_PORT_NULL; - } - else - { - __mach_port_mod_refs (__mach_task_self (), _hurd_init_dtable[fd], - MACH_PORT_RIGHT_SEND, 1); - return _hurd_init_dtable[fd]; - } -} - -weak_alias (__getdport, getdport) diff --git a/hurd/geteuids.c b/hurd/geteuids.c deleted file mode 100644 index 5c0796fef9..0000000000 --- a/hurd/geteuids.c +++ /dev/null @@ -1,68 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/id.h> -#include <string.h> - -int -geteuids (int n, uid_t *uidset) -{ - error_t err; - int nuids; - void *crit; - - crit = _hurd_critical_section_lock (); - __mutex_lock (&_hurd_id.lock); - - if (err = _hurd_check_ids ()) - { - __mutex_unlock (&_hurd_id.lock); - _hurd_critical_section_unlock (crit); - return __hurd_fail (err); - } - - nuids = _hurd_id.gen.nuids; - - if (n != 0) - { - /* Copy the uids onto stack storage and then release the idlock. */ - uid_t uids[nuids]; - memcpy (uids, _hurd_id.gen.uids, sizeof (uids)); - __mutex_unlock (&_hurd_id.lock); - _hurd_critical_section_unlock (crit); - - /* Now that the lock is released, we can safely copy the - uid set into the user's array, which might fault. */ - if (nuids > n) - nuids = n; - memcpy (uidset, uids, nuids * sizeof (uid_t)); - } - else - { - __mutex_unlock (&_hurd_id.lock); - _hurd_critical_section_unlock (crit); - } - - return nuids; -} - -/* XXX Remove this alias when we bump the libc soname. */ - -#ifdef SHARED -weak_alias (geteuids, __getuids) -#endif diff --git a/hurd/getumask.c b/hurd/getumask.c deleted file mode 100644 index 452a671720..0000000000 --- a/hurd/getumask.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (C) 1992-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/>. */ - -#include <hurd.h> - -mode_t -getumask (void) -{ - return _hurd_umask; -} diff --git a/hurd/hurd-raise.c b/hurd/hurd-raise.c deleted file mode 100644 index af99db38bd..0000000000 --- a/hurd/hurd-raise.c +++ /dev/null @@ -1,50 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/signal.h> -#include <hurd/msg.h> -#include <setjmp.h> - -/* Handle signal SIGNO in the calling thread. - If SS is not NULL it is the sigstate for the calling thread; - SS->lock is held on entry and released before return. */ - -int -_hurd_raise_signal (struct hurd_sigstate *ss, - int signo, const struct hurd_signal_detail *detail) -{ - if (ss == NULL) - { - ss = _hurd_self_sigstate (); - __spin_lock (&ss->lock); - } - - /* Mark SIGNO as pending to be delivered. */ - __sigaddset (&ss->pending, signo); - ss->pending_data[signo] = *detail; - - __spin_unlock (&ss->lock); - - /* Send a message to the signal thread so it will wake up and check for - pending signals. This is a generic "poll request" message (SIGNO==0) - rather than delivering this signal and its detail, because we have - already marked the signal as pending for the particular thread we - want. Generating the signal with an RPC might deliver it to some - other thread. */ - return __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); -} diff --git a/hurd/hurd.h b/hurd/hurd.h deleted file mode 100644 index 3caa69fbdf..0000000000 --- a/hurd/hurd.h +++ /dev/null @@ -1,345 +0,0 @@ -/* 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_H - -#define _HURD_H 1 -#include <features.h> - - -/* Get types, macros, constants and function declarations - for all Mach microkernel interaction. */ -#include <mach.h> -#include <mach/mig_errors.h> - -/* Get types and constants necessary for Hurd interfaces. */ -#include <hurd/hurd_types.h> - -/* Get MiG stub declarations for commonly used Hurd interfaces. */ -#include <hurd/auth.h> -#include <hurd/process.h> -#include <hurd/fs.h> -#include <hurd/io.h> - -/* Get `struct hurd_port' and related definitions implementing lightweight - user references for ports. These are used pervasively throughout the C - library; this is here to avoid putting it in nearly every source file. */ -#include <hurd/port.h> - -#include <errno.h> - -#ifndef _HURD_H_EXTERN_INLINE -#define _HURD_H_EXTERN_INLINE __extern_inline -#endif - -_HURD_H_EXTERN_INLINE int -__hurd_fail (error_t err) -{ - switch (err) - { - case EMACH_SEND_INVALID_DEST: - case EMIG_SERVER_DIED: - /* The server has disappeared! */ - err = (error_t) EIEIO; - break; - - case KERN_NO_SPACE: - err = (error_t) ENOMEM; - break; - - case KERN_INVALID_ARGUMENT: - err = (error_t) EINVAL; - break; - - case 0: - return 0; - - default: - break; - } - - errno = err; - return -1; -} - -/* Basic ports and info, initialized by startup. */ - -extern int _hurd_exec_flags; /* Flags word passed in exec_startup. */ -extern struct hurd_port *_hurd_ports; -extern unsigned int _hurd_nports; -extern mode_t _hurd_umask; -extern sigset_t _hurdsig_traced; - -/* Shorthand macro for internal library code referencing _hurd_ports (see - <hurd/port.h>). */ - -#define __USEPORT(which, expr) \ - HURD_PORT_USE (&_hurd_ports[INIT_PORT_##which], (expr)) - -/* Function version of __USEPORT: calls OPERATE with a send right. */ - -extern error_t _hurd_ports_use (int which, error_t (*operate) (mach_port_t)); - - -/* Base address and size of the initial stack set up by the exec server. - If using cthreads, this stack is deallocated in startup. - Not locked. */ - -extern vm_address_t _hurd_stack_base; -extern vm_size_t _hurd_stack_size; - -/* Initial file descriptor table we were passed at startup. If we are - using a real dtable, these are turned into that and then cleared at - startup. If not, these are never changed after startup. Not locked. */ - -extern mach_port_t *_hurd_init_dtable; -extern mach_msg_type_number_t _hurd_init_dtablesize; - -/* Current process IDs. */ - -extern pid_t _hurd_pid, _hurd_ppid, _hurd_pgrp; -extern int _hurd_orphaned; - -/* This variable is incremented every time the process IDs change. */ -extern unsigned int _hurd_pids_changed_stamp; - -/* This condition is broadcast every time the process IDs change. */ -extern struct condition _hurd_pids_changed_sync; - -/* Unix `data break', for brk and sbrk. - If brk and sbrk are not used, this info will not be initialized or used. */ - - -/* Data break. This is what `sbrk (0)' returns. */ - -extern vm_address_t _hurd_brk; - -/* End of allocated space. This is generally `round_page (_hurd_brk)'. */ - -extern vm_address_t _hurd_data_end; - -/* This mutex locks _hurd_brk and _hurd_data_end. */ - -extern struct mutex _hurd_brk_lock; - -/* Set the data break to NEWBRK; _hurd_brk_lock must - be held, and is released on return. */ - -extern int _hurd_set_brk (vm_address_t newbrk); - -#include <bits/types/FILE.h> - -/* Calls to get and set basic ports. */ - -extern error_t _hurd_ports_get (unsigned int which, mach_port_t *result); -extern error_t _hurd_ports_set (unsigned int which, mach_port_t newport); - -extern process_t getproc (void); -extern file_t getcwdir (void), getcrdir (void); -extern auth_t getauth (void); -extern mach_port_t getcttyid (void); -extern int setproc (process_t); -extern int setcwdir (file_t), setcrdir (file_t); -extern int setcttyid (mach_port_t); - -/* Does reauth with the proc server and fd io servers. */ -extern int __setauth (auth_t), setauth (auth_t); - - -/* Modify a port cell by looking up a directory name. - This verifies that it is a directory and that we have search permission. */ -extern int _hurd_change_directory_port_from_name (struct hurd_port *portcell, - const char *name); -/* Same thing, but using an open file descriptor. - Also verifies that it is a directory and that we have search permission. */ -extern int _hurd_change_directory_port_from_fd (struct hurd_port *portcell, - int fd); - - - -/* Get and set the effective UID set. */ -extern int geteuids (int __n, uid_t *__uidset); -extern int seteuids (int __n, const uid_t *__uidset); - - -/* Split FILE into a directory and a name within the directory. The - directory lookup uses the current root and working directory. If - successful, stores in *NAME a pointer into FILE where the name - within directory begins and returns a port to the directory; - otherwise sets `errno' and returns MACH_PORT_NULL. */ - -extern file_t __file_name_split (const char *file, char **name); -extern file_t file_name_split (const char *file, char **name); - -/* Split DIRECTORY into a parent directory and a name within the directory. - This is the same as file_name_split, but ignores trailing slashes. */ - -extern file_t __directory_name_split (const char *file, char **name); -extern file_t directory_name_split (const char *file, char **name); - -/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>). - The file lookup uses the current root and working directory. - Returns a port to the file if successful; otherwise sets `errno' - and returns MACH_PORT_NULL. */ - -extern file_t __file_name_lookup (const char *file, int flags, mode_t mode); -extern file_t file_name_lookup (const char *file, int flags, mode_t mode); - -/* Open a port to FILE with the given FLAGS and MODE (see <fcntl.h>). The - file lookup uses the current root directory, but uses STARTDIR as the - "working directory" for file relative names. Returns a port to the file - if successful; otherwise sets `errno' and returns MACH_PORT_NULL. */ - -extern file_t __file_name_lookup_under (file_t startdir, const char *file, - int flags, mode_t mode); -extern file_t file_name_lookup_under (file_t startdir, const char *file, - int flags, mode_t mode); - - -/* Lookup FILE_NAME and return the node opened with FLAGS & MODE - (see hurd_file_name_lookup for details), but a simple file name (without - any directory prefixes) will be consecutively prefixed with the pathnames - in the `:' separated list PATH until one succeeds in a successful lookup. - If none succeed, then the first error that wasn't ENOENT is returned, or - ENOENT if no other errors were returned. If PREFIXED_NAME is non-NULL, - then if the result is looked up directly, *PREFIXED_NAME is set to NULL, and - if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to - malloc'd storage containing the prefixed name. */ -extern file_t file_name_path_lookup (const char *file_name, const char *path, - int flags, mode_t mode, - char **prefixed_name); - - - -/* Open a file descriptor on a port. FLAGS are as for `open'; flags - affected by io_set_openmodes are not changed by this. If successful, - this consumes a user reference for PORT (which will be deallocated on - close). */ - -extern int openport (io_t port, int flags); - -/* Open a stream on a port. MODE is as for `fopen'. - If successful, this consumes a user reference for PORT - (which will be deallocated on fclose). */ - -extern FILE *fopenport (io_t port, const char *mode); -extern FILE *__fopenport (io_t port, const char *mode); - - -/* Execute a file, replacing TASK's current program image. */ - -extern error_t _hurd_exec (task_t task, - file_t file, - char *const argv[], - char *const envp[]); - - -/* Inform the proc server we have exited with STATUS, and kill the - task thoroughly. This function never returns, no matter what. */ - -extern void _hurd_exit (int status) __attribute__ ((noreturn)); - - -/* Initialize the library data structures from the - ints and ports passed to us by the exec server. - Then vm_deallocate PORTARRAY and INTARRAY. */ - -extern void _hurd_init (int flags, char **argv, - mach_port_t *portarray, size_t portarraysize, - int *intarray, size_t intarraysize); - -/* Do startup handshaking with the proc server, and initialize library data - structures that require proc server interaction. This includes - initializing signals; see _hurdsig_init in <hurd/signal.h>. */ - -extern void _hurd_proc_init (char **argv, - const int *intarray, size_t intarraysize); - - -/* Return the socket server for sockaddr domain DOMAIN. If DEAD is - nonzero, remove the old cached port and always do a fresh lookup. - - It is assumed that a socket server will stay alive during a complex socket - operation involving several RPCs. But a socket server may die during - long idle periods between socket operations. Callers should first pass - zero for DEAD; if the first socket RPC tried on the returned port fails - with MACH_SEND_INVALID_DEST or MIG_SERVER_DIED (indicating the server - went away), the caller should call _hurd_socket_server again with DEAD - nonzero and retry the RPC on the new socket server port. */ - -extern socket_t _hurd_socket_server (int domain, int dead); - -/* Send a `sig_post' RPC to process number PID. If PID is zero, - send the message to all processes in the current process's process group. - If PID is < -1, send SIG to all processes in process group - PID. - SIG and REFPORT are passed along in the request message. */ - -extern error_t _hurd_sig_post (pid_t pid, int sig, mach_port_t refport); -extern error_t hurd_sig_post (pid_t pid, int sig, mach_port_t refport); - -/* Fetch the host privileged port and device master port from the proc - server. They are fetched only once and then cached in the - variables below. A special program that gets them from somewhere - other than the proc server (such as a bootstrap filesystem) can set - these variables to install the ports. */ - -extern kern_return_t __get_privileged_ports (mach_port_t *host_priv_ptr, - device_t *device_master_ptr); -extern kern_return_t get_privileged_ports (mach_port_t *host_priv_ptr, - device_t *device_master_ptr); -extern mach_port_t _hurd_host_priv, _hurd_device_master; - -/* Return the PID of the task whose control port is TASK. - On error, sets `errno' and returns -1. */ - -extern pid_t __task2pid (task_t task), task2pid (task_t task); - -/* Return the task control port of process PID. - On error, sets `errno' and returns MACH_PORT_NULL. */ - -extern task_t __pid2task (pid_t pid), pid2task (pid_t pid); - -/* Return the current thread's thread port. This is a cheap operation (no - system call), but it relies on Hurd signal state being set up. */ -extern thread_t hurd_thread_self (void); - - -/* Cancel pending operations on THREAD. If it is doing an interruptible RPC, - that RPC will now return EINTR; otherwise, the "cancelled" flag will be - set, causing the next `hurd_check_cancel' call to return nonzero or the - next interruptible RPC to return EINTR (whichever is called first). */ -extern error_t hurd_thread_cancel (thread_t thread); - -/* Test and clear the calling thread's "cancelled" flag. */ -extern int hurd_check_cancel (void); - - -/* Return the io server port for file descriptor FD. - This adds a Mach user reference to the returned port. - On error, sets `errno' and returns MACH_PORT_NULL. */ - -extern io_t __getdport (int fd), getdport (int fd); - - -#include <stdarg.h> - -/* Write formatted output to PORT, a Mach port supporting the i/o protocol, - according to the format string FORMAT, using the argument list in ARG. */ -int vpprintf (io_t port, const char *format, va_list arg); - - -#endif /* hurd.h */ diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h deleted file mode 100644 index 8954be0d50..0000000000 --- a/hurd/hurd/fd.h +++ /dev/null @@ -1,275 +0,0 @@ -/* 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/hurd/hurd/id.h b/hurd/hurd/id.h deleted file mode 100644 index ef1292ebe8..0000000000 --- a/hurd/hurd/id.h +++ /dev/null @@ -1,54 +0,0 @@ -/* 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/hurd/hurd/ioctl.h b/hurd/hurd/ioctl.h deleted file mode 100644 index 0423b8cb9f..0000000000 --- a/hurd/hurd/ioctl.h +++ /dev/null @@ -1,81 +0,0 @@ -/* 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/hurd/hurd/lookup.h b/hurd/hurd/lookup.h deleted file mode 100644 index 99052994c7..0000000000 --- a/hurd/hurd/lookup.h +++ /dev/null @@ -1,190 +0,0 @@ -/* 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/hurd/hurd/port.h b/hurd/hurd/port.h deleted file mode 100644 index 94874f8f25..0000000000 --- a/hurd/hurd/port.h +++ /dev/null @@ -1,158 +0,0 @@ -/* 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/hurd/hurd/resource.h b/hurd/hurd/resource.h deleted file mode 100644 index c550d04f07..0000000000 --- a/hurd/hurd/resource.h +++ /dev/null @@ -1,51 +0,0 @@ -/* 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/hurd/hurd/signal.h b/hurd/hurd/signal.h deleted file mode 100644 index e03d53e6d7..0000000000 --- a/hurd/hurd/signal.h +++ /dev/null @@ -1,364 +0,0 @@ -/* 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/hurd/hurd/sigpreempt.h b/hurd/hurd/sigpreempt.h deleted file mode 100644 index 406f0f58fa..0000000000 --- a/hurd/hurd/sigpreempt.h +++ /dev/null @@ -1,102 +0,0 @@ -/* 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/hurd/hurd/threadvar.h b/hurd/hurd/threadvar.h deleted file mode 100644 index 72982e1744..0000000000 --- a/hurd/hurd/threadvar.h +++ /dev/null @@ -1,116 +0,0 @@ -/* 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/hurd/hurd/userlink.h b/hurd/hurd/userlink.h deleted file mode 100644 index 4946402df5..0000000000 --- a/hurd/hurd/userlink.h +++ /dev/null @@ -1,147 +0,0 @@ -/* 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/hurd/hurd/xattr.h b/hurd/hurd/xattr.h deleted file mode 100644 index bc4c2ce451..0000000000 --- a/hurd/hurd/xattr.h +++ /dev/null @@ -1,34 +0,0 @@ -/* 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 */ diff --git a/hurd/hurdauth.c b/hurd/hurdauth.c deleted file mode 100644 index 6a7d69d027..0000000000 --- a/hurd/hurdauth.c +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> -#include <hurd/msg_server.h> -#include <hurd/id.h> -#include <string.h> - -int -_hurd_refport_secure_p (mach_port_t ref) -{ - if (ref == __mach_task_self ()) - return 1; - if (__USEPORT (AUTH, ref == port)) - return 1; - return 0; -} - -kern_return_t -_S_msg_add_auth (mach_port_t me, - auth_t addauth) -{ - error_t err; - auth_t newauth; - uid_t *genuids, *gengids, *auxuids, *auxgids; - mach_msg_type_number_t ngenuids, ngengids, nauxuids, nauxgids; - uid_t *newgenuids, *newgengids, *newauxuids, *newauxgids; - mach_msg_type_number_t nnewgenuids, nnewgengids, nnewauxuids, nnewauxgids; - - /* Create a list of ids and store it in NEWLISTP, length NEWLISTLEN. - Keep all the ids in EXIST (len NEXIST), adding in those from NEW - (len NNEW) which are not already there. */ - error_t make_list (uid_t **newlistp, mach_msg_type_number_t *newlistlen, - uid_t *exist, mach_msg_type_number_t nexist, - uid_t *new, mach_msg_type_number_t nnew) - { - error_t urp; - int i, j, k; - vm_size_t offset; - - urp = vm_allocate (mach_task_self (), (vm_address_t *) newlistp, - nexist + nnew * sizeof (uid_t), 1); - if (urp) - return urp; - - j = 0; - for (i = 0; i < nexist; i++) - (*newlistp)[j++] = exist[i]; - - for (i = 0; i < nnew; i++) - { - for (k = 0; k < nexist; k++) - if (exist[k] == new[i]) - break; - if (k < nexist) - continue; - - (*newlistp)[j++] = new[i]; - } - - offset = (round_page (nexist + nnew * sizeof (uid_t)) - - round_page (j * sizeof (uid_t))); - if (offset) - vm_deallocate (mach_task_self (), - (vm_address_t) (*newlistp - + (nexist + nnew * sizeof (uid_t))), - offset); - *newlistlen = j; - return 0; - } - - /* Find out what ids ADDAUTH refers to */ - - genuids = gengids = auxuids = auxgids = 0; - ngenuids = ngengids = nauxuids = nauxgids = 0; - err = __auth_getids (addauth, - &genuids, &ngenuids, - &auxuids, &nauxuids, - &gengids, &ngengids, - &auxgids, &nauxgids); - if (err) - return err; - - /* OR in these ids to what we already have, creating a new list. */ - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_id.lock); - _hurd_check_ids (); - -#define MAKE(genaux,uidgid) \ - make_list (&new ## genaux ## uidgid ## s, \ - &nnew ## genaux ## uidgid ## s, \ - _hurd_id.genaux.uidgid ## s, \ - _hurd_id.genaux.n ## uidgid ## s, \ - genaux ## uidgid ## s, \ - n ## genaux ## uidgid ## s) - - err = MAKE (gen, uid); - if (!err) - MAKE (aux, uid); - if (!err) - MAKE (gen, gid); - if (!err) - MAKE (aux, gid); -#undef MAKE - - __mutex_unlock (&_hurd_id.lock); - HURD_CRITICAL_END; - - - /* Create the new auth port */ - - if (!err) - err = __USEPORT (AUTH, - __auth_makeauth (port, - &addauth, MACH_MSG_TYPE_MOVE_SEND, 1, - newgenuids, nnewgenuids, - newauxuids, nnewauxuids, - newgengids, nnewgengids, - newauxgids, nnewauxgids, - &newauth)); - -#define freeup(array, len) \ - if (array) \ - vm_deallocate (mach_task_self (), (vm_address_t) array, \ - len * sizeof (uid_t)); - - freeup (genuids, ngenuids); - freeup (auxuids, nauxuids); - freeup (gengids, ngengids); - freeup (auxgids, nauxgids); - freeup (newgenuids, nnewgenuids); - freeup (newauxuids, nnewauxuids); - freeup (newgengids, nnewgengids); - freeup (newauxgids, nnewauxgids); -#undef freeup - - if (err) - return err; - - /* And install it. */ - - err = __setauth (newauth); - __mach_port_deallocate (__mach_task_self (), newauth); - if (err) - return errno; - - return 0; -} - -kern_return_t -_S_msg_del_auth (mach_port_t me, - task_t task, - intarray_t uids, mach_msg_type_number_t nuids, - intarray_t gids, mach_msg_type_number_t ngids) -{ - error_t err; - auth_t newauth; - - if (!_hurd_refport_secure_p (task)) - return EPERM; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_id.lock); - err = _hurd_check_ids (); - - if (!err) - { - size_t i, j; - size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids; - uid_t newu[nu]; - gid_t newg[ng]; - - memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t)); - memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t)); - - for (j = 0; j < nuids; ++j) - { - const uid_t uid = uids[j]; - for (i = 0; i < nu; ++i) - if (newu[i] == uid) - /* Move the last uid into this slot, and decrease the - number of uids so the last slot is no longer used. */ - newu[i] = newu[--nu]; - } - __vm_deallocate (__mach_task_self (), - (vm_address_t) uids, nuids * sizeof (uid_t)); - - for (j = 0; j < ngids; ++j) - { - const gid_t gid = gids[j]; - for (i = 0; i < nu; ++i) - if (newu[i] == gid) - /* Move the last gid into this slot, and decrease the - number of gids so the last slot is no longer used. */ - newu[i] = newu[--nu]; - } - __vm_deallocate (__mach_task_self (), - (vm_address_t) gids, ngids * sizeof (gid_t)); - - err = __USEPORT (AUTH, __auth_makeauth - (port, - NULL, MACH_MSG_TYPE_COPY_SEND, 0, - newu, nu, - _hurd_id.aux.uids, _hurd_id.aux.nuids, - newg, ng, - _hurd_id.aux.uids, _hurd_id.aux.ngids, - &newauth)); - } - __mutex_unlock (&_hurd_id.lock); - HURD_CRITICAL_END; - - if (err) - return err; - - err = __setauth (newauth); - __mach_port_deallocate (__mach_task_self (), newauth); - if (err) - return errno; - - return 0; -} diff --git a/hurd/hurdchdir.c b/hurd/hurdchdir.c deleted file mode 100644 index b38734d8f6..0000000000 --- a/hurd/hurdchdir.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Change a port cell to a directory by looking up a name. - Copyright (C) 1999-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/>. */ - -#include <errno.h> -#include <unistd.h> -#include <hurd.h> -#include <hurd/port.h> -#include <hurd/fd.h> -#include <fcntl.h> -#include <string.h> - -int -_hurd_change_directory_port_from_name (struct hurd_port *portcell, - const char *name) -{ - size_t len; - const char *lookup; - file_t dir; - - /* Append trailing "/." to directory name to force ENOTDIR if it's not a - directory and EACCES if we don't have search permission. */ - len = strlen (name); - if (len >= 2 && name[len - 2] == '/' && name[len - 1] == '.') - lookup = name; - else if (len == 0) - /* Special-case empty file name according to POSIX. */ - return __hurd_fail (ENOENT); - else - { - char *n = alloca (len + 3); - memcpy (n, name, len); - n[len] = '/'; - n[len + 1] = '.'; - n[len + 2] = '\0'; - lookup = n; - } - - dir = __file_name_lookup (lookup, 0, 0); - if (dir == MACH_PORT_NULL) - return -1; - - _hurd_port_set (portcell, dir); - return 0; -} diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c deleted file mode 100644 index 98b8dca674..0000000000 --- a/hurd/hurdexec.c +++ /dev/null @@ -1,403 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <hurd.h> -#include <hurd/fd.h> -#include <hurd/signal.h> -#include <hurd/id.h> -#include <assert.h> -#include <argz.h> - -/* Overlay TASK, executing FILE with arguments ARGV and environment ENVP. - If TASK == mach_task_self (), some ports are dealloc'd by the exec server. - ARGV and ENVP are terminated by NULL pointers. */ -error_t -_hurd_exec (task_t task, file_t file, - char *const argv[], char *const envp[]) -{ - error_t err; - char *args, *env; - size_t argslen, envlen; - int ints[INIT_INT_MAX]; - mach_port_t ports[_hurd_nports]; - struct hurd_userlink ulink_ports[_hurd_nports]; - inline void free_port (unsigned int i) - { - _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]); - } - file_t *dtable; - unsigned int dtablesize, i; - struct hurd_port **dtable_cells; - struct hurd_userlink *ulink_dtable; - struct hurd_sigstate *ss; - mach_port_t *please_dealloc, *pdp; - int reauth = 0; - - /* XXX needs to be hurdmalloc XXX */ - if (argv == NULL) - args = NULL, argslen = 0; - else if (err = __argz_create (argv, &args, &argslen)) - return err; - if (envp == NULL) - env = NULL, envlen = 0; - else if (err = __argz_create (envp, &env, &envlen)) - goto outargs; - - /* Load up the ports to give to the new program. */ - for (i = 0; i < _hurd_nports; ++i) - if (i == INIT_PORT_PROC && task != __mach_task_self ()) - { - /* This is another task, so we need to ask the proc server - for the right proc server port for it. */ - if (err = __USEPORT (PROC, __proc_task2proc (port, task, &ports[i]))) - { - while (--i > 0) - free_port (i); - goto outenv; - } - } - else - ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]); - - - /* Load up the ints to give the new program. */ - for (i = 0; i < INIT_INT_MAX; ++i) - switch (i) - { - case INIT_UMASK: - ints[i] = _hurd_umask; - break; - - case INIT_SIGMASK: - case INIT_SIGIGN: - case INIT_SIGPENDING: - /* We will set these all below. */ - break; - - case INIT_TRACEMASK: - ints[i] = _hurdsig_traced; - break; - - default: - ints[i] = 0; - } - - ss = _hurd_self_sigstate (); - - assert (! __spin_lock_locked (&ss->critical_section_lock)); - __spin_lock (&ss->critical_section_lock); - - __spin_lock (&ss->lock); - ints[INIT_SIGMASK] = ss->blocked; - ints[INIT_SIGPENDING] = ss->pending; - ints[INIT_SIGIGN] = 0; - for (i = 1; i < NSIG; ++i) - if (ss->actions[i].sa_handler == SIG_IGN) - ints[INIT_SIGIGN] |= __sigmask (i); - - /* We hold the sigstate lock until the exec has failed so that no signal - can arrive between when we pack the blocked and ignored signals, and - when the exec actually happens. A signal handler could change what - signals are blocked and ignored. Either the change will be reflected - in the exec, or the signal will never be delivered. Setting the - critical section flag avoids anything we call trying to acquire the - sigstate lock. */ - - __spin_unlock (&ss->lock); - - /* Pack up the descriptor table to give the new program. */ - __mutex_lock (&_hurd_dtable_lock); - - dtablesize = _hurd_dtable ? _hurd_dtablesize : _hurd_init_dtablesize; - - if (task == __mach_task_self ()) - /* Request the exec server to deallocate some ports from us if the exec - succeeds. The init ports and descriptor ports will arrive in the - new program's exec_startup message. If we failed to deallocate - them, the new program would have duplicate user references for them. - But we cannot deallocate them ourselves, because we must still have - them after a failed exec call. */ - please_dealloc = __alloca ((_hurd_nports + 3 + (3 * dtablesize)) - * sizeof (mach_port_t)); - else - please_dealloc = NULL; - pdp = please_dealloc; - - if (_hurd_dtable != NULL) - { - dtable = __alloca (dtablesize * sizeof (dtable[0])); - ulink_dtable = __alloca (dtablesize * sizeof (ulink_dtable[0])); - dtable_cells = __alloca (dtablesize * sizeof (dtable_cells[0])); - for (i = 0; i < dtablesize; ++i) - { - struct hurd_fd *const d = _hurd_dtable[i]; - if (d == NULL) - { - dtable[i] = MACH_PORT_NULL; - continue; - } - __spin_lock (&d->port.lock); - if (d->flags & FD_CLOEXEC) - { - /* This descriptor is marked to be closed on exec. - So don't pass it to the new program. */ - dtable[i] = MACH_PORT_NULL; - if (pdp && d->port.port != MACH_PORT_NULL) - { - /* We still need to deallocate the ports. */ - *pdp++ = d->port.port; - if (d->ctty.port != MACH_PORT_NULL) - *pdp++ = d->ctty.port; - } - __spin_unlock (&d->port.lock); - } - else - { - if (pdp && d->ctty.port != MACH_PORT_NULL) - /* All the elements of DTABLE are added to PLEASE_DEALLOC - below, so we needn't add the port itself. - But we must deallocate the ctty port as well as - the normal port that got installed in DTABLE[I]. */ - *pdp++ = d->ctty.port; - dtable[i] = _hurd_port_locked_get (&d->port, &ulink_dtable[i]); - dtable_cells[i] = &d->port; - } - } - } - else - { - dtable = _hurd_init_dtable; - ulink_dtable = NULL; - dtable_cells = NULL; - } - - /* Prune trailing null ports from the descriptor table. */ - while (dtablesize > 0 && dtable[dtablesize - 1] == MACH_PORT_NULL) - --dtablesize; - - /* See if we need to diddle the auth port of the new program. - The purpose of this is to get the effect setting the saved-set UID and - GID to the respective effective IDs after the exec, as POSIX.1 requires. - Note that we don't reauthenticate with the proc server; that would be a - no-op since it only keeps track of the effective UIDs, and if it did - keep track of the available IDs we would have the problem that we'd be - changing the IDs before the exec and have to change them back after a - failure. Arguably we could skip all the reauthentications because the - available IDs have no bearing on any filesystem. But the conservative - approach is to reauthenticate all the io ports so that no state anywhere - reflects that our whole ID set differs from what we've set it to. */ - __mutex_lock (&_hurd_id.lock); - err = _hurd_check_ids (); - if (err == 0 && ((_hurd_id.aux.nuids >= 2 && _hurd_id.gen.nuids >= 1 - && _hurd_id.aux.uids[1] != _hurd_id.gen.uids[0]) - || (_hurd_id.aux.ngids >= 2 && _hurd_id.gen.ngids >= 1 - && _hurd_id.aux.gids[1] != _hurd_id.gen.gids[0]))) - { - /* We have euid != svuid or egid != svgid. POSIX.1 says that exec - sets svuid = euid and svgid = egid. So we must get a new auth - port and reauthenticate everything with it. We'll pass the new - ports in file_exec instead of our own ports. */ - - auth_t newauth; - - _hurd_id.aux.uids[1] = _hurd_id.gen.uids[0]; - _hurd_id.aux.gids[1] = _hurd_id.gen.gids[0]; - _hurd_id.valid = 0; - if (_hurd_id.rid_auth != MACH_PORT_NULL) - { - __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth); - _hurd_id.rid_auth = MACH_PORT_NULL; - } - - err = __auth_makeauth (ports[INIT_PORT_AUTH], - NULL, MACH_MSG_TYPE_COPY_SEND, 0, - _hurd_id.gen.uids, _hurd_id.gen.nuids, - _hurd_id.aux.uids, _hurd_id.aux.nuids, - _hurd_id.gen.gids, _hurd_id.gen.ngids, - _hurd_id.aux.gids, _hurd_id.aux.ngids, - &newauth); - if (err == 0) - { - /* Now we have to reauthenticate the ports with this new ID. - */ - - inline error_t reauth_io (io_t port, io_t *newport) - { - mach_port_t ref = __mach_reply_port (); - *newport = MACH_PORT_NULL; - error_t err = __io_reauthenticate (port, - ref, MACH_MSG_TYPE_MAKE_SEND); - if (!err) - err = __auth_user_authenticate (newauth, - ref, MACH_MSG_TYPE_MAKE_SEND, - newport); - __mach_port_destroy (__mach_task_self (), ref); - return err; - } - inline void reauth_port (unsigned int idx) - { - io_t newport; - err = reauth_io (ports[idx], &newport) ?: err; - if (pdp) - *pdp++ = ports[idx]; /* XXX presumed still in _hurd_ports */ - free_port (idx); - ports[idx] = newport; - } - - if (pdp) - *pdp++ = ports[INIT_PORT_AUTH]; - free_port (INIT_PORT_AUTH); - ports[INIT_PORT_AUTH] = newauth; - - reauth_port (INIT_PORT_CRDIR); - reauth_port (INIT_PORT_CWDIR); - - if (!err) - { - /* Now we'll reauthenticate each file descriptor. */ - if (ulink_dtable == NULL) - { - assert (dtable == _hurd_init_dtable); - dtable = __alloca (dtablesize * sizeof (dtable[0])); - for (i = 0; i < dtablesize; ++i) - if (_hurd_init_dtable[i] != MACH_PORT_NULL) - { - if (pdp) - *pdp++ = _hurd_init_dtable[i]; - err = reauth_io (_hurd_init_dtable[i], &dtable[i]); - if (err) - { - while (++i < dtablesize) - dtable[i] = MACH_PORT_NULL; - break; - } - } - else - dtable[i] = MACH_PORT_NULL; - } - else - { - if (pdp) - { - /* Ask to deallocate all the old fd ports, - since we will have new ones in DTABLE. */ - memcpy (pdp, dtable, dtablesize * sizeof pdp[0]); - pdp += dtablesize; - } - for (i = 0; i < dtablesize; ++i) - if (dtable[i] != MACH_PORT_NULL) - { - io_t newport; - err = reauth_io (dtable[i], &newport); - _hurd_port_free (dtable_cells[i], &ulink_dtable[i], - dtable[i]); - dtable[i] = newport; - if (err) - { - while (++i < dtablesize) - _hurd_port_free (dtable_cells[i], - &ulink_dtable[i], dtable[i]); - break; - } - } - ulink_dtable = NULL; - dtable_cells = NULL; - } - } - } - - reauth = 1; - } - __mutex_unlock (&_hurd_id.lock); - - /* The information is all set up now. Try to exec the file. */ - if (!err) - { - int flags; - - if (pdp) - { - /* Request the exec server to deallocate some ports from us if - the exec succeeds. The init ports and descriptor ports will - arrive in the new program's exec_startup message. If we - failed to deallocate them, the new program would have - duplicate user references for them. But we cannot deallocate - them ourselves, because we must still have them after a failed - exec call. */ - - for (i = 0; i < _hurd_nports; ++i) - *pdp++ = ports[i]; - for (i = 0; i < dtablesize; ++i) - *pdp++ = dtable[i]; - } - - flags = 0; -#ifdef EXEC_SIGTRAP - /* PTRACE_TRACEME sets all bits in _hurdsig_traced, which is - propagated through exec by INIT_TRACEMASK, so this checks if - PTRACE_TRACEME has been called in this process in any of its - current or prior lives. */ - if (__sigismember (&_hurdsig_traced, SIGKILL)) - flags |= EXEC_SIGTRAP; -#endif - err = __file_exec (file, task, flags, - args, argslen, env, envlen, - dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize, - ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports, - ints, INIT_INT_MAX, - please_dealloc, pdp - please_dealloc, - &_hurd_msgport, task == __mach_task_self () ? 1 : 0); - } - - /* Release references to the standard ports. */ - for (i = 0; i < _hurd_nports; ++i) - if ((i == INIT_PORT_PROC && task != __mach_task_self ()) - || (reauth && (i == INIT_PORT_AUTH - || i == INIT_PORT_CRDIR || i == INIT_PORT_CWDIR))) - __mach_port_deallocate (__mach_task_self (), ports[i]); - else - free_port (i); - - /* Release references to the file descriptor ports. */ - if (ulink_dtable != NULL) - { - for (i = 0; i < dtablesize; ++i) - if (dtable[i] != MACH_PORT_NULL) - _hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]); - } - else if (dtable && dtable != _hurd_init_dtable) - for (i = 0; i < dtablesize; ++i) - __mach_port_deallocate (__mach_task_self (), dtable[i]); - - /* Release lock on the file descriptor table. */ - __mutex_unlock (&_hurd_dtable_lock); - - /* Safe to let signals happen now. */ - _hurd_critical_section_unlock (ss); - - outargs: - free (args); - outenv: - free (env); - return err; -} diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c deleted file mode 100644 index 9cd65b6cd9..0000000000 --- a/hurd/hurdfault.c +++ /dev/null @@ -1,237 +0,0 @@ -/* Handle faults in the signal thread. - 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/>. */ - -#include <hurd.h> -#include <hurd/signal.h> -#include "hurdfault.h" -#include <errno.h> -#include <string.h> -#include <setjmp.h> -#include <stdio.h> -#include <thread_state.h> -#include "faultexc_server.h" /* mig-generated header for our exc server. */ -#include <assert.h> - -jmp_buf _hurdsig_fault_env; -struct hurd_signal_preemptor _hurdsig_fault_preemptor = {0}; - -/* XXX temporary to deal with spelling fix */ -weak_alias (_hurdsig_fault_preemptor, _hurdsig_fault_preempter) - -static mach_port_t forward_sigexc; - -kern_return_t -_hurdsig_fault_catch_exception_raise (mach_port_t port, - thread_t thread, - task_t task, -#ifdef EXC_MASK_ALL /* New interface flavor. */ - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt -#else /* Vanilla Mach 3.0 interface. */ - integer_t exception, - integer_t code, integer_t subcode -#endif - ) -{ - int signo; - struct hurd_signal_detail d; - - if (port != forward_sigexc || - thread != _hurd_msgport_thread || task != __mach_task_self ()) - return EPERM; /* Strange bogosity. */ - - d.exc = exception; -#ifdef EXC_MASK_ALL - assert (codeCnt >= 2); - d.exc_code = code[0]; - d.exc_subcode = code[1]; -#else - d.exc_code = code; - d.exc_subcode = subcode; -#endif - - /* Call the machine-dependent function to translate the Mach exception - codes into a signal number and subcode. */ - _hurd_exception2signal (&d, &signo); - - return HURD_PREEMPT_SIGNAL_P (&_hurdsig_fault_preemptor, signo, d.code) - ? 0 : EGREGIOUS; -} - -#ifdef EXC_MASK_ALL -/* XXX New interface flavor has additional RPCs that we could be using - instead. These RPCs roll a thread_get_state/thread_set_state into - the message, so the signal thread ought to use these to save some calls. - */ -kern_return_t -_hurdsig_fault_catch_exception_raise_state -(mach_port_t port, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt) -{ - abort (); - return KERN_FAILURE; -} - -kern_return_t -_hurdsig_fault_catch_exception_raise_state_identity -(mach_port_t exception_port, - thread_t thread, - task_t task, - exception_type_t exception, - exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt) -{ - abort (); - return KERN_FAILURE; -} -#endif - - -#ifdef NDR_CHAR_ASCII /* OSF Mach flavors have different names. */ -# define mig_reply_header_t mig_reply_error_t -#endif - -static void -faulted (void) -{ - struct - { - mach_msg_header_t head; - char buf[64]; - } request; - mig_reply_header_t reply; - extern int _hurdsig_fault_exc_server (mach_msg_header_t *, - mach_msg_header_t *); - - /* Wait for the exception_raise message forwarded by the proc server. */ - - if (__mach_msg (&request.head, MACH_RCV_MSG, 0, - sizeof request, forward_sigexc, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL) - != MACH_MSG_SUCCESS) - __libc_fatal ("msg receive failed on signal thread exc\n"); - - /* Run the exc demuxer which should call the server function above. - That function returns 0 if the exception was expected. */ - _hurdsig_fault_exc_server (&request.head, &reply.Head); - if (reply.Head.msgh_remote_port != MACH_PORT_NULL) - __mach_msg (&reply.Head, MACH_SEND_MSG, reply.Head.msgh_size, - 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - if (reply.RetCode == MIG_BAD_ID) - __mach_msg_destroy (&request.head); - - if (reply.RetCode) - __libc_fatal ("BUG: unexpected fault in signal thread\n"); - - _hurdsig_fault_preemptor.signals = 0; - longjmp (_hurdsig_fault_env, 1); -} - -static char faultstack[1024]; - -/* Send exceptions for the signal thread to the proc server. - It will forward the message on to our message port, - and then restore the thread's state to code which - does `longjmp (_hurd_sigthread_fault_env, 1)'. */ - -void -_hurdsig_fault_init (void) -{ - error_t err; - struct machine_thread_state state; - mach_port_t sigexc; - - /* Allocate a port to receive signal thread exceptions. - We will move this receive right to the proc server. */ - err = __mach_port_allocate (__mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, &sigexc); - assert_perror (err); - err = __mach_port_allocate (__mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, &forward_sigexc); - assert_perror (err); - - /* Allocate a port to receive the exception msgs forwarded - from the proc server. */ - err = __mach_port_insert_right (__mach_task_self (), sigexc, - sigexc, MACH_MSG_TYPE_MAKE_SEND); - assert_perror (err); - - /* Set the queue limit for this port to just one. The proc server will - notice if we ever get a second exception while one remains queued and - unreceived, and decide we are hopelessly buggy. */ -#ifdef MACH_PORT_RECEIVE_STATUS_COUNT - { - const mach_port_limits_t lim = { mpl_qlimit: 1 }; - assert (MACH_PORT_RECEIVE_STATUS_COUNT == sizeof lim / sizeof (natural_t)); - err = __mach_port_set_attributes (__mach_task_self (), forward_sigexc, - MACH_PORT_RECEIVE_STATUS, - (mach_port_info_t) &lim, - MACH_PORT_RECEIVE_STATUS_COUNT); - } -#else - err = __mach_port_set_qlimit (__mach_task_self (), forward_sigexc, 1); -#endif - assert_perror (err); - - /* This state will be restored when we fault. - It runs the function above. */ - memset (&state, 0, sizeof state); - MACHINE_THREAD_STATE_SET_PC (&state, faulted); - MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack); - - err = __USEPORT - (PROC, - __proc_handle_exceptions (port, - sigexc, - forward_sigexc, MACH_MSG_TYPE_MAKE_SEND, - MACHINE_THREAD_STATE_FLAVOR, - (natural_t *) &state, - MACHINE_THREAD_STATE_COUNT)); - assert_perror (err); - - /* Direct signal thread exceptions to the proc server. */ -#ifdef THREAD_EXCEPTION_PORT - err = __thread_set_special_port (_hurd_msgport_thread, - THREAD_EXCEPTION_PORT, sigexc); -#elif defined (EXC_MASK_ALL) - __thread_set_exception_ports (_hurd_msgport_thread, - EXC_MASK_ALL & ~(EXC_MASK_SYSCALL - | EXC_MASK_MACH_SYSCALL - | EXC_MASK_RPC_ALERT), - sigexc, - EXCEPTION_STATE_IDENTITY, - MACHINE_THREAD_STATE); -#else -# error thread_set_exception_ports? -#endif - __mach_port_deallocate (__mach_task_self (), sigexc); - assert_perror (err); -} diff --git a/hurd/hurdfault.h b/hurd/hurdfault.h deleted file mode 100644 index 9da5b684dc..0000000000 --- a/hurd/hurdfault.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Declarations for handling faults in the signal thread. - 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_FAULT_H -#define _HURD_FAULT_H - -#include <hurd/sigpreempt.h> -#include <setjmp.h> - -/* Call this before code that might fault in the signal thread; SIGNO is - the signal expected to possibly arrive. This behaves like setjmp: it - returns zero the first time, and returns again nonzero if the signal - does arrive. */ - -#define _hurdsig_catch_fault(sigset, firstcode, lastcode) \ - (_hurdsig_fault_preemptor.signals = (sigset), \ - _hurdsig_fault_preemptor.first = (long int) (firstcode), \ - _hurdsig_fault_preemptor.last = (long int) (lastcode), \ - setjmp (_hurdsig_fault_env)) - -/* Call this at the end of a section protected by _hurdsig_catch_fault. */ - -#define _hurdsig_end_catch_fault() \ - (_hurdsig_fault_preemptor.signals = 0) - -extern jmp_buf _hurdsig_fault_env; -extern struct hurd_signal_preemptor _hurdsig_fault_preemptor; - - -#define _hurdsig_catch_memory_fault(object) \ - _hurdsig_catch_fault (sigmask (SIGSEGV) | sigmask (SIGBUS), \ - (object), (object) + 1) - - -#endif /* hurdfault.h */ diff --git a/hurd/hurdfchdir.c b/hurd/hurdfchdir.c deleted file mode 100644 index 97c758b67f..0000000000 --- a/hurd/hurdfchdir.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Change a port cell to a directory in an open file descriptor. - Copyright (C) 1999-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/>. */ - -#include <errno.h> -#include <unistd.h> -#include <hurd.h> -#include <hurd/port.h> -#include <hurd/fd.h> -#include <fcntl.h> - -int -_hurd_change_directory_port_from_fd (struct hurd_port *portcell, int fd) -{ - int ret; - struct hurd_fd *d = _hurd_fd_get (fd); - - if (!d) - return __hurd_fail (EBADF); - - HURD_CRITICAL_BEGIN; - - ret = HURD_PORT_USE (&d->port, - ({ - int ret; - /* We look up "." to force ENOTDIR if it's not a - directory and EACCES if we don't have search - permission. */ - file_t dir = __file_name_lookup_under (port, ".", - O_NOTRANS, 0); - if (dir == MACH_PORT_NULL) - ret = -1; - else - { - _hurd_port_set (portcell, dir); - ret = 0; - } - ret; - })); - - HURD_CRITICAL_END; - - return ret; -} diff --git a/hurd/hurdhost.h b/hurd/hurdhost.h deleted file mode 100644 index c4e89517bc..0000000000 --- a/hurd/hurdhost.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Host configuration items kept as the whole contents of a file. - 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/>. */ - -/* Fetch and atomically store the contents of the file ITEM. - Returns the size read or written, or -1 for errors. - If BUFLEN is not big enough to contain the whole contents, - BUFLEN bytes of BUF are filled in and we fail with ENAMETOOLONG. */ - -ssize_t _hurd_get_host_config (const char *item, - char *buf, size_t buflen); -ssize_t _hurd_set_host_config (const char *item, - const char *value, size_t valuelen); diff --git a/hurd/hurdid.c b/hurd/hurdid.c deleted file mode 100644 index 66d760beef..0000000000 --- a/hurd/hurdid.c +++ /dev/null @@ -1,90 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/id.h> - -struct hurd_id_data _hurd_id; - - -/* Check that _hurd_id.{gen,aux} are valid and update them if not. - Expects _hurd_id.lock to be held and does not release it. */ - -error_t -_hurd_check_ids (void) -{ - if (! _hurd_id.valid) - { - inline void dealloc (__typeof (_hurd_id.gen) *p) - { - if (p->uids) - { - __vm_deallocate (__mach_task_self (), - (vm_address_t) p->uids, - p->nuids * sizeof (uid_t)); - p->uids = NULL; - } - p->nuids = 0; - if (p->gids) - { - __vm_deallocate (__mach_task_self (), - (vm_address_t) p->gids, - p->ngids * sizeof (gid_t)); - p->gids = NULL; - } - p->ngids = 0; - } - - error_t err; - - dealloc (&_hurd_id.gen); - dealloc (&_hurd_id.aux); - - if (_hurd_id.rid_auth != MACH_PORT_NULL) - { - __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth); - _hurd_id.rid_auth = MACH_PORT_NULL; - } - - if (err = __USEPORT (AUTH, __auth_getids - (port, - &_hurd_id.gen.uids, &_hurd_id.gen.nuids, - &_hurd_id.aux.uids, &_hurd_id.aux.nuids, - &_hurd_id.gen.gids, &_hurd_id.gen.ngids, - &_hurd_id.aux.gids, &_hurd_id.aux.ngids))) - return err; - - _hurd_id.valid = 1; - } - - return 0; -} - -static void -init_id (void) -{ - __mutex_init (&_hurd_id.lock); - _hurd_id.valid = 0; - _hurd_id.rid_auth = MACH_PORT_NULL; - _hurd_id.gen.uids = _hurd_id.aux.uids = NULL; - _hurd_id.gen.nuids = _hurd_id.aux.nuids = 0; - _hurd_id.gen.gids = _hurd_id.aux.gids = NULL; - _hurd_id.gen.ngids = _hurd_id.aux.ngids = 0; - - (void) &init_id; /* Avoid "defined but not used" warning. */ -} -text_set_element (_hurd_preinit_hook, init_id); diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c deleted file mode 100644 index 5afdfbc890..0000000000 --- a/hurd/hurdinit.c +++ /dev/null @@ -1,225 +0,0 @@ -/* Copyright (C) 1992-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/>. */ - -#include <sys/stat.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <hurd.h> -#include <hurd/port.h> -#include "set-hooks.h" -#include "hurdmalloc.h" /* XXX */ - - -int _hurd_exec_flags; -struct hurd_port *_hurd_ports; -unsigned int _hurd_nports; -mode_t _hurd_umask; -sigset_t _hurdsig_traced; - -char **__libc_argv; -int __libc_argc; - - -error_t -_hurd_ports_use (int which, error_t (*operate) (mach_port_t)) -{ - if (__glibc_unlikely (_hurd_ports == NULL)) - /* This means that _hurd_init has not been called yet, which is - normally only the case in the bootstrap filesystem, and there - only in the early phases of booting. */ - return EGRATUITOUS; - - return HURD_PORT_USE (&_hurd_ports[which], (*operate) (port)); -} - -DEFINE_HOOK (_hurd_subinit, (void)); - -__typeof (_hurd_proc_init) _hurd_new_proc_init; /* below */ - -/* Initialize the library data structures from the - ints and ports passed to us by the exec server. - - PORTARRAY and INTARRAY are vm_deallocate'd. */ - -void -_hurd_init (int flags, char **argv, - mach_port_t *portarray, size_t portarraysize, - int *intarray, size_t intarraysize) -{ - size_t i; - - _hurd_exec_flags = flags; - - _hurd_ports = malloc (portarraysize * sizeof (*_hurd_ports)); - if (_hurd_ports == NULL) - __libc_fatal ("Can't allocate _hurd_ports\n"); - _hurd_nports = portarraysize; - - /* See what ports we were passed. */ - for (i = 0; i < portarraysize; ++i) - _hurd_port_init (&_hurd_ports[i], portarray[i]); - - /* When the user asks for the bootstrap port, - he will get the one the exec server passed us. */ - __task_set_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT, - portarray[INIT_PORT_BOOTSTRAP]); - - if (intarraysize > INIT_UMASK) - _hurd_umask = intarray[INIT_UMASK] & 0777; - else - _hurd_umask = CMASK; - - if (intarraysize > INIT_TRACEMASK) - _hurdsig_traced = intarray[INIT_TRACEMASK]; - - /* Tell the proc server we exist, if it does. */ - if (portarray[INIT_PORT_PROC] != MACH_PORT_NULL) - _hurd_new_proc_init (argv, intarray, intarraysize); - - /* All done with init ints and ports. */ - __vm_deallocate (__mach_task_self (), - (vm_address_t) intarray, - intarraysize * sizeof (int)); - __vm_deallocate (__mach_task_self (), - (vm_address_t) portarray, - portarraysize * sizeof (mach_port_t)); - - if (flags & EXEC_SECURE) - /* XXX if secure exec, elide environment variables - which the library uses and could be security holes. - CORESERVER, COREFILE - */ ; - - /* Call other things which want to do some initialization. These are not - on the __libc_subinit hook because things there like to be able to - assume the availability of the POSIX.1 services we provide. */ - RUN_HOOK (_hurd_subinit, ()); -} - -#include <hurd/signal.h> - -/* The user can do "int _hide_arguments = 1;" to make - sure the arguments are never visible with `ps'. */ -int _hide_arguments, _hide_environment; - -/* Hook for things which should be initialized as soon as the proc - server is available. */ -DEFINE_HOOK (_hurd_proc_subinit, (void)); - -/* Do startup handshaking with the proc server just installed in _hurd_ports. - Call _hurdsig_init to set up signal processing. */ - -void -_hurd_new_proc_init (char **argv, - const int *intarray, size_t intarraysize) -{ - mach_port_t oldmsg; - struct hurd_userlink ulink; - process_t procserver; - - /* Initialize the signal code; Mach exceptions will become signals. */ - _hurdsig_init (intarray, intarraysize); - - /* The signal thread is now prepared to receive messages. - It is safe to give the port to the proc server. */ - - procserver = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink); - - /* Give the proc server our message port. */ - __proc_setmsgport (procserver, _hurd_msgport, &oldmsg); - if (oldmsg != MACH_PORT_NULL) - /* Deallocate the old msg port we replaced. */ - __mach_port_deallocate (__mach_task_self (), oldmsg); - - /* Tell the proc server where our args and environment are. */ - __proc_set_arg_locations (procserver, - _hide_arguments ? 0 : (vm_address_t) argv, - _hide_environment ? 0 : (vm_address_t) __environ); - - _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, procserver); - - /* Initialize proc server-assisted fault recovery for the signal thread. */ - _hurdsig_fault_init (); - - /* Call other things which want to do some initialization. These are not - on the _hurd_subinit hook because things there assume that things done - here, like _hurd_pid, are already initialized. */ - RUN_HOOK (_hurd_proc_subinit, ()); - - /* XXX This code should probably be removed entirely at some point. This - conditional should make it reasonably usable with old gdb's for a - while. Eventually it probably makes most sense for the exec server to - mask out EXEC_SIGTRAP so the debugged program is closer to not being - able to tell it's being debugged. */ - if (!__sigisemptyset (&_hurdsig_traced) -#ifdef EXEC_SIGTRAP - && !(_hurd_exec_flags & EXEC_SIGTRAP) -#endif - ) - /* This process is "traced", meaning it should stop on signals or exec. - We are all set up now to handle signals. Stop ourselves, to inform - our parent (presumably a debugger) that the exec has completed. */ - __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ()); -} - -#include <shlib-compat.h> -versioned_symbol (libc, _hurd_new_proc_init, _hurd_proc_init, GLIBC_2_1); - -/* Called when we get a message telling us to change our proc server port. */ - -error_t -_hurd_setproc (process_t procserver) -{ - error_t err; - mach_port_t oldmsg; - - /* Give the proc server our message port. */ - if (err = __proc_setmsgport (procserver, _hurd_msgport, &oldmsg)) - return err; - if (oldmsg != MACH_PORT_NULL) - /* Deallocate the old msg port we replaced. */ - __mach_port_deallocate (__mach_task_self (), oldmsg); - - /* Tell the proc server where our args and environment are. */ - if (err = __proc_set_arg_locations (procserver, - _hide_arguments ? 0 : - (vm_address_t) __libc_argv, - _hide_environment ? 0 : - (vm_address_t) __environ)) - return err; - - /* Those calls worked, so the port looks good. */ - _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver); - - { - pid_t oldpgrp = _hurd_pgrp; - - /* Call these functions again so they can fetch the - new information from the new proc server. */ - RUN_HOOK (_hurd_proc_subinit, ()); - - if (_hurd_pgrp != oldpgrp) - { - /* Run things that want notification of a pgrp change. */ - DECLARE_HOOK (_hurd_pgrp_changed_hook, (pid_t)); - RUN_HOOK (_hurd_pgrp_changed_hook, (_hurd_pgrp)); - } - } - - return 0; -} diff --git a/hurd/hurdioctl.c b/hurd/hurdioctl.c deleted file mode 100644 index 73ec3ea3cc..0000000000 --- a/hurd/hurdioctl.c +++ /dev/null @@ -1,331 +0,0 @@ -/* ioctl commands which must be done in the C library. - 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/>. */ - -#include <hurd.h> -#include <hurd/fd.h> -#include <sys/ioctl.h> -#include <hurd/ioctl.h> -#include <string.h> - - -/* Symbol set of ioctl handler lists. If there are user-registered - handlers, one of these lists will contain them. The other lists are - handlers built into the library. */ -symbol_set_define (_hurd_ioctl_handler_lists) - -/* Look up REQUEST in the set of handlers. */ -ioctl_handler_t -_hurd_lookup_ioctl_handler (int request) -{ - void *const *ptr; - const struct ioctl_handler *h; - - /* Mask off the type bits, so that we see requests in a single group as a - contiguous block of values. */ - request = _IOC_NOTYPE (request); - - for (ptr = symbol_set_first_element (_hurd_ioctl_handler_lists); - !symbol_set_end_p (_hurd_ioctl_handler_lists, ptr); - ++ptr) - for (h = *ptr; h != NULL; h = h->next) - if (request >= h->first_request && request <= h->last_request) - return h->handler; - - return NULL; -} - -#include <fcntl.h> - -/* Find out how many bytes may be read from FD without blocking. */ - -static int -fioctl (int fd, - int request, - int *arg) -{ - error_t err; - - *(volatile int *) arg = *arg; - - switch (request) - { - default: - err = ENOTTY; - break; - - case FIONREAD: - { - mach_msg_type_number_t navail; - err = HURD_DPORT_USE (fd, __io_readable (port, &navail)); - if (!err) - *arg = (int) navail; - } - break; - - case FIONBIO: - err = HURD_DPORT_USE (fd, (*arg ? - __io_set_some_openmodes : - __io_clear_some_openmodes) - (port, O_NONBLOCK)); - break; - - case FIOASYNC: - err = HURD_DPORT_USE (fd, (*arg ? - __io_set_some_openmodes : - __io_clear_some_openmodes) - (port, O_ASYNC)); - break; - - case FIOSETOWN: - err = HURD_DPORT_USE (fd, __io_mod_owner (port, *arg)); - break; - - case FIOGETOWN: - err = HURD_DPORT_USE (fd, __io_get_owner (port, arg)); - break; - } - - return err ? __hurd_dfail (fd, err) : 0; -} - -_HURD_HANDLE_IOCTLS (fioctl, FIOGETOWN, FIONREAD); - - -static int -fioclex (int fd, - int request) -{ - int flag; - - switch (request) - { - default: - return __hurd_fail (ENOTTY); - case FIOCLEX: - flag = FD_CLOEXEC; - break; - case FIONCLEX: - flag = 0; - break; - } - - return __fcntl (fd, F_SETFD, flag); -} -_HURD_HANDLE_IOCTLS (fioclex, FIOCLEX, FIONCLEX); - -#include <hurd/term.h> -#include <hurd/tioctl.h> - -/* 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) -{ - mach_port_t old; - struct hurd_port *const port = &_hurd_ports[INIT_PORT_CTTYID]; - struct hurd_userlink ulink; - int i; - - /* Install the new cttyid port, and preserve it with a ulink. - We unroll the _hurd_port_set + _hurd_port_get here so that - there is no window where the cell is unlocked and CTTYID could - be changed by another thread. (We also delay the deallocation - of the old port until the end, to minimize the duration of the - critical section.) - - It is important that changing the cttyid port is only ever done by - holding the dtable lock continuously while updating the port cell and - re-ctty'ing the dtable; dtable.c assumes we do this. Otherwise, the - pgrp-change notification code in dtable.c has to worry about racing - against us here in odd situations. The one exception to this is - setsid, which holds the dtable lock while changing the pgrp and - clearing the cttyid port, and then unlocks the dtable lock to allow - - - */ - - __spin_lock (&port->lock); - old = _hurd_userlink_clear (&port->users) ? port->port : MACH_PORT_NULL; - port->port = cttyid; - cttyid = _hurd_port_locked_get (port, &ulink); - - for (i = 0; i < _hurd_dtablesize; ++i) - { - struct hurd_fd *const d = _hurd_dtable[i]; - mach_port_t newctty = MACH_PORT_NULL; - - if (d == NULL) - /* Nothing to do for an unused descriptor cell. */ - continue; - - if (cttyid != MACH_PORT_NULL) - /* We do have some controlling tty. */ - HURD_PORT_USE (&d->port, - ({ mach_port_t id; - /* Get the io object's cttyid port. */ - if (! __term_getctty (port, &id)) - { - if (id == cttyid /* Is it ours? */ - /* Get the ctty io port. */ - && __term_open_ctty (port, - _hurd_pid, _hurd_pgrp, - &newctty)) - /* XXX it is our ctty but the call failed? */ - newctty = MACH_PORT_NULL; - __mach_port_deallocate (__mach_task_self (), id); - } - 0; - })); - - /* Install the new ctty port. */ - _hurd_port_set (&d->ctty, newctty); - } - - __mutex_unlock (&_hurd_dtable_lock); - - if (old != MACH_PORT_NULL) - __mach_port_deallocate (__mach_task_self (), old); - _hurd_port_free (port, &ulink, cttyid); -} - -static void -install_ctty (mach_port_t cttyid) -{ - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_dtable_lock); - _hurd_locked_install_cttyid (cttyid); - HURD_CRITICAL_END; -} - - -/* Called when we have received a message saying to use a new ctty ID port. */ - -error_t -_hurd_setcttyid (mach_port_t cttyid) -{ - error_t err; - - if (cttyid != MACH_PORT_NULL) - { - /* Give the new send right a user reference. - This is a good way to check that it is valid. */ - if (err = __mach_port_mod_refs (__mach_task_self (), cttyid, - MACH_PORT_RIGHT_SEND, 1)) - return err; - } - - /* Install the port, consuming the reference we just created. */ - install_ctty (cttyid); - - return 0; -} - - -static inline error_t -do_tiocsctty (io_t port, io_t ctty) -{ - mach_port_t cttyid; - error_t err; - - if (ctty != MACH_PORT_NULL) - /* PORT is already the ctty. Nothing to do. */ - return 0; - - /* Get PORT's cttyid port. */ - err = __term_getctty (port, &cttyid); - if (err) - return err; - - /* Change the terminal's pgrp to ours. */ - err = __tioctl_tiocspgrp (port, _hurd_pgrp); - if (err) - __mach_port_deallocate (__mach_task_self (), cttyid); - else - /* Make it our own. */ - install_ctty (cttyid); - - return err; -} - -/* Make FD be the controlling terminal. - This function is called for `ioctl (fd, TCIOSCTTY)'. */ - -static int -tiocsctty (int fd, - int request) /* Always TIOCSCTTY. */ -{ - return __hurd_fail (HURD_DPORT_USE (fd, do_tiocsctty (port, ctty))); -} -_HURD_HANDLE_IOCTL (tiocsctty, TIOCSCTTY); - -/* Dissociate from the controlling terminal. */ - -static int -tiocnotty (int fd, - int request) /* Always TIOCNOTTY. */ -{ - mach_port_t fd_cttyid; - error_t err; - - if (err = HURD_DPORT_USE (fd, __term_getctty (port, &fd_cttyid))) - return __hurd_fail (err); - - if (__USEPORT (CTTYID, port != fd_cttyid)) - err = EINVAL; - - __mach_port_deallocate (__mach_task_self (), fd_cttyid); - - if (err) - return __hurd_fail (err); - - /* Clear our cttyid port. */ - install_ctty (MACH_PORT_NULL); - - return 0; -} -_HURD_HANDLE_IOCTL (tiocnotty, TIOCNOTTY); - -#include <hurd/pfinet.h> -#include <net/if.h> -#include <netinet/in.h> - -/* Fill in the buffer IFC->IFC_BUF of length IFC->IFC_LEN with a list - of ifr structures, one for each network interface. */ -static int -siocgifconf (int fd, int request, struct ifconf *ifc) -{ - error_t err; - size_t data_len = ifc->ifc_len; - char *data = ifc->ifc_buf; - - if (data_len <= 0) - return 0; - - err = HURD_DPORT_USE (fd, __pfinet_siocgifconf (port, ifc->ifc_len, - &data, &data_len)); - if (data_len < ifc->ifc_len) - ifc->ifc_len = data_len; - if (data != ifc->ifc_buf) - { - memcpy (ifc->ifc_buf, data, ifc->ifc_len); - __vm_deallocate (__mach_task_self (), (vm_address_t) data, data_len); - } - return err ? __hurd_dfail (fd, err) : 0; -} -_HURD_HANDLE_IOCTL (siocgifconf, SIOCGIFCONF); diff --git a/hurd/hurdkill.c b/hurd/hurdkill.c deleted file mode 100644 index e8375d3d3d..0000000000 --- a/hurd/hurdkill.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <errno.h> -#include <sys/types.h> -#include <signal.h> -#include <hurd.h> -#include <hurd/port.h> -#include <hurd/signal.h> -#include <hurd/msg.h> - -/* Send a `sig_post' RPC to process number PID. If PID is zero, - send the message to all processes in the current process's process group. - If PID is < -1, send SIG to all processes in process group - PID. - SIG and REFPORT are passed along in the request message. */ -error_t -_hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport) -{ - int delivered = 0; /* Set when we deliver any signal. */ - error_t err; - mach_port_t proc; - struct hurd_userlink ulink; - - inline void kill_pid (pid_t pid) /* Kill one PID. */ - { - err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport), - (refport = arg_refport, 0), 0, - /* If no message port we cannot send signals. */ - msgport == MACH_PORT_NULL ? EPERM : - __msg_sig_post (msgport, sig, 0, refport)); - if (! err) - delivered = 1; - } - - proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink); - - if (pid <= 0) - { - /* Send SIG to each process in pgrp (- PID). */ - mach_msg_type_number_t npids = 10, i; - pid_t pidsbuf[10], *pids = pidsbuf; - - err = __proc_getpgrppids (proc, - pid, &pids, &npids); - if (!err) - { - int self = 0; - for (i = 0; i < npids; ++i) - if (pids[i] == _hurd_pid) - /* We must do ourselves last so we are not suspended - and fail to suspend the other processes in the pgrp. */ - self = 1; - else - { - kill_pid (pids[i]); - if (err == ESRCH) - /* The process died already. Ignore it. */ - err = 0; - } - if (pids != pidsbuf) - __vm_deallocate (__mach_task_self (), - (vm_address_t) pids, npids * sizeof (pids[0])); - - if (self) - kill_pid (_hurd_pid); - } - } - else - kill_pid (pid); - - _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc); - - /* If we delivered no signals, but ERR is clear, this must mean that - every kill_pid call failed with ESRCH, meaning all the processes in - the pgrp died between proc_getpgrppids and kill_pid; in that case we - fail with ESRCH. */ - return delivered ? 0 : err ?: ESRCH; -} -weak_alias (_hurd_sig_post, hurd_sig_post) diff --git a/hurd/hurdlookup.c b/hurd/hurdlookup.c deleted file mode 100644 index 84cb3d3015..0000000000 --- a/hurd/hurdlookup.c +++ /dev/null @@ -1,281 +0,0 @@ -/* Copyright (C) 1992-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/>. */ - -#include <hurd.h> -#include <hurd/lookup.h> -#include <string.h> -#include <fcntl.h> - - -/* Translate the error from dir_lookup into the error the user sees. */ -static inline error_t -lookup_error (error_t error) -{ - switch (error) - { - case EOPNOTSUPP: - case MIG_BAD_ID: - /* These indicate that the server does not understand dir_lookup - at all. If it were a directory, it would, by definition. */ - return ENOTDIR; - default: - return error; - } -} - -error_t -__hurd_file_name_lookup (error_t (*use_init_port) - (int which, error_t (*operate) (file_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 err; - enum retry_type doretry; - char retryname[1024]; /* XXX string_t LOSES! */ - int startport; - - error_t lookup_op (mach_port_t startdir) - { - return lookup_error ((*lookup) (startdir, file_name, flags, mode, - &doretry, retryname, result)); - } - - if (! lookup) - lookup = __dir_lookup; - - if (file_name[0] == '\0') - return ENOENT; - - startport = (file_name[0] == '/') ? INIT_PORT_CRDIR : INIT_PORT_CWDIR; - while (file_name[0] == '/') - file_name++; - - if (flags & O_NOFOLLOW) /* See lookup-retry.c about O_NOFOLLOW. */ - flags |= O_NOTRANS; - - if (flags & O_DIRECTORY) - { - /* The caller wants to require that the file we look up is a directory. - We can do this without an extra RPC by appending a trailing slash - to the file name we look up. */ - size_t len = strlen (file_name); - if (len == 0) - file_name = "/"; - else if (file_name[len - 1] != '/') - { - char *n = alloca (len + 2); - memcpy (n, file_name, len); - n[len] = '/'; - n[len + 1] = '\0'; - file_name = n; - } - } - - err = (*use_init_port) (startport, &lookup_op); - if (! err) - err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port, - lookup, doretry, retryname, - flags, mode, result); - - return err; -} -weak_alias (__hurd_file_name_lookup, hurd_file_name_lookup) - -error_t -__hurd_file_name_split (error_t (*use_init_port) - (int which, error_t (*operate) (file_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 addref (file_t crdir) - { - *dir = crdir; - return __mach_port_mod_refs (__mach_task_self (), - crdir, MACH_PORT_RIGHT_SEND, +1); - } - - const char *lastslash = strrchr (file_name, '/'); - - if (lastslash != NULL) - { - if (lastslash == file_name) - { - /* "/foobar" => crdir + "foobar". */ - *name = (char *) file_name + 1; - return (*use_init_port) (INIT_PORT_CRDIR, &addref); - } - else - { - /* "/dir1/dir2/.../file". */ - char dirname[lastslash - file_name + 1]; - memcpy (dirname, file_name, lastslash - file_name); - dirname[lastslash - file_name] = '\0'; - *name = (char *) lastslash + 1; - return - __hurd_file_name_lookup (use_init_port, get_dtable_port, lookup, - dirname, 0, 0, dir); - } - } - else if (file_name[0] == '\0') - return ENOENT; - else - { - /* "foobar" => cwdir + "foobar". */ - *name = (char *) file_name; - return (*use_init_port) (INIT_PORT_CWDIR, &addref); - } -} -weak_alias (__hurd_file_name_split, hurd_file_name_split) - -/* This is the same as hurd_file_name_split, except that it ignores - trailing slashes (so *NAME is never ""). */ -error_t -__hurd_directory_name_split (error_t (*use_init_port) - (int which, error_t (*operate) (file_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 addref (file_t crdir) - { - *dir = crdir; - return __mach_port_mod_refs (__mach_task_self (), - crdir, MACH_PORT_RIGHT_SEND, +1); - } - - const char *lastslash = strrchr (file_name, '/'); - - if (lastslash != NULL && lastslash[1] == '\0') - { - /* Trailing slash doesn't count. Look back further. */ - - /* Back up over all trailing slashes. */ - while (lastslash > file_name && *lastslash == '/') - --lastslash; - - /* Find the last one earlier in the string, before the trailing ones. */ - lastslash = __memrchr (file_name, '/', lastslash - file_name); - } - - if (lastslash != NULL) - { - if (lastslash == file_name) - { - /* "/foobar" => crdir + "foobar". */ - *name = (char *) file_name + 1; - return (*use_init_port) (INIT_PORT_CRDIR, &addref); - } - else - { - /* "/dir1/dir2/.../file". */ - char dirname[lastslash - file_name + 1]; - memcpy (dirname, file_name, lastslash - file_name); - dirname[lastslash - file_name] = '\0'; - *name = (char *) lastslash + 1; - return - __hurd_file_name_lookup (use_init_port, get_dtable_port, lookup, - dirname, 0, 0, dir); - } - } - else if (file_name[0] == '\0') - return ENOENT; - else - { - /* "foobar" => cwdir + "foobar". */ - *name = (char *) file_name; - return (*use_init_port) (INIT_PORT_CWDIR, &addref); - } -} -weak_alias (__hurd_directory_name_split, hurd_directory_name_split) - - -file_t -__file_name_lookup (const char *file_name, int flags, mode_t mode) -{ - error_t err; - file_t result; - - err = __hurd_file_name_lookup (&_hurd_ports_use, &__getdport, 0, - file_name, flags, mode & ~_hurd_umask, - &result); - - return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; -} -weak_alias (__file_name_lookup, file_name_lookup) - - -file_t -__file_name_split (const char *file_name, char **name) -{ - error_t err; - file_t result; - - err = __hurd_file_name_split (&_hurd_ports_use, &__getdport, 0, - file_name, &result, name); - - return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; -} -weak_alias (__file_name_split, file_name_split) - -file_t -__directory_name_split (const char *directory_name, char **name) -{ - error_t err; - file_t result; - - err = __hurd_directory_name_split (&_hurd_ports_use, &__getdport, 0, - directory_name, &result, name); - - return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; -} -weak_alias (__directory_name_split, directory_name_split) - - -file_t -__file_name_lookup_under (file_t startdir, - const char *file_name, int flags, mode_t mode) -{ - error_t err; - file_t result; - - error_t use_init_port (int which, error_t (*operate) (mach_port_t)) - { - return (which == INIT_PORT_CWDIR ? (*operate) (startdir) : - _hurd_ports_use (which, operate)); - } - - err = __hurd_file_name_lookup (&use_init_port, &__getdport, 0, - file_name, flags, mode & ~_hurd_umask, - &result); - - return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; -} -weak_alias (__file_name_lookup_under, file_name_lookup_under) diff --git a/hurd/hurdmalloc.c b/hurd/hurdmalloc.c deleted file mode 100644 index 65fb959d84..0000000000 --- a/hurd/hurdmalloc.c +++ /dev/null @@ -1,449 +0,0 @@ -#include <stdlib.h> -#include <string.h> - -#include "hurdmalloc.h" /* XXX see that file */ - -#include <mach.h> -#define vm_allocate __vm_allocate -#define vm_page_size __vm_page_size - -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * (pre-GNU) HISTORY - * - * Revision 2.7 91/05/14 17:57:34 mrt - * Correcting copyright - * - * Revision 2.6 91/02/14 14:20:26 mrt - * Added new Mach copyright - * [91/02/13 12:41:21 mrt] - * - * Revision 2.5 90/11/05 14:37:33 rpd - * Added malloc_fork* code. - * [90/11/02 rwd] - * - * Add spin_lock_t. - * [90/10/31 rwd] - * - * Revision 2.4 90/08/07 14:31:28 rpd - * Removed RCS keyword nonsense. - * - * Revision 2.3 90/06/02 15:14:00 rpd - * Converted to new IPC. - * [90/03/20 20:56:57 rpd] - * - * Revision 2.2 89/12/08 19:53:59 rwd - * Removed conditionals. - * [89/10/23 rwd] - * - * Revision 2.1 89/08/03 17:09:46 rwd - * Created. - * - * - * 13-Sep-88 Eric Cooper (ecc) at Carnegie Mellon University - * Changed realloc() to copy min(old size, new size) bytes. - * Bug found by Mike Kupfer at Olivetti. - */ -/* - * File: malloc.c - * Author: Eric Cooper, Carnegie Mellon University - * Date: July, 1988 - * - * Memory allocator for use with multiple threads. - */ - - -#include <assert.h> - -#include <cthreads.h> - -#define MCHECK - -/* - * Structure of memory block header. - * When free, next points to next block on free list. - * When allocated, fl points to free list. - * Size of header is 4 bytes, so minimum usable block size is 8 bytes. - */ - -#define CHECK_BUSY 0x8a3c743e -#define CHECK_FREE 0x66688b92 - -#ifdef MCHECK - -typedef struct header { - long check; - union { - struct header *next; - struct free_list *fl; - } u; -} *header_t; - -#define HEADER_SIZE sizeof (struct header) -#define HEADER_NEXT(h) ((h)->u.next) -#define HEADER_FREE(h) ((h)->u.fl) -#define HEADER_CHECK(h) ((h)->check) -#define MIN_SIZE 16 -#define LOG2_MIN_SIZE 4 - -#else /* ! MCHECK */ - -typedef union header { - union header *next; - struct free_list *fl; -} *header_t; - -#define HEADER_SIZE sizeof (union header) -#define HEADER_NEXT(h) ((h)->next) -#define HEADER_FREE(h) ((h)->fl) -#define MIN_SIZE 8 /* minimum block size */ -#define LOG2_MIN_SIZE 3 - -#endif /* MCHECK */ - -typedef struct free_list { - spin_lock_t lock; /* spin lock for mutual exclusion */ - header_t head; /* head of free list for this size */ -#ifdef DEBUG - int in_use; /* # mallocs - # frees */ -#endif /* DEBUG */ -} *free_list_t; - -/* - * Free list with index i contains blocks of size 2 ^ (i + LOG2_MIN_SIZE) - * including header. Smallest block size is MIN_SIZE, with MIN_SIZE - - * HEADER_SIZE bytes available to user. Size argument to malloc is a signed - * integer for sanity checking, so largest block size is 2^31. - */ -#define NBUCKETS 29 - -static struct free_list malloc_free_list[NBUCKETS]; - -/* Initialization just sets everything to zero, but might be necessary on a - machine where spin_lock_init does otherwise, and is necessary when - running an executable that was written by something like Emacs's unexec. - It preserves the values of data variables like malloc_free_list, but - does not save the vm_allocate'd space allocated by this malloc. */ - -static void -malloc_init (void) -{ - int i; - for (i = 0; i < NBUCKETS; ++i) - { - spin_lock_init (&malloc_free_list[i].lock); - malloc_free_list[i].head = NULL; -#ifdef DEBUG - malloc_free_list[i].in_use = 0; -#endif - } - - /* This not only suppresses a `defined but not used' warning, - but it is ABSOLUTELY NECESSARY to avoid the hyperclever - compiler from "optimizing out" the entire function! */ - (void) &malloc_init; -} - -static void -more_memory(int size, free_list_t fl) -{ - int amount; - int n; - vm_address_t where; - header_t h; - kern_return_t r; - - if (size <= vm_page_size) { - amount = vm_page_size; - n = vm_page_size / size; - /* We lose vm_page_size - n*size bytes here. */ - } else { - amount = size; - n = 1; - } - - r = vm_allocate(mach_task_self(), &where, (vm_size_t) amount, TRUE); - assert_perror (r); - - h = (header_t) where; - do { - HEADER_NEXT (h) = fl->head; -#ifdef MCHECK - HEADER_CHECK (h) = CHECK_FREE; -#endif - fl->head = h; - h = (header_t) ((char *) h + size); - } while (--n != 0); -} - -/* Declaration changed to standard one for GNU. */ -void * -malloc (size_t size) -{ - int i, n; - free_list_t fl; - header_t h; - - if ((int) size < 0) /* sanity check */ - return 0; - size += HEADER_SIZE; - /* - * Find smallest power-of-two block size - * big enough to hold requested size plus header. - */ - i = 0; - n = MIN_SIZE; - while (n < size) { - i += 1; - n <<= 1; - } - ASSERT(i < NBUCKETS); - fl = &malloc_free_list[i]; - spin_lock(&fl->lock); - h = fl->head; - if (h == 0) { - /* - * Free list is empty; - * allocate more blocks. - */ - more_memory(n, fl); - h = fl->head; - if (h == 0) { - /* - * Allocation failed. - */ - spin_unlock(&fl->lock); - return 0; - } - } - /* - * Pop block from free list. - */ - fl->head = HEADER_NEXT (h); - -#ifdef MCHECK - assert (HEADER_CHECK (h) == CHECK_FREE); - HEADER_CHECK (h) = CHECK_BUSY; -#endif - -#ifdef DEBUG - fl->in_use += 1; -#endif /* DEBUG */ - spin_unlock(&fl->lock); - /* - * Store free list pointer in block header - * so we can figure out where it goes - * at free() time. - */ - HEADER_FREE (h) = fl; - /* - * Return pointer past the block header. - */ - return ((char *) h) + HEADER_SIZE; -} - -/* Declaration changed to standard one for GNU. */ -void -free (void *base) -{ - header_t h; - free_list_t fl; - int i; - - if (base == 0) - return; - /* - * Find free list for block. - */ - h = (header_t) (base - HEADER_SIZE); - -#ifdef MCHECK - assert (HEADER_CHECK (h) == CHECK_BUSY); -#endif - - fl = HEADER_FREE (h); - i = fl - malloc_free_list; - /* - * Sanity checks. - */ - if (i < 0 || i >= NBUCKETS) { - ASSERT(0 <= i && i < NBUCKETS); - return; - } - if (fl != &malloc_free_list[i]) { - ASSERT(fl == &malloc_free_list[i]); - return; - } - /* - * Push block on free list. - */ - spin_lock(&fl->lock); - HEADER_NEXT (h) = fl->head; -#ifdef MCHECK - HEADER_CHECK (h) = CHECK_FREE; -#endif - fl->head = h; -#ifdef DEBUG - fl->in_use -= 1; -#endif /* DEBUG */ - spin_unlock(&fl->lock); - return; -} - -/* Declaration changed to standard one for GNU. */ -void * -realloc (void *old_base, size_t new_size) -{ - header_t h; - free_list_t fl; - int i; - unsigned int old_size; - char *new_base; - - if (old_base == 0) - return malloc (new_size); - - /* - * Find size of old block. - */ - h = (header_t) (old_base - HEADER_SIZE); -#ifdef MCHECK - assert (HEADER_CHECK (h) == CHECK_BUSY); -#endif - fl = HEADER_FREE (h); - i = fl - malloc_free_list; - /* - * Sanity checks. - */ - if (i < 0 || i >= NBUCKETS) { - ASSERT(0 <= i && i < NBUCKETS); - return 0; - } - if (fl != &malloc_free_list[i]) { - ASSERT(fl == &malloc_free_list[i]); - return 0; - } - /* - * Free list with index i contains blocks of size - * 2 ^ (i + * LOG2_MIN_SIZE) including header. - */ - old_size = (1 << (i + LOG2_MIN_SIZE)) - HEADER_SIZE; - - if (new_size <= old_size - && new_size > (((old_size + HEADER_SIZE) >> 1) - HEADER_SIZE)) - /* The new size still fits in the same block, and wouldn't fit in - the next smaller block! */ - return old_base; - - /* - * Allocate new block, copy old bytes, and free old block. - */ - new_base = malloc(new_size); - if (new_base) - memcpy (new_base, old_base, - (int) (old_size < new_size ? old_size : new_size)); - - if (new_base || new_size == 0) - /* Free OLD_BASE, but only if the malloc didn't fail. */ - free (old_base); - - return new_base; -} - -#ifdef DEBUG -void -print_malloc_free_list (void) -{ - int i, size; - free_list_t fl; - int n; - header_t h; - int total_used = 0; - int total_free = 0; - - fprintf(stderr, " Size In Use Free Total\n"); - for (i = 0, size = MIN_SIZE, fl = malloc_free_list; - i < NBUCKETS; - i += 1, size <<= 1, fl += 1) { - spin_lock(&fl->lock); - if (fl->in_use != 0 || fl->head != 0) { - total_used += fl->in_use * size; - for (n = 0, h = fl->head; h != 0; h = HEADER_NEXT (h), n += 1) - ; - total_free += n * size; - fprintf(stderr, "%10d %10d %10d %10d\n", - size, fl->in_use, n, fl->in_use + n); - } - spin_unlock(&fl->lock); - } - fprintf(stderr, " all sizes %10d %10d %10d\n", - total_used, total_free, total_used + total_free); -} -#endif /* DEBUG */ - -void -_hurd_malloc_fork_prepare(void) -/* - * Prepare the malloc module for a fork by insuring that no thread is in a - * malloc critical section. - */ -{ - int i; - - for (i = 0; i < NBUCKETS; i++) { - spin_lock(&malloc_free_list[i].lock); - } -} - -void -_hurd_malloc_fork_parent(void) -/* - * Called in the parent process after a fork() to resume normal operation. - */ -{ - int i; - - for (i = NBUCKETS-1; i >= 0; i--) { - spin_unlock(&malloc_free_list[i].lock); - } -} - -void -_hurd_malloc_fork_child(void) -/* - * Called in the child process after a fork() to resume normal operation. - */ -{ - int i; - - for (i = NBUCKETS-1; i >= 0; i--) { - spin_unlock(&malloc_free_list[i].lock); - } -} - - -text_set_element (_hurd_preinit_hook, malloc_init); diff --git a/hurd/hurdmalloc.h b/hurd/hurdmalloc.h deleted file mode 100644 index 3520ffacd8..0000000000 --- a/hurd/hurdmalloc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* XXX this file is a temporary hack. - - All hurd-internal code which uses malloc et al includes this file so it - will use the internal malloc routines _hurd_{malloc,realloc,free} - instead. The "hurd-internal" functions are the cthreads version, - which uses vm_allocate and is thread-safe. The normal user version - of malloc et al is the unixoid one using sbrk. - - */ - -extern void *_hurd_malloc (size_t); -extern void *_hurd_realloc (void *, size_t); -extern void _hurd_free (void *); - -extern void _hurd_malloc_fork_prepare (void); -extern void _hurd_malloc_fork_parent (void); -extern void _hurd_malloc_fork_child (void); - -#define malloc _hurd_malloc -#define realloc _hurd_realloc -#define free _hurd_free diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c deleted file mode 100644 index 4249ba104a..0000000000 --- a/hurd/hurdmsg.c +++ /dev/null @@ -1,419 +0,0 @@ -/* Copyright (C) 1992-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/>. */ - -#include <hurd.h> -#include <hurd/msg_server.h> -#include <hurd/fd.h> -#include <unistd.h> -#include <limits.h> -#include <string.h> -#include <argz.h> - - -#define AUTHCHECK \ - if (auth != mach_task_self () && ! __USEPORT (AUTH, port == auth)) \ - return EPERM - - -/* Snarfing and frobbing the init ports. */ - -kern_return_t - _S_msg_get_init_port (mach_port_t msgport, mach_port_t auth, int which, - mach_port_t *result, mach_msg_type_name_t *result_type) -{ - AUTHCHECK; - *result_type = MACH_MSG_TYPE_MOVE_SEND; - /* This function adds a new user reference for the *RESULT it gives back. - Our reply message uses a move-send right that consumes this reference. */ - return _hurd_ports_get (which, result); -} - -kern_return_t -_S_msg_set_init_port (mach_port_t msgport, mach_port_t auth, - int which, mach_port_t port) -{ - error_t err; - - AUTHCHECK; - - err = _hurd_ports_set (which, port); - if (err == 0) - __mach_port_deallocate (__mach_task_self (), port); - - return 0; -} - -kern_return_t -_S_msg_get_init_ports (mach_port_t msgport, mach_port_t auth, - mach_port_t **ports, - mach_msg_type_name_t *ports_type, - mach_msg_type_number_t *nports) -{ - mach_msg_type_number_t i; - error_t err; - - AUTHCHECK; - - if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) ports, - _hurd_nports * sizeof (mach_port_t), 1)) - return err; - *nports = _hurd_nports; - - for (i = 0; i < _hurd_nports; ++i) - /* This function adds a new user ref for the *RESULT it gives back. - Our reply message uses move-send rights that consumes this ref. */ - if (err = _hurd_ports_get (i, &(*ports)[i])) - { - /* Died part way through. Deallocate the ports already fetched. */ - while (i-- > 0) - __mach_port_deallocate (__mach_task_self (), (*ports)[i]); - __vm_deallocate (__mach_task_self (), - (vm_address_t) *ports, - *nports * sizeof (mach_port_t)); - return err; - } - - *ports_type = MACH_MSG_TYPE_MOVE_SEND; - return 0; -} - -kern_return_t -_S_msg_set_init_ports (mach_port_t msgport, mach_port_t auth, - mach_port_t *ports, mach_msg_type_number_t nports) -{ - mach_msg_type_number_t i; - error_t err; - - AUTHCHECK; - - for (i = 0; i < _hurd_nports; ++i) - { - if (err = _hurd_ports_set (i, ports[i])) - return err; - else - __mach_port_deallocate (__mach_task_self (), ports[i]); - } - - return 0; -} - -/* Snarfing and frobbing the init ints. */ - -static kern_return_t -get_int (int which, int *value) -{ - switch (which) - { - case INIT_UMASK: - *value = _hurd_umask; - return 0; - case INIT_SIGMASK: - { - struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); - __spin_lock (&ss->lock); - *value = ss->blocked; - __spin_unlock (&ss->lock); - return 0; - } - case INIT_SIGPENDING: - { - struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); - __spin_lock (&ss->lock); - *value = ss->pending; - __spin_unlock (&ss->lock); - return 0; - } - case INIT_SIGIGN: - { - struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); - sigset_t ign; - int sig; - __spin_lock (&ss->lock); - __sigemptyset (&ign); - for (sig = 1; sig < NSIG; ++sig) - if (ss->actions[sig].sa_handler == SIG_IGN) - __sigaddset (&ign, sig); - __spin_unlock (&ss->lock); - *value = ign; - return 0; - } - default: - return EINVAL; - } -} - -kern_return_t -_S_msg_get_init_int (mach_port_t msgport, mach_port_t auth, - int which, int *value) -{ - AUTHCHECK; - - return get_int (which, value); -} - -kern_return_t -_S_msg_get_init_ints (mach_port_t msgport, mach_port_t auth, - int **values, mach_msg_type_number_t *nvalues) -{ - error_t err; - mach_msg_type_number_t i; - - AUTHCHECK; - - if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) values, - INIT_INT_MAX * sizeof (int), 1)) - return err; - *nvalues = INIT_INT_MAX; - - for (i = 0; i < INIT_INT_MAX; ++i) - switch (err = get_int (i, &(*values)[i])) - { - case 0: /* Success. */ - break; - case EINVAL: /* Unknown index. */ - (*values)[i] = 0; - break; - default: /* Lossage. */ - __vm_deallocate (__mach_task_self (), - (vm_address_t) *values, INIT_INT_MAX * sizeof (int)); - return err; - } - - return 0; -} - - -static kern_return_t -set_int (int which, int value) -{ - switch (which) - { - case INIT_UMASK: - _hurd_umask = value; - return 0; - - /* These are pretty odd things to do. But you asked for it. */ - case INIT_SIGMASK: - { - struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); - __spin_lock (&ss->lock); - ss->blocked = value; - __spin_unlock (&ss->lock); - return 0; - } - case INIT_SIGPENDING: - { - struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); - __spin_lock (&ss->lock); - ss->pending = value; - __spin_unlock (&ss->lock); - return 0; - } - case INIT_SIGIGN: - { - struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread); - int sig; - const sigset_t ign = value; - __spin_lock (&ss->lock); - for (sig = 1; sig < NSIG; ++sig) - { - if (__sigismember (&ign, sig)) - ss->actions[sig].sa_handler = SIG_IGN; - else if (ss->actions[sig].sa_handler == SIG_IGN) - ss->actions[sig].sa_handler = SIG_DFL; - } - __spin_unlock (&ss->lock); - return 0; - - case INIT_TRACEMASK: - _hurdsig_traced = value; - return 0; - } - default: - return EINVAL; - } -} - -kern_return_t -_S_msg_set_init_int (mach_port_t msgport, mach_port_t auth, - int which, int value) -{ - AUTHCHECK; - - return set_int (which, value); -} - -kern_return_t -_S_msg_set_init_ints (mach_port_t msgport, mach_port_t auth, - int *values, mach_msg_type_number_t nvalues) -{ - error_t err; - mach_msg_type_number_t i; - - AUTHCHECK; - - for (i = 0; i < INIT_INT_MAX; ++i) - switch (err = set_int (i, values[i])) - { - case 0: /* Success. */ - break; - case EINVAL: /* Unknown index. */ - break; - default: /* Lossage. */ - return err; - } - - return 0; -} - - -kern_return_t -_S_msg_get_fd (mach_port_t msgport, mach_port_t auth, int which, - mach_port_t *result, mach_msg_type_name_t *result_type) -{ - AUTHCHECK; - - /* This creates a new user reference for the send right. - Our reply message will move that reference to the caller. */ - *result = __getdport (which); - if (*result == MACH_PORT_NULL) - return errno; - *result_type = MACH_MSG_TYPE_MOVE_SEND; - - return 0; -} - -kern_return_t -_S_msg_set_fd (mach_port_t msgport, mach_port_t auth, - int which, mach_port_t port) -{ - AUTHCHECK; - - /* We consume the reference if successful. */ - return HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0)); -} - -/* Snarfing and frobbing environment variables. */ - -kern_return_t -_S_msg_get_env_variable (mach_port_t msgport, - char *variable, - char **data, mach_msg_type_number_t *datalen) -{ - error_t err; - mach_msg_type_number_t valuelen; - const char *value = getenv (variable); - - if (value == NULL) - return ENOENT; - - valuelen = strlen (value); - if (valuelen > *datalen) - { - if (err = __vm_allocate (__mach_task_self (), - (vm_address_t *) data, valuelen, 1)) - return err; - } - - memcpy (*data, value, valuelen); - *datalen = valuelen; - - return 0; -} - - -kern_return_t -_S_msg_set_env_variable (mach_port_t msgport, mach_port_t auth, - char *variable, - char *value, - int replace) -{ - AUTHCHECK; - - if (setenv (variable, value, replace)) /* XXX name space */ - return errno; - return 0; -} - -kern_return_t -_S_msg_get_environment (mach_port_t msgport, - char **data, mach_msg_type_number_t *datalen) -{ - /* Pack the environment into an array with nulls separating elements. */ - if (__environ != NULL) - { - char *ap, **p; - size_t envlen = 0; - - for (p = __environ; *p != NULL; ++p) - envlen += strlen (*p) + 1; - - if (envlen > *datalen) - { - if (__vm_allocate (__mach_task_self (), - (vm_address_t *) data, envlen, 1)) - return ENOMEM; - } - - ap = *data; - for (p = __environ; *p != NULL; ++p) - ap = __memccpy (ap, *p, '\0', ULONG_MAX); - - *datalen = envlen; - } - else - *datalen = 0; - - return 0; -} - -kern_return_t -_S_msg_set_environment (mach_port_t msgport, mach_port_t auth, - char *data, mach_msg_type_number_t datalen) -{ - int _hurd_split_args (char *, mach_msg_type_number_t, char **); - int envc; - char **envp; - - AUTHCHECK; - - envc = __argz_count (data, datalen); - envp = malloc ((envc + 1) * sizeof (char *)); - if (envp == NULL) - return errno; - __argz_extract (data, datalen, envp); - __environ = envp; /* XXX cooperate with loadenv et al */ - return 0; -} - - -/* XXX */ - -kern_return_t -_S_msg_get_dtable (mach_port_t process, - mach_port_t refport, - portarray_t *dtable, - mach_msg_type_name_t *dtablePoly, - mach_msg_type_number_t *dtableCnt) -{ return EOPNOTSUPP; } - -kern_return_t -_S_msg_set_dtable (mach_port_t process, - mach_port_t refport, - portarray_t dtable, - mach_msg_type_number_t dtableCnt) -{ return EOPNOTSUPP; } diff --git a/hurd/hurdpid.c b/hurd/hurdpid.c deleted file mode 100644 index 114077d0cc..0000000000 --- a/hurd/hurdpid.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> -pid_t _hurd_pid, _hurd_ppid, _hurd_pgrp; -int _hurd_orphaned; - -static void -init_pids (void) -{ - __USEPORT (PROC, - ({ - __proc_getpids (port, &_hurd_pid, &_hurd_ppid, &_hurd_orphaned); - __proc_getpgrp (port, _hurd_pid, &_hurd_pgrp); - })); - - (void) &init_pids; /* Avoid "defined but not used" warning. */ -} - -text_set_element (_hurd_proc_subinit, init_pids); - -#include <hurd/msg_server.h> -#include "set-hooks.h" -#include <cthreads.h> - -DEFINE_HOOK (_hurd_pgrp_changed_hook, (pid_t)); - -/* These let user threads synchronize with an operation which changes ids. */ -unsigned int _hurd_pids_changed_stamp; -struct condition _hurd_pids_changed_sync; - -kern_return_t -_S_msg_proc_newids (mach_port_t me, - task_t task, - pid_t ppid, pid_t pgrp, int orphaned) -{ - int pgrp_changed; - - if (task != __mach_task_self ()) - return EPERM; - - __mach_port_deallocate (__mach_task_self (), task); - - pgrp_changed = pgrp != _hurd_pgrp; - _hurd_ppid = ppid; - _hurd_pgrp = pgrp; - _hurd_orphaned = orphaned; - - if (pgrp_changed) - /* Run things that want notification of a pgrp change. */ - RUN_HOOK (_hurd_pgrp_changed_hook, (pgrp)); - - /* Notify any waiting user threads that the id change as been completed. */ - ++_hurd_pids_changed_stamp; - - return 0; -} diff --git a/hurd/hurdports.c b/hurd/hurdports.c deleted file mode 100644 index 1cf918d944..0000000000 --- a/hurd/hurdports.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> -#include <hurd/port.h> - - -static inline mach_port_t -get (const int idx) -{ - mach_port_t result; - error_t err = _hurd_ports_get (idx, &result); - - if (err) - return __hurd_fail (err), MACH_PORT_NULL; - return result; -} -#define GET(type, what, idx) \ - type get##what (void) { return get (INIT_PORT_##idx); } - -static inline int -set (const int idx, mach_port_t new) -{ - error_t err = _hurd_ports_set (idx, new); - return err ? __hurd_fail (err) : 0; -} -#define SET(type, what, idx) \ - int set##what (type new) { return set (INIT_PORT_##idx, new); } - -#define GETSET(type, what, idx) \ - GET (type, what, idx) SET (type, what, idx) - -GETSET (process_t, proc, PROC) -GETSET (mach_port_t, cttyid, CTTYID) -GETSET (file_t, cwdir, CWDIR) -GETSET (file_t, crdir, CRDIR) -GETSET (auth_t, auth, AUTH) diff --git a/hurd/hurdprio.c b/hurd/hurdprio.c deleted file mode 100644 index 5ea46b633c..0000000000 --- a/hurd/hurdprio.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Support code for dealing with priorities in 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/>. */ - -#include <hurd.h> -#include <hurd/resource.h> -#include <sys/mman.h> -#include <unistd.h> - -error_t -_hurd_priority_which_map (enum __priority_which which, int who, - error_t (*function) (pid_t, struct procinfo *), - int pi_flags) -{ - mach_msg_type_number_t npids = 64, i; - pid_t pidbuf[npids], *pids = pidbuf; - error_t err; - struct procinfo *pip; - int pibuf[sizeof *pip + 5 * sizeof (pip->threadinfos[0])], *pi = pibuf; - mach_msg_type_number_t pisize = sizeof (pibuf) / sizeof (int); - - switch (which) - { - default: - return EINVAL; - - case PRIO_PROCESS: - err = (*function) (who ?: getpid (), 0); /* XXX special-case self? */ - break; - - case PRIO_PGRP: - err = __USEPORT (PROC, __proc_getpgrppids (port, who, &pids, &npids)); - for (i = 0; !err && i < npids; ++i) - err = (*function) (pids[i], 0); - break; - - case PRIO_USER: - if (who == 0) - who = geteuid (); - err = __USEPORT (PROC, __proc_getallpids (port, &pids, &npids)); - for (i = 0; !err && i < npids; ++i) - { - /* Get procinfo to check the owner. */ - int *oldpi = pi; - mach_msg_type_number_t oldpisize = pisize; - char *tw = 0; - size_t twsz = 0; - err = __USEPORT (PROC, __proc_getprocinfo (port, pids[i], - &pi_flags, - &pi, &pisize, - &tw, &twsz)); - if (!err) - { - if (twsz) /* Gratuitous. */ - __munmap (tw, twsz); - if (pi != oldpi && oldpi != pibuf) - /* Old buffer from last call was not reused; free it. */ - __munmap (oldpi, oldpisize * sizeof pi[0]); - - pip = (struct procinfo *) pi; - if (pip->owner == (uid_t) who) - err = (*function) (pids[i], pip); - } - } - break; - } - - if (pids != pidbuf) - __munmap (pids, npids * sizeof pids[0]); - if (pi != pibuf) - __munmap (pi, pisize * sizeof pi[0]); - - return err; -} diff --git a/hurd/hurdrlimit.c b/hurd/hurdrlimit.c deleted file mode 100644 index 6efb8e51c6..0000000000 --- a/hurd/hurdrlimit.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Resource limits. - 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/>. */ - -#include <hurd.h> -#include <cthreads.h> -#include <hurd/resource.h> - -/* This must be given an initializer, or the a.out linking rules will - not include the entire file when this symbol is referenced. */ -struct rlimit _hurd_rlimits[RLIM_NLIMITS] = { { 0, }, }; - -/* This must be initialized data for the same reason as above, but this is - intentionally initialized to a bogus value to emphasize the point that - mutex_init is still required below just in case of unexec. */ -struct mutex _hurd_rlimit_lock = { SPIN_LOCK_INITIALIZER, }; - -static void -init_rlimit (void) -{ - int i; - - __mutex_init (&_hurd_rlimit_lock); - - for (i = 0; i < RLIM_NLIMITS; ++i) - { - if (_hurd_rlimits[i].rlim_max == 0) - _hurd_rlimits[i].rlim_max = RLIM_INFINITY; - if (_hurd_rlimits[i].rlim_cur == 0) -#define I(lim, val) case RLIMIT_##lim: _hurd_rlimits[i].rlim_cur = (val); break - switch (i) - { - I (NOFILE, 1024); /* Linux 2.2.12 uses this initial value. */ - - default: - _hurd_rlimits[i].rlim_cur = _hurd_rlimits[i].rlim_max; - break; - } -#undef I - } - - (void) &init_rlimit; -} -text_set_element (_hurd_preinit_hook, init_rlimit); diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c deleted file mode 100644 index 8dc7c76995..0000000000 --- a/hurd/hurdselect.c +++ /dev/null @@ -1,491 +0,0 @@ -/* Guts of both `select' and `poll' for Hurd. - Copyright (C) 1991-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/>. */ - -#include <sys/types.h> -#include <sys/poll.h> -#include <hurd.h> -#include <hurd/fd.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <stdint.h> - -/* All user select types. */ -#define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG) - -/* Used to record that a particular select rpc returned. Must be distinct - from SELECT_ALL (which better not have the high bit set). */ -#define SELECT_RETURNED ((SELECT_ALL << 1) & ~SELECT_ALL) - -/* Check the first NFDS descriptors either in POLLFDS (if nonnnull) or in - each of READFDS, WRITEFDS, EXCEPTFDS that is nonnull. If TIMEOUT is not - NULL, time out after waiting the interval specified therein. Returns - the number of ready descriptors, or -1 for errors. */ -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) -{ - int i; - mach_port_t portset; - int got; - error_t err; - fd_set rfds, wfds, xfds; - int firstfd, lastfd; - mach_msg_timeout_t to = 0; - struct - { - struct hurd_userlink ulink; - struct hurd_fd *cell; - mach_port_t io_port; - int type; - mach_port_t reply_port; - } d[nfds]; - sigset_t oset; - - union typeword /* Use this to avoid unkosher casts. */ - { - mach_msg_type_t type; - uint32_t word; - }; - assert (sizeof (union typeword) == sizeof (mach_msg_type_t)); - assert (sizeof (uint32_t) == sizeof (mach_msg_type_t)); - - if (nfds < 0 || (pollfds == NULL && nfds > FD_SETSIZE)) - { - errno = EINVAL; - return -1; - } - - if (timeout != NULL) - { - if (timeout->tv_sec < 0 || timeout->tv_nsec < 0) - { - errno = EINVAL; - return -1; - } - - to = (timeout->tv_sec * 1000 + - (timeout->tv_nsec + 999999) / 1000000); - } - - if (sigmask && __sigprocmask (SIG_SETMASK, sigmask, &oset)) - return -1; - - if (pollfds) - { - /* Collect interesting descriptors from the user's `pollfd' array. - We do a first pass that reads the user's array before taking - any locks. The second pass then only touches our own stack, - and gets the port references. */ - - for (i = 0; i < nfds; ++i) - if (pollfds[i].fd >= 0) - { - int type = 0; - if (pollfds[i].events & POLLIN) - type |= SELECT_READ; - if (pollfds[i].events & POLLOUT) - type |= SELECT_WRITE; - if (pollfds[i].events & POLLPRI) - type |= SELECT_URG; - - d[i].io_port = pollfds[i].fd; - d[i].type = type; - } - else - d[i].type = 0; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_dtable_lock); - - for (i = 0; i < nfds; ++i) - if (d[i].type != 0) - { - const int fd = (int) d[i].io_port; - - if (fd < _hurd_dtablesize) - { - d[i].cell = _hurd_dtable[fd]; - d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink); - if (d[i].io_port != MACH_PORT_NULL) - continue; - } - - /* If one descriptor is bogus, we fail completely. */ - while (i-- > 0) - if (d[i].type != 0) - _hurd_port_free (&d[i].cell->port, - &d[i].ulink, d[i].io_port); - break; - } - - __mutex_unlock (&_hurd_dtable_lock); - HURD_CRITICAL_END; - - if (i < nfds) - { - if (sigmask) - __sigprocmask (SIG_SETMASK, &oset, NULL); - errno = EBADF; - return -1; - } - - lastfd = i - 1; - firstfd = i == 0 ? lastfd : 0; - } - else - { - /* Collect interested descriptors from the user's fd_set arguments. - Use local copies so we can't crash from user bogosity. */ - - if (readfds == NULL) - FD_ZERO (&rfds); - else - rfds = *readfds; - if (writefds == NULL) - FD_ZERO (&wfds); - else - wfds = *writefds; - if (exceptfds == NULL) - FD_ZERO (&xfds); - else - xfds = *exceptfds; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_dtable_lock); - - if (nfds > _hurd_dtablesize) - nfds = _hurd_dtablesize; - - /* Collect the ports for interesting FDs. */ - firstfd = lastfd = -1; - for (i = 0; i < nfds; ++i) - { - int type = 0; - if (readfds != NULL && FD_ISSET (i, &rfds)) - type |= SELECT_READ; - if (writefds != NULL && FD_ISSET (i, &wfds)) - type |= SELECT_WRITE; - if (exceptfds != NULL && FD_ISSET (i, &xfds)) - type |= SELECT_URG; - d[i].type = type; - if (type) - { - d[i].cell = _hurd_dtable[i]; - d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink); - if (d[i].io_port == MACH_PORT_NULL) - { - /* If one descriptor is bogus, we fail completely. */ - while (i-- > 0) - if (d[i].type != 0) - _hurd_port_free (&d[i].cell->port, &d[i].ulink, - d[i].io_port); - break; - } - lastfd = i; - if (firstfd == -1) - firstfd = i; - } - } - - __mutex_unlock (&_hurd_dtable_lock); - HURD_CRITICAL_END; - - if (i < nfds) - { - if (sigmask) - __sigprocmask (SIG_SETMASK, &oset, NULL); - errno = EBADF; - return -1; - } - } - - - err = 0; - got = 0; - - /* Send them all io_select request messages. */ - - if (firstfd == -1) - /* But not if there were no ports to deal with at all. - We are just a pure timeout. */ - portset = __mach_reply_port (); - else - { - portset = MACH_PORT_NULL; - - for (i = firstfd; i <= lastfd; ++i) - if (d[i].type) - { - int type = d[i].type; - d[i].reply_port = __mach_reply_port (); - err = __io_select (d[i].io_port, d[i].reply_port, - /* Poll only if there's a single descriptor. */ - (firstfd == lastfd) ? to : 0, - &type); - switch (err) - { - case MACH_RCV_TIMED_OUT: - /* No immediate response. This is normal. */ - err = 0; - if (firstfd == lastfd) - /* When there's a single descriptor, we don't need a - portset, so just pretend we have one, but really - use the single reply port. */ - portset = d[i].reply_port; - else if (got == 0) - /* We've got multiple reply ports, so we need a port set to - multiplex them. */ - { - /* We will wait again for a reply later. */ - if (portset == MACH_PORT_NULL) - /* Create the portset to receive all the replies on. */ - err = __mach_port_allocate (__mach_task_self (), - MACH_PORT_RIGHT_PORT_SET, - &portset); - if (! err) - /* Put this reply port in the port set. */ - __mach_port_move_member (__mach_task_self (), - d[i].reply_port, portset); - } - break; - - default: - /* No other error should happen. Callers of select - don't expect to see errors, so we simulate - readiness of the erring object and the next call - hopefully will get the error again. */ - type = SELECT_ALL; - /* FALLTHROUGH */ - - case 0: - /* We got an answer. */ - if ((type & SELECT_ALL) == 0) - /* Bogus answer; treat like an error, as a fake positive. */ - type = SELECT_ALL; - - /* This port is already ready already. */ - d[i].type &= type; - d[i].type |= SELECT_RETURNED; - ++got; - break; - } - _hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port); - } - } - - /* Now wait for reply messages. */ - if (!err && got == 0) - { - /* Now wait for io_select_reply messages on PORT, - timing out as appropriate. */ - - union - { - mach_msg_header_t head; -#ifdef MACH_MSG_TRAILER_MINIMUM_SIZE - struct - { - mach_msg_header_t head; - NDR_record_t ndr; - error_t err; - } error; - struct - { - mach_msg_header_t head; - NDR_record_t ndr; - error_t err; - int result; - mach_msg_trailer_t trailer; - } success; -#else - struct - { - mach_msg_header_t head; - union typeword err_type; - error_t err; - } error; - struct - { - mach_msg_header_t head; - union typeword err_type; - error_t err; - union typeword result_type; - int result; - } success; -#endif - } msg; - mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT); - error_t msgerr; - while ((msgerr = __mach_msg (&msg.head, - MACH_RCV_MSG | MACH_RCV_INTERRUPT | options, - 0, sizeof msg, portset, to, - MACH_PORT_NULL)) == MACH_MSG_SUCCESS) - { - /* We got a message. Decode it. */ -#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */ -#ifdef MACH_MSG_TYPE_BIT - const union typeword inttype = - { type: - { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 } - }; -#endif - if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID && - msg.head.msgh_size >= sizeof msg.error && - !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX) && -#ifdef MACH_MSG_TYPE_BIT - msg.error.err_type.word == inttype.word -#endif - ) - { - /* This is a properly formatted message so far. - See if it is a success or a failure. */ - if (msg.error.err == EINTR && - msg.head.msgh_size == sizeof msg.error) - { - /* EINTR response; poll for further responses - and then return quickly. */ - err = EINTR; - goto poll; - } - if (msg.error.err || - msg.head.msgh_size != sizeof msg.success || -#ifdef MACH_MSG_TYPE_BIT - msg.success.result_type.word != inttype.word || -#endif - (msg.success.result & SELECT_ALL) == 0) - { - /* Error or bogus reply. Simulate readiness. */ - __mach_msg_destroy (&msg.head); - msg.success.result = SELECT_ALL; - } - - /* Look up the respondent's reply port and record its - readiness. */ - { - int had = got; - if (firstfd != -1) - for (i = firstfd; i <= lastfd; ++i) - if (d[i].type - && d[i].reply_port == msg.head.msgh_local_port) - { - d[i].type &= msg.success.result; - d[i].type |= SELECT_RETURNED; - ++got; - } - assert (got > had); - } - } - - if (msg.head.msgh_remote_port != MACH_PORT_NULL) - __mach_port_deallocate (__mach_task_self (), - msg.head.msgh_remote_port); - - if (got) - poll: - { - /* Poll for another message. */ - to = 0; - options |= MACH_RCV_TIMEOUT; - } - } - - if (msgerr == MACH_RCV_INTERRUPTED) - /* Interruption on our side (e.g. signal reception). */ - err = EINTR; - - if (got) - /* At least one descriptor is known to be ready now, so we will - return success. */ - err = 0; - } - - if (firstfd != -1) - for (i = firstfd; i <= lastfd; ++i) - if (d[i].type) - __mach_port_destroy (__mach_task_self (), d[i].reply_port); - if (firstfd == -1 || (firstfd != lastfd && portset != MACH_PORT_NULL)) - /* Destroy PORTSET, but only if it's not actually the reply port for a - single descriptor (in which case it's destroyed in the previous loop; - not doing it here is just a bit more efficient). */ - __mach_port_destroy (__mach_task_self (), portset); - - if (err) - { - if (sigmask) - __sigprocmask (SIG_SETMASK, &oset, NULL); - return __hurd_fail (err); - } - - if (pollfds) - /* Fill in the `revents' members of the user's array. */ - for (i = 0; i < nfds; ++i) - { - int type = d[i].type; - int_fast16_t revents = 0; - - if (type & SELECT_RETURNED) - { - if (type & SELECT_READ) - revents |= POLLIN; - if (type & SELECT_WRITE) - revents |= POLLOUT; - if (type & SELECT_URG) - revents |= POLLPRI; - } - - pollfds[i].revents = revents; - } - else - { - /* Below we recalculate GOT to include an increment for each operation - allowed on each fd. */ - got = 0; - - /* Set the user bitarrays. We only ever have to clear bits, as all - desired ones are initially set. */ - if (firstfd != -1) - for (i = firstfd; i <= lastfd; ++i) - { - int type = d[i].type; - - if ((type & SELECT_RETURNED) == 0) - type = 0; - - if (type & SELECT_READ) - got++; - else if (readfds) - FD_CLR (i, readfds); - if (type & SELECT_WRITE) - got++; - else if (writefds) - FD_CLR (i, writefds); - if (type & SELECT_URG) - got++; - else if (exceptfds) - FD_CLR (i, exceptfds); - } - } - - if (sigmask && __sigprocmask (SIG_SETMASK, &oset, NULL)) - return -1; - - return got; -} diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c deleted file mode 100644 index ec6a6995e6..0000000000 --- a/hurd/hurdsig.c +++ /dev/null @@ -1,1405 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <cthreads.h> /* For `struct mutex'. */ -#include <mach.h> -#include <mach/thread_switch.h> - -#include <hurd.h> -#include <hurd/id.h> -#include <hurd/signal.h> - -#include "hurdfault.h" -#include "hurdmalloc.h" /* XXX */ -#include "../locale/localeinfo.h" - -const char *_hurdsig_getenv (const char *); - -struct mutex _hurd_siglock; -int _hurd_stopped; - -/* Port that receives signals and other miscellaneous messages. */ -mach_port_t _hurd_msgport; - -/* Thread listening on it. */ -thread_t _hurd_msgport_thread; - -/* Thread which receives task-global signals. */ -thread_t _hurd_sigthread; - -/* These are set up by _hurdsig_init. */ -unsigned long int __hurd_sigthread_stack_base; -unsigned long int __hurd_sigthread_stack_end; -unsigned long int *__hurd_sigthread_variables; - -/* Linked-list of per-thread signal state. */ -struct hurd_sigstate *_hurd_sigstates; - -/* Timeout for RPC's after interrupt_operation. */ -mach_msg_timeout_t _hurd_interrupted_rpc_timeout = 3000; - -static void -default_sigaction (struct sigaction actions[NSIG]) -{ - int signo; - - __sigemptyset (&actions[0].sa_mask); - actions[0].sa_flags = SA_RESTART; - actions[0].sa_handler = SIG_DFL; - - for (signo = 1; signo < NSIG; ++signo) - actions[signo] = actions[0]; -} - -struct hurd_sigstate * -_hurd_thread_sigstate (thread_t thread) -{ - struct hurd_sigstate *ss; - __mutex_lock (&_hurd_siglock); - for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) - if (ss->thread == thread) - break; - if (ss == NULL) - { - ss = malloc (sizeof (*ss)); - if (ss == NULL) - __libc_fatal ("hurd: Can't allocate thread sigstate\n"); - ss->thread = thread; - __spin_lock_init (&ss->lock); - - /* Initialize default state. */ - __sigemptyset (&ss->blocked); - __sigemptyset (&ss->pending); - memset (&ss->sigaltstack, 0, sizeof (ss->sigaltstack)); - ss->preemptors = NULL; - ss->suspended = MACH_PORT_NULL; - ss->intr_port = MACH_PORT_NULL; - ss->context = NULL; - - /* Initialize the sigaction vector from the default signal receiving - thread's state, and its from the system defaults. */ - if (thread == _hurd_sigthread) - default_sigaction (ss->actions); - else - { - struct hurd_sigstate *s; - for (s = _hurd_sigstates; s != NULL; s = s->next) - if (s->thread == _hurd_sigthread) - break; - if (s) - { - __spin_lock (&s->lock); - memcpy (ss->actions, s->actions, sizeof (s->actions)); - __spin_unlock (&s->lock); - } - else - default_sigaction (ss->actions); - } - - ss->next = _hurd_sigstates; - _hurd_sigstates = ss; - } - __mutex_unlock (&_hurd_siglock); - return ss; -} - -/* Signal delivery itself is on this page. */ - -#include <hurd/fd.h> -#include <hurd/crash.h> -#include <hurd/resource.h> -#include <hurd/paths.h> -#include <setjmp.h> -#include <fcntl.h> -#include <sys/wait.h> -#include <thread_state.h> -#include <hurd/msg_server.h> -#include <hurd/msg_reply.h> /* For __msg_sig_post_reply. */ -#include <hurd/interrupt.h> -#include <assert.h> -#include <unistd.h> - - -/* Call the crash dump server to mummify us before we die. - Returns nonzero if a core file was written. */ -static int -write_corefile (int signo, const struct hurd_signal_detail *detail) -{ - error_t err; - mach_port_t coreserver; - file_t file, coredir; - const char *name; - - /* Don't bother locking since we just read the one word. */ - rlim_t corelimit = _hurd_rlimits[RLIMIT_CORE].rlim_cur; - - if (corelimit == 0) - /* No core dumping, thank you very much. Note that this makes - `ulimit -c 0' prevent crash-suspension too, which is probably - what the user wanted. */ - return 0; - - /* XXX RLIMIT_CORE: - When we have a protocol to make the server return an error - for RLIMIT_FSIZE, then tell the corefile fs server the RLIMIT_CORE - value in place of the RLIMIT_FSIZE value. */ - - /* First get a port to the core dumping server. */ - coreserver = MACH_PORT_NULL; - name = _hurdsig_getenv ("CRASHSERVER"); - if (name != NULL) - coreserver = __file_name_lookup (name, 0, 0); - if (coreserver == MACH_PORT_NULL) - coreserver = __file_name_lookup (_SERVERS_CRASH, 0, 0); - if (coreserver == MACH_PORT_NULL) - return 0; - - /* Get a port to the directory where the new core file will reside. */ - file = MACH_PORT_NULL; - name = _hurdsig_getenv ("COREFILE"); - if (name == NULL) - name = "core"; - coredir = __file_name_split (name, (char **) &name); - if (coredir != MACH_PORT_NULL) - /* Create the new file, but don't link it into the directory yet. */ - __dir_mkfile (coredir, O_WRONLY|O_CREAT, - 0600 & ~_hurd_umask, /* XXX ? */ - &file); - - /* Call the core dumping server to write the core file. */ - err = __crash_dump_task (coreserver, - __mach_task_self (), - file, - signo, detail->code, detail->error, - detail->exc, detail->exc_code, detail->exc_subcode, - _hurd_ports[INIT_PORT_CTTYID].port, - MACH_MSG_TYPE_COPY_SEND); - __mach_port_deallocate (__mach_task_self (), coreserver); - - if (! err && file != MACH_PORT_NULL) - /* The core dump into FILE succeeded, so now link it into the - directory. */ - err = __dir_link (coredir, file, name, 1); - __mach_port_deallocate (__mach_task_self (), file); - __mach_port_deallocate (__mach_task_self (), coredir); - return !err && file != MACH_PORT_NULL; -} - - -/* The lowest-numbered thread state flavor value is 1, - so we use bit 0 in machine_thread_all_state.set to - record whether we have done thread_abort. */ -#define THREAD_ABORTED 1 - -/* SS->thread is suspended. Abort the thread and get its basic state. */ -static void -abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state, - void (*reply) (void)) -{ - if (!(state->set & THREAD_ABORTED)) - { - error_t err = __thread_abort (ss->thread); - assert_perror (err); - /* Clear all thread state flavor set bits, because thread_abort may - have changed the state. */ - state->set = THREAD_ABORTED; - } - - if (reply) - (*reply) (); - - machine_get_basic_state (ss->thread, state); -} - -/* Find the location of the MiG reply port cell in use by the thread whose - state is described by THREAD_STATE. If SIGTHREAD is nonzero, make sure - that this location can be set without faulting, or else return NULL. */ - -static mach_port_t * -interrupted_reply_port_location (struct machine_thread_all_state *thread_state, - int sigthread) -{ - mach_port_t *portloc = (mach_port_t *) __hurd_threadvar_location_from_sp - (_HURD_THREADVAR_MIG_REPLY, (void *) thread_state->basic.SP); - - if (sigthread && _hurdsig_catch_memory_fault (portloc)) - /* Faulted trying to read the stack. */ - return NULL; - - /* Fault now if this pointer is bogus. */ - *(volatile mach_port_t *) portloc = *portloc; - - if (sigthread) - _hurdsig_end_catch_fault (); - - return portloc; -} - -#include <hurd/sigpreempt.h> -#include <intr-msg.h> - -/* Timeout on interrupt_operation calls. */ -mach_msg_timeout_t _hurdsig_interrupt_timeout = 1000; - -/* SS->thread is suspended. - - Abort any interruptible RPC operation the thread is doing. - - This uses only the constant member SS->thread and the unlocked, atomically - set member SS->intr_port, so no locking is needed. - - If successfully sent an interrupt_operation and therefore the thread should - wait for its pending RPC to return (possibly EINTR) before taking the - incoming signal, returns the reply port to be received on. Otherwise - returns MACH_PORT_NULL. - - SIGNO is used to find the applicable SA_RESTART bit. If SIGNO is zero, - the RPC fails with EINTR instead of restarting (thread_cancel). - - *STATE_CHANGE is set nonzero if STATE->basic was modified and should - be applied back to the thread if it might ever run again, else zero. */ - -mach_port_t -_hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread, - struct machine_thread_all_state *state, int *state_change, - void (*reply) (void)) -{ - extern const void _hurd_intr_rpc_msg_in_trap; - mach_port_t rcv_port = MACH_PORT_NULL; - mach_port_t intr_port; - - *state_change = 0; - - intr_port = ss->intr_port; - if (intr_port == MACH_PORT_NULL) - /* No interruption needs done. */ - return MACH_PORT_NULL; - - /* Abort the thread's kernel context, so any pending message send or - receive completes immediately or aborts. */ - abort_thread (ss, state, reply); - - if (state->basic.PC < (natural_t) &_hurd_intr_rpc_msg_in_trap) - { - /* The thread is about to do the RPC, but hasn't yet entered - mach_msg. Mutate the thread's state so it knows not to try - the RPC. */ - INTR_MSG_BACK_OUT (&state->basic); - MACHINE_THREAD_STATE_SET_PC (&state->basic, - &_hurd_intr_rpc_msg_in_trap); - state->basic.SYSRETURN = MACH_SEND_INTERRUPTED; - *state_change = 1; - } - else if (state->basic.PC == (natural_t) &_hurd_intr_rpc_msg_in_trap && - /* The thread was blocked in the system call. After thread_abort, - the return value register indicates what state the RPC was in - when interrupted. */ - state->basic.SYSRETURN == MACH_RCV_INTERRUPTED) - { - /* The RPC request message was sent and the thread was waiting for - the reply message; now the message receive has been aborted, so - the mach_msg call will return MACH_RCV_INTERRUPTED. We must tell - the server to interrupt the pending operation. The thread must - wait for the reply message before running the signal handler (to - guarantee that the operation has finished being interrupted), so - our nonzero return tells the trampoline code to finish the message - receive operation before running the handler. */ - - mach_port_t *reply = interrupted_reply_port_location (state, - sigthread); - error_t err = __interrupt_operation (intr_port, _hurdsig_interrupt_timeout); - - if (err) - { - if (reply) - { - /* The interrupt didn't work. - Destroy the receive right the thread is blocked on. */ - __mach_port_destroy (__mach_task_self (), *reply); - *reply = MACH_PORT_NULL; - } - - /* The system call return value register now contains - MACH_RCV_INTERRUPTED; when mach_msg resumes, it will retry the - call. Since we have just destroyed the receive right, the - retry will fail with MACH_RCV_INVALID_NAME. Instead, just - change the return value here to EINTR so mach_msg will not - retry and the EINTR error code will propagate up. */ - state->basic.SYSRETURN = EINTR; - *state_change = 1; - } - else if (reply) - rcv_port = *reply; - - /* All threads whose RPCs were interrupted by the interrupt_operation - call above will retry their RPCs unless we clear SS->intr_port. - So we clear it for the thread taking a signal when SA_RESTART is - clear, so that its call returns EINTR. */ - if (! signo || !(ss->actions[signo].sa_flags & SA_RESTART)) - ss->intr_port = MACH_PORT_NULL; - } - - return rcv_port; -} - - -/* Abort the RPCs being run by all threads but this one; - all other threads should be suspended. If LIVE is nonzero, those - threads may run again, so they should be adjusted as necessary to be - happy when resumed. STATE is clobbered as a scratch area; its initial - contents are ignored, and its contents on return are not useful. */ - -static void -abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live) -{ - /* We can just loop over the sigstates. Any thread doing something - interruptible must have one. We needn't bother locking because all - other threads are stopped. */ - - struct hurd_sigstate *ss; - size_t nthreads; - mach_port_t *reply_ports; - - /* First loop over the sigstates to count them. - We need to know how big a vector we will need for REPLY_PORTS. */ - nthreads = 0; - for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) - ++nthreads; - - reply_ports = alloca (nthreads * sizeof *reply_ports); - - nthreads = 0; - for (ss = _hurd_sigstates; ss != NULL; ss = ss->next, ++nthreads) - if (ss->thread == _hurd_msgport_thread) - reply_ports[nthreads] = MACH_PORT_NULL; - else - { - int state_changed; - state->set = 0; /* Reset scratch area. */ - - /* Abort any operation in progress with interrupt_operation. - Record the reply port the thread is waiting on. - We will wait for all the replies below. */ - reply_ports[nthreads] = _hurdsig_abort_rpcs (ss, signo, 1, - state, &state_changed, - NULL); - if (live) - { - if (reply_ports[nthreads] != MACH_PORT_NULL) - { - /* We will wait for the reply to this RPC below, so the - thread must issue a new RPC rather than waiting for the - reply to the one it sent. */ - state->basic.SYSRETURN = EINTR; - state_changed = 1; - } - if (state_changed) - /* Aborting the RPC needed to change this thread's state, - and it might ever run again. So write back its state. */ - __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR, - (natural_t *) &state->basic, - MACHINE_THREAD_STATE_COUNT); - } - } - - /* Wait for replies from all the successfully interrupted RPCs. */ - while (nthreads-- > 0) - if (reply_ports[nthreads] != MACH_PORT_NULL) - { - error_t err; - mach_msg_header_t head; - err = __mach_msg (&head, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof head, - reply_ports[nthreads], - _hurd_interrupted_rpc_timeout, MACH_PORT_NULL); - switch (err) - { - case MACH_RCV_TIMED_OUT: - case MACH_RCV_TOO_LARGE: - break; - - default: - assert_perror (err); - } - } -} - -struct hurd_signal_preemptor *_hurdsig_preemptors = 0; -sigset_t _hurdsig_preempted_set; - -/* XXX temporary to deal with spelling fix */ -weak_alias (_hurdsig_preemptors, _hurdsig_preempters) - -/* Mask of stop signals. */ -#define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \ - sigmask (SIGSTOP) | sigmask (SIGTSTP)) - -/* Deliver a signal. SS is not locked. */ -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) -{ - error_t err; - struct machine_thread_all_state thread_state; - enum { stop, ignore, core, term, handle } act; - sighandler_t handler; - sigset_t pending; - int ss_suspended; - - /* Reply to this sig_post message. */ - __typeof (__msg_sig_post_reply) *reply_rpc - = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply); - void reply (void) - { - error_t err; - if (reply_port == MACH_PORT_NULL) - return; - err = (*reply_rpc) (reply_port, reply_port_type, 0); - reply_port = MACH_PORT_NULL; - if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */ - assert_perror (err); - } - - /* Mark the signal as pending. */ - void mark_pending (void) - { - __sigaddset (&ss->pending, signo); - /* Save the details to be given to the handler when SIGNO is - unblocked. */ - ss->pending_data[signo] = *detail; - } - - /* Suspend the process with SIGNO. */ - void suspend (void) - { - /* Stop all other threads and mark ourselves stopped. */ - __USEPORT (PROC, - ({ - /* Hold the siglock while stopping other threads to be - sure it is not held by another thread afterwards. */ - __mutex_lock (&_hurd_siglock); - __proc_dostop (port, _hurd_msgport_thread); - __mutex_unlock (&_hurd_siglock); - abort_all_rpcs (signo, &thread_state, 1); - reply (); - __proc_mark_stop (port, signo, detail->code); - })); - _hurd_stopped = 1; - } - /* Resume the process after a suspension. */ - void resume (void) - { - /* Resume the process from being stopped. */ - thread_t *threads; - mach_msg_type_number_t nthreads, i; - error_t err; - - if (! _hurd_stopped) - return; - - /* Tell the proc server we are continuing. */ - __USEPORT (PROC, __proc_mark_cont (port)); - /* Fetch ports to all our threads and resume them. */ - err = __task_threads (__mach_task_self (), &threads, &nthreads); - assert_perror (err); - for (i = 0; i < nthreads; ++i) - { - if (threads[i] != _hurd_msgport_thread && - (act != handle || threads[i] != ss->thread)) - { - err = __thread_resume (threads[i]); - assert_perror (err); - } - err = __mach_port_deallocate (__mach_task_self (), - threads[i]); - assert_perror (err); - } - __vm_deallocate (__mach_task_self (), - (vm_address_t) threads, - nthreads * sizeof *threads); - _hurd_stopped = 0; - if (act == handle) - /* The thread that will run the handler is already suspended. */ - ss_suspended = 1; - } - - if (signo == 0) - { - if (untraced) - /* This is PTRACE_CONTINUE. */ - resume (); - - /* This call is just to check for pending signals. */ - __spin_lock (&ss->lock); - goto check_pending_signals; - } - - post_signal: - - thread_state.set = 0; /* We know nothing. */ - - __spin_lock (&ss->lock); - - /* Check for a preempted signal. Preempted signals can arrive during - critical sections. */ - { - inline sighandler_t try_preemptor (struct hurd_signal_preemptor *pe) - { /* PE cannot be null. */ - do - { - if (HURD_PREEMPT_SIGNAL_P (pe, signo, detail->code)) - { - if (pe->preemptor) - { - sighandler_t handler = (*pe->preemptor) (pe, ss, - &signo, detail); - if (handler != SIG_ERR) - return handler; - } - else - return pe->handler; - } - pe = pe->next; - } while (pe != 0); - return SIG_ERR; - } - - handler = ss->preemptors ? try_preemptor (ss->preemptors) : SIG_ERR; - - /* If no thread-specific preemptor, check for a global one. */ - if (handler == SIG_ERR && __sigismember (&_hurdsig_preempted_set, signo)) - { - __mutex_lock (&_hurd_siglock); - handler = try_preemptor (_hurdsig_preemptors); - __mutex_unlock (&_hurd_siglock); - } - } - - ss_suspended = 0; - - if (handler == SIG_IGN) - /* Ignore the signal altogether. */ - act = ignore; - else if (handler != SIG_ERR) - /* Run the preemption-provided handler. */ - act = handle; - else - { - /* No preemption. Do normal handling. */ - - if (!untraced && __sigismember (&_hurdsig_traced, signo)) - { - /* We are being traced. Stop to tell the debugger of the signal. */ - if (_hurd_stopped) - /* Already stopped. Mark the signal as pending; - when resumed, we will notice it and stop again. */ - mark_pending (); - else - suspend (); - __spin_unlock (&ss->lock); - reply (); - return; - } - - handler = ss->actions[signo].sa_handler; - - if (handler == SIG_DFL) - /* Figure out the default action for this signal. */ - switch (signo) - { - case 0: - /* A sig_post msg with SIGNO==0 is sent to - tell us to check for pending signals. */ - act = ignore; - break; - - case SIGTTIN: - case SIGTTOU: - case SIGSTOP: - case SIGTSTP: - act = stop; - break; - - case SIGCONT: - case SIGIO: - case SIGURG: - case SIGCHLD: - case SIGWINCH: - act = ignore; - break; - - case SIGQUIT: - case SIGILL: - case SIGTRAP: - case SIGIOT: - case SIGEMT: - case SIGFPE: - case SIGBUS: - case SIGSEGV: - case SIGSYS: - act = core; - break; - - case SIGINFO: - if (_hurd_pgrp == _hurd_pid) - { - /* We are the process group leader. Since there is no - user-specified handler for SIGINFO, we use a default one - which prints something interesting. We use the normal - handler mechanism instead of just doing it here to avoid - the signal thread faulting or blocking in this - potentially hairy operation. */ - act = handle; - handler = _hurd_siginfo_handler; - } - else - act = ignore; - break; - - default: - act = term; - break; - } - else if (handler == SIG_IGN) - act = ignore; - else - act = handle; - - if (__sigmask (signo) & STOPSIGS) - /* Stop signals clear a pending SIGCONT even if they - are handled or ignored (but not if preempted). */ - __sigdelset (&ss->pending, SIGCONT); - else - { - if (signo == SIGCONT) - /* Even if handled or ignored (but not preempted), SIGCONT clears - stop signals and resumes the process. */ - ss->pending &= ~STOPSIGS; - - if (_hurd_stopped && act != stop && (untraced || signo == SIGCONT)) - resume (); - } - } - - if (_hurd_orphaned && act == stop && - (__sigmask (signo) & (__sigmask (SIGTTIN) | __sigmask (SIGTTOU) | - __sigmask (SIGTSTP)))) - { - /* If we would ordinarily stop for a job control signal, but we are - orphaned so noone would ever notice and continue us again, we just - quietly die, alone and in the dark. */ - detail->code = signo; - signo = SIGKILL; - act = term; - } - - /* Handle receipt of a blocked signal, or any signal while stopped. */ - if (act != ignore && /* Signals ignored now are forgotten now. */ - __sigismember (&ss->blocked, signo) || - (signo != SIGKILL && _hurd_stopped)) - { - mark_pending (); - act = ignore; - } - - /* Perform the chosen action for the signal. */ - switch (act) - { - case stop: - if (_hurd_stopped) - { - /* We are already stopped, but receiving an untraced stop - signal. Instead of resuming and suspending again, just - notify the proc server of the new stop signal. */ - error_t err = __USEPORT (PROC, __proc_mark_stop - (port, signo, detail->code)); - assert_perror (err); - } - else - /* Suspend the process. */ - suspend (); - break; - - case ignore: - if (detail->exc) - /* Blocking or ignoring a machine exception is fatal. - Otherwise we could just spin on the faulting instruction. */ - goto fatal; - - /* Nobody cares about this signal. If there was a call to resume - above in SIGCONT processing and we've left a thread suspended, - now's the time to set it going. */ - if (ss_suspended) - { - err = __thread_resume (ss->thread); - assert_perror (err); - ss_suspended = 0; - } - break; - - sigbomb: - /* We got a fault setting up the stack frame for the handler. - Nothing to do but die; BSD gets SIGILL in this case. */ - detail->code = signo; /* XXX ? */ - signo = SIGILL; - - fatal: - act = core; - /* FALLTHROUGH */ - - case term: /* Time to die. */ - case core: /* And leave a rotting corpse. */ - /* Have the proc server stop all other threads in our task. */ - err = __USEPORT (PROC, __proc_dostop (port, _hurd_msgport_thread)); - assert_perror (err); - /* No more user instructions will be executed. - The signal can now be considered delivered. */ - reply (); - /* Abort all server operations now in progress. */ - abort_all_rpcs (signo, &thread_state, 0); - - { - int status = W_EXITCODE (0, signo); - /* Do a core dump if desired. Only set the wait status bit saying we - in fact dumped core if the operation was actually successful. */ - if (act == core && write_corefile (signo, detail)) - status |= WCOREFLAG; - /* Tell proc how we died and then stick the saber in the gut. */ - _hurd_exit (status); - /* NOTREACHED */ - } - - case handle: - /* Call a handler for this signal. */ - { - struct sigcontext *scp, ocontext; - int wait_for_reply, state_changed; - - /* Stop the thread and abort its pending RPC operations. */ - if (! ss_suspended) - { - err = __thread_suspend (ss->thread); - assert_perror (err); - } - - /* Abort the thread's kernel context, so any pending message send - or receive completes immediately or aborts. If an interruptible - RPC is in progress, abort_rpcs will do this. But we must always - do it before fetching the thread's state, because - thread_get_state is never kosher before thread_abort. */ - abort_thread (ss, &thread_state, NULL); - - if (ss->context) - { - /* We have a previous sigcontext that sigreturn was about - to restore when another signal arrived. */ - - mach_port_t *loc; - - if (_hurdsig_catch_memory_fault (ss->context)) - { - /* We faulted reading the thread's stack. Forget that - context and pretend it wasn't there. It almost - certainly crash if this handler returns, but that's it's - problem. */ - ss->context = NULL; - } - else - { - /* Copy the context from the thread's stack before - we start diddling the stack to set up the handler. */ - ocontext = *ss->context; - ss->context = &ocontext; - } - _hurdsig_end_catch_fault (); - - if (! machine_get_basic_state (ss->thread, &thread_state)) - goto sigbomb; - loc = interrupted_reply_port_location (&thread_state, 1); - if (loc && *loc != MACH_PORT_NULL) - /* This is the reply port for the context which called - sigreturn. Since we are abandoning that context entirely - and restoring SS->context instead, destroy this port. */ - __mach_port_destroy (__mach_task_self (), *loc); - - /* The thread was in sigreturn, not in any interruptible RPC. */ - wait_for_reply = 0; - - assert (! __spin_lock_locked (&ss->critical_section_lock)); - } - else - { - int crit = __spin_lock_locked (&ss->critical_section_lock); - - wait_for_reply - = (_hurdsig_abort_rpcs (ss, - /* In a critical section, any RPC - should be cancelled instead of - restarted, regardless of - SA_RESTART, so the entire - "atomic" operation can be aborted - as a unit. */ - crit ? 0 : signo, 1, - &thread_state, &state_changed, - &reply) - != MACH_PORT_NULL); - - if (crit) - { - /* The thread is in a critical section. Mark the signal as - pending. When it finishes the critical section, it will - check for pending signals. */ - mark_pending (); - if (state_changed) - /* Some cases of interrupting an RPC must change the - thread state to back out the call. Normally this - change is rolled into the warping to the handler and - sigreturn, but we are not running the handler now - because the thread is in a critical section. Instead, - mutate the thread right away for the RPC interruption - and resume it; the RPC will return early so the - critical section can end soon. */ - __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR, - (natural_t *) &thread_state.basic, - MACHINE_THREAD_STATE_COUNT); - /* */ - ss->intr_port = MACH_PORT_NULL; - __thread_resume (ss->thread); - break; - } - } - - /* Call the machine-dependent function to set the thread up - to run the signal handler, and preserve its old context. */ - scp = _hurd_setup_sighandler (ss, handler, signo, detail, - wait_for_reply, &thread_state); - if (scp == NULL) - goto sigbomb; - - /* Set the machine-independent parts of the signal context. */ - - { - /* Fetch the thread variable for the MiG reply port, - and set it to MACH_PORT_NULL. */ - mach_port_t *loc = interrupted_reply_port_location (&thread_state, - 1); - if (loc) - { - scp->sc_reply_port = *loc; - *loc = MACH_PORT_NULL; - } - else - scp->sc_reply_port = MACH_PORT_NULL; - - /* Save the intr_port in use by the interrupted code, - and clear the cell before running the trampoline. */ - scp->sc_intr_port = ss->intr_port; - ss->intr_port = MACH_PORT_NULL; - - if (ss->context) - { - /* After the handler runs we will restore to the state in - SS->context, not the state of the thread now. So restore - that context's reply port and intr port. */ - - scp->sc_reply_port = ss->context->sc_reply_port; - scp->sc_intr_port = ss->context->sc_intr_port; - - ss->context = NULL; - } - } - - /* Backdoor extra argument to signal handler. */ - scp->sc_error = detail->error; - - /* Block requested signals while running the handler. */ - scp->sc_mask = ss->blocked; - __sigorset (&ss->blocked, &ss->blocked, &ss->actions[signo].sa_mask); - - /* Also block SIGNO unless we're asked not to. */ - if (! (ss->actions[signo].sa_flags & (SA_RESETHAND | SA_NODEFER))) - __sigaddset (&ss->blocked, signo); - - /* Reset to SIG_DFL if requested. SIGILL and SIGTRAP cannot - be automatically reset when delivered; the system silently - enforces this restriction. */ - if (ss->actions[signo].sa_flags & SA_RESETHAND - && signo != SIGILL && signo != SIGTRAP) - ss->actions[signo].sa_handler = SIG_DFL; - - /* Start the thread running the handler (or possibly waiting for an - RPC reply before running the handler). */ - err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR, - (natural_t *) &thread_state.basic, - MACHINE_THREAD_STATE_COUNT); - assert_perror (err); - err = __thread_resume (ss->thread); - assert_perror (err); - thread_state.set = 0; /* Everything we know is now wrong. */ - break; - } - } - - /* The signal has either been ignored or is now being handled. We can - consider it delivered and reply to the killer. */ - reply (); - - /* We get here unless the signal was fatal. We still hold SS->lock. - Check for pending signals, and loop to post them. */ - { - /* Return nonzero if SS has any signals pending we should worry about. - We don't worry about any pending signals if we are stopped, nor if - SS is in a critical section. We are guaranteed to get a sig_post - message before any of them become deliverable: either the SIGCONT - signal, or a sig_post with SIGNO==0 as an explicit poll when the - thread finishes its critical section. */ - inline int signals_pending (void) - { - if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock)) - return 0; - return pending = ss->pending & ~ss->blocked; - } - - check_pending_signals: - untraced = 0; - - if (signals_pending ()) - { - for (signo = 1; signo < NSIG; ++signo) - if (__sigismember (&pending, signo)) - { - deliver_pending: - __sigdelset (&ss->pending, signo); - *detail = ss->pending_data[signo]; - __spin_unlock (&ss->lock); - goto post_signal; - } - } - - /* No pending signals left undelivered for this thread. - If we were sent signal 0, we need to check for pending - signals for all threads. */ - if (signo == 0) - { - __spin_unlock (&ss->lock); - __mutex_lock (&_hurd_siglock); - for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) - { - __spin_lock (&ss->lock); - for (signo = 1; signo < NSIG; ++signo) - if (__sigismember (&ss->pending, signo) - && (!__sigismember (&ss->blocked, signo) - /* We "deliver" immediately pending blocked signals whose - action might be to ignore, so that if ignored they are - dropped right away. */ - || ss->actions[signo].sa_handler == SIG_IGN - || ss->actions[signo].sa_handler == SIG_DFL)) - { - mutex_unlock (&_hurd_siglock); - goto deliver_pending; - } - __spin_unlock (&ss->lock); - } - __mutex_unlock (&_hurd_siglock); - } - else - { - /* No more signals pending; SS->lock is still locked. - Wake up any sigsuspend call that is blocking SS->thread. */ - if (ss->suspended != MACH_PORT_NULL) - { - /* There is a sigsuspend waiting. Tell it to wake up. */ - error_t err; - mach_msg_header_t msg; - msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0); - msg.msgh_remote_port = ss->suspended; - msg.msgh_local_port = MACH_PORT_NULL; - /* These values do not matter. */ - msg.msgh_id = 8675309; /* Jenny, Jenny. */ - ss->suspended = MACH_PORT_NULL; - err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0, - MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - assert_perror (err); - } - __spin_unlock (&ss->lock); - } - } - - /* All pending signals delivered to all threads. - Now we can send the reply message even for signal 0. */ - reply (); -} - -/* Decide whether REFPORT enables the sender to send us a SIGNO signal. - Returns zero if so, otherwise the error code to return to the sender. */ - -static error_t -signal_allowed (int signo, mach_port_t refport) -{ - if (signo < 0 || signo >= NSIG) - return EINVAL; - - if (refport == __mach_task_self ()) - /* Can send any signal. */ - goto win; - - /* Avoid needing to check for this below. */ - if (refport == MACH_PORT_NULL) - return EPERM; - - switch (signo) - { - case SIGINT: - case SIGQUIT: - case SIGTSTP: - case SIGHUP: - case SIGINFO: - case SIGTTIN: - case SIGTTOU: - case SIGWINCH: - /* Job control signals can be sent by the controlling terminal. */ - if (__USEPORT (CTTYID, port == refport)) - goto win; - break; - - case SIGCONT: - { - /* A continue signal can be sent by anyone in the session. */ - mach_port_t sessport; - if (! __USEPORT (PROC, __proc_getsidport (port, &sessport))) - { - __mach_port_deallocate (__mach_task_self (), sessport); - if (refport == sessport) - goto win; - } - } - break; - - case SIGIO: - case SIGURG: - { - /* Any io object a file descriptor refers to might send us - one of these signals using its async ID port for REFPORT. - - This is pretty wide open; it is not unlikely that some random - process can at least open for reading something we have open, - get its async ID port, and send us a spurious SIGIO or SIGURG - signal. But BSD is actually wider open than that!--you can set - the owner of an io object to any process or process group - whatsoever and send them gratuitous signals. - - Someday we could implement some reasonable scheme for - authorizing SIGIO and SIGURG signals properly. */ - - int d; - int lucky = 0; /* True if we find a match for REFPORT. */ - __mutex_lock (&_hurd_dtable_lock); - for (d = 0; !lucky && (unsigned) d < (unsigned) _hurd_dtablesize; ++d) - { - struct hurd_userlink ulink; - io_t port; - mach_port_t asyncid; - if (_hurd_dtable[d] == NULL) - continue; - port = _hurd_port_get (&_hurd_dtable[d]->port, &ulink); - if (! __io_get_icky_async_id (port, &asyncid)) - { - if (refport == asyncid) - /* Break out of the loop on the next iteration. */ - lucky = 1; - __mach_port_deallocate (__mach_task_self (), asyncid); - } - _hurd_port_free (&_hurd_dtable[d]->port, &ulink, port); - } - __mutex_unlock (&_hurd_dtable_lock); - /* If we found a lucky winner, we've set D to -1 in the loop. */ - if (lucky) - goto win; - } - } - - /* If this signal is legit, we have done `goto win' by now. - When we return the error, mig deallocates REFPORT. */ - return EPERM; - - win: - /* Deallocate the REFPORT send right; we are done with it. */ - __mach_port_deallocate (__mach_task_self (), refport); - - return 0; -} - -/* Implement the sig_post RPC from <hurd/msg.defs>; - sent when someone wants us to get a signal. */ -kern_return_t -_S_msg_sig_post (mach_port_t me, - mach_port_t reply_port, mach_msg_type_name_t reply_port_type, - int signo, natural_t sigcode, - mach_port_t refport) -{ - error_t err; - struct hurd_signal_detail d; - - if (err = signal_allowed (signo, refport)) - return err; - - d.code = sigcode; - d.exc = 0; - - /* Post the signal to the designated signal-receiving thread. This will - reply when the signal can be considered delivered. */ - _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread), - signo, &d, reply_port, reply_port_type, - 0); /* Stop if traced. */ - - return MIG_NO_REPLY; /* Already replied. */ -} - -/* Implement the sig_post_untraced RPC from <hurd/msg.defs>; - sent when the debugger wants us to really get a signal - even if we are traced. */ -kern_return_t -_S_msg_sig_post_untraced (mach_port_t me, - mach_port_t reply_port, - mach_msg_type_name_t reply_port_type, - int signo, natural_t sigcode, - mach_port_t refport) -{ - error_t err; - struct hurd_signal_detail d; - - if (err = signal_allowed (signo, refport)) - return err; - - d.code = sigcode; - d.exc = 0; - - /* Post the signal to the designated signal-receiving thread. This will - reply when the signal can be considered delivered. */ - _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread), - signo, &d, reply_port, reply_port_type, - 1); /* Untraced flag. */ - - return MIG_NO_REPLY; /* Already replied. */ -} - -extern void __mig_init (void *); - -#include <mach/task_special_ports.h> - -/* Initialize the message port and _hurd_sigthread and start the signal - thread. */ - -void -_hurdsig_init (const int *intarray, size_t intarraysize) -{ - error_t err; - vm_size_t stacksize; - struct hurd_sigstate *ss; - - __mutex_init (&_hurd_siglock); - - err = __mach_port_allocate (__mach_task_self (), - MACH_PORT_RIGHT_RECEIVE, - &_hurd_msgport); - assert_perror (err); - - /* Make a send right to the signal port. */ - err = __mach_port_insert_right (__mach_task_self (), - _hurd_msgport, - _hurd_msgport, - MACH_MSG_TYPE_MAKE_SEND); - assert_perror (err); - - /* Initialize the main thread's signal state. */ - ss = _hurd_self_sigstate (); - - /* Copy inherited values from our parent (or pre-exec process state) - into the signal settings of the main thread. */ - if (intarraysize > INIT_SIGMASK) - ss->blocked = intarray[INIT_SIGMASK]; - if (intarraysize > INIT_SIGPENDING) - ss->pending = intarray[INIT_SIGPENDING]; - if (intarraysize > INIT_SIGIGN && intarray[INIT_SIGIGN] != 0) - { - int signo; - for (signo = 1; signo < NSIG; ++signo) - if (intarray[INIT_SIGIGN] & __sigmask(signo)) - ss->actions[signo].sa_handler = SIG_IGN; - } - - /* Set the default thread to receive task-global signals - to this one, the main (first) user thread. */ - _hurd_sigthread = ss->thread; - - /* Start the signal thread listening on the message port. */ - - if (__hurd_threadvar_stack_mask == 0) - { - err = __thread_create (__mach_task_self (), &_hurd_msgport_thread); - assert_perror (err); - - stacksize = __vm_page_size * 8; /* Small stack for signal thread. */ - err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread, - _hurd_msgport_receive, - (vm_address_t *) &__hurd_sigthread_stack_base, - &stacksize); - assert_perror (err); - - __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize; - __hurd_sigthread_variables = - malloc (__hurd_threadvar_max * sizeof (unsigned long int)); - if (__hurd_sigthread_variables == NULL) - __libc_fatal ("hurd: Can't allocate threadvars for signal thread\n"); - memset (__hurd_sigthread_variables, 0, - __hurd_threadvar_max * sizeof (unsigned long int)); - __hurd_sigthread_variables[_HURD_THREADVAR_LOCALE] - = (unsigned long int) &_nl_global_locale; - - /* Reinitialize the MiG support routines so they will use a per-thread - variable for the cached reply port. */ - __mig_init ((void *) __hurd_sigthread_stack_base); - - err = __thread_resume (_hurd_msgport_thread); - assert_perror (err); - } - else - { - /* When cthreads is being used, we need to make the signal thread a - proper cthread. Otherwise it cannot use mutex_lock et al, which - will be the cthreads versions. Various of the message port RPC - handlers need to take locks, so we need to be able to call into - cthreads code and meet its assumptions about how our thread and - its stack are arranged. Since cthreads puts it there anyway, - we'll let the signal thread's per-thread variables be found as for - any normal cthread, and just leave the magic __hurd_sigthread_* - values all zero so they'll be ignored. */ -#pragma weak cthread_fork -#pragma weak cthread_detach - cthread_detach (cthread_fork ((cthread_fn_t) &_hurd_msgport_receive, 0)); - - /* XXX We need the thread port for the signal thread further on - in this thread (see hurdfault.c:_hurdsigfault_init). - Therefore we block until _hurd_msgport_thread is initialized - by the newly created thread. This really shouldn't be - necessary; we should be able to fetch the thread port for a - cthread from here. */ - while (_hurd_msgport_thread == 0) - __swtch_pri (0); - } - - /* Receive exceptions on the signal port. */ -#ifdef TASK_EXCEPTION_PORT - __task_set_special_port (__mach_task_self (), - TASK_EXCEPTION_PORT, _hurd_msgport); -#elif defined (EXC_MASK_ALL) - __task_set_exception_ports (__mach_task_self (), - EXC_MASK_ALL & ~(EXC_MASK_SYSCALL - | EXC_MASK_MACH_SYSCALL - | EXC_MASK_RPC_ALERT), - _hurd_msgport, - EXCEPTION_DEFAULT, MACHINE_THREAD_STATE); -#else -# error task_set_exception_port? -#endif - - /* Sanity check. Any pending, unblocked signals should have been - taken by our predecessor incarnation (i.e. parent or pre-exec state) - before packing up our init ints. This assert is last (not above) - so that signal handling is all set up to handle the abort. */ - assert ((ss->pending &~ ss->blocked) == 0); -} - /* XXXX */ -/* Reauthenticate with the proc server. */ - -static void -reauth_proc (mach_port_t new) -{ - mach_port_t ref, ignore; - - ref = __mach_reply_port (); - if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC], - __proc_reauthenticate (port, ref, - MACH_MSG_TYPE_MAKE_SEND) || - __auth_user_authenticate (new, ref, - MACH_MSG_TYPE_MAKE_SEND, - &ignore)) - && ignore != MACH_PORT_NULL) - __mach_port_deallocate (__mach_task_self (), ignore); - __mach_port_destroy (__mach_task_self (), ref); - - /* Set the owner of the process here too. */ - mutex_lock (&_hurd_id.lock); - if (!_hurd_check_ids ()) - HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC], - __proc_setowner (port, - (_hurd_id.gen.nuids - ? _hurd_id.gen.uids[0] : 0), - !_hurd_id.gen.nuids)); - mutex_unlock (&_hurd_id.lock); - - (void) &reauth_proc; /* Silence compiler warning. */ -} -text_set_element (_hurd_reauth_hook, reauth_proc); - -/* Like `getenv', but safe for the signal thread to run. - If the environment is trashed, this will just return NULL. */ - -const char * -_hurdsig_getenv (const char *variable) -{ - if (__libc_enable_secure) - return NULL; - - if (_hurdsig_catch_memory_fault (__environ)) - /* We bombed in getenv. */ - return NULL; - else - { - const size_t len = strlen (variable); - char *value = NULL; - char *volatile *ep = __environ; - while (*ep) - { - const char *p = *ep; - _hurdsig_fault_preemptor.first = (long int) p; - _hurdsig_fault_preemptor.last = VM_MAX_ADDRESS; - if (! strncmp (p, variable, len) && p[len] == '=') - { - size_t valuelen; - p += len + 1; - valuelen = strlen (p); - _hurdsig_fault_preemptor.last = (long int) (p + valuelen); - value = malloc (++valuelen); - if (value) - memcpy (value, p, valuelen); - break; - } - _hurdsig_fault_preemptor.first = (long int) ++ep; - _hurdsig_fault_preemptor.last = (long int) (ep + 1); - } - _hurdsig_end_catch_fault (); - return value; - } -} diff --git a/hurd/hurdsock.c b/hurd/hurdsock.c deleted file mode 100644 index de4158def8..0000000000 --- a/hurd/hurdsock.c +++ /dev/null @@ -1,120 +0,0 @@ -/* _hurd_socket_server - Find the server for a socket domain. - Copyright (C) 1991-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/>. */ - -#include <hurd.h> -#include <sys/socket.h> -#include <stdlib.h> -#include <string.h> -#include <hurd/paths.h> -#include <stdio.h> -#include <_itoa.h> -#include <cthreads.h> /* For `struct mutex'. */ -#include "hurdmalloc.h" /* XXX */ - -static struct mutex lock; - -static file_t *servers; -static int max_domain = -1; - -/* Return a port to the socket server for DOMAIN. - Socket servers translate nodes in the directory _SERVERS_SOCKET - (canonically /servers/socket). These naming point nodes are named - by the simplest decimal representation of the socket domain number, - for example "/servers/socket/3". - - Socket servers are assumed not to change very often. - The library keeps all the server socket ports it has ever looked up, - and does not look them up in /servers/socket more than once. */ - -socket_t -_hurd_socket_server (int domain, int dead) -{ - socket_t server; - - if (domain < 0) - { - errno = EAFNOSUPPORT; - return MACH_PORT_NULL; - } - - HURD_CRITICAL_BEGIN; - __mutex_lock (&lock); - - if (domain > max_domain) - { - error_t save = errno; - file_t *new = realloc (servers, (domain + 1) * sizeof (file_t)); - if (new != NULL) - { - do - new[++max_domain] = MACH_PORT_NULL; - while (max_domain < domain); - servers = new; - } - else - /* No space to cache the port; we will just fetch it anew below. */ - errno = save; - } - - if (dead && domain <= max_domain) - { - /* The user says the port we returned earlier (now in SERVERS[DOMAIN]) - was dead. Clear the cache and fetch a new one below. */ - __mach_port_deallocate (__mach_task_self (), servers[domain]); - servers[domain] = MACH_PORT_NULL; - } - - if (domain > max_domain || servers[domain] == MACH_PORT_NULL) - { - char name[sizeof (_SERVERS_SOCKET) + 100]; - char *np = &name[sizeof (name)]; - *--np = '\0'; - np = _itoa (domain, np, 10, 0); - *--np = '/'; - np -= sizeof (_SERVERS_SOCKET) - 1; - memcpy (np, _SERVERS_SOCKET, sizeof (_SERVERS_SOCKET) - 1); - server = __file_name_lookup (np, 0, 0); - if (domain <= max_domain) - servers[domain] = server; - } - else - server = servers[domain]; - - if (server == MACH_PORT_NULL && errno == ENOENT) - /* If the server node is absent, we don't support that protocol. */ - errno = EAFNOSUPPORT; - - __mutex_unlock (&lock); - HURD_CRITICAL_END; - - return server; -} - -static void -init (void) -{ - int i; - - __mutex_init (&lock); - - for (i = 0; i < max_domain; ++i) - servers[i] = MACH_PORT_NULL; - - (void) &init; /* Avoid "defined but not used" warning. */ -} -text_set_element (_hurd_preinit_hook, init); diff --git a/hurd/hurdsocket.h b/hurd/hurdsocket.h deleted file mode 100644 index de2111b751..0000000000 --- a/hurd/hurdsocket.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Hurd-specific socket functions - Copyright (C) 2013-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_HURDSOCKET_H -#define _HURD_HURDSOCKET_H - -#include <string.h> - -/* Returns a duplicate of ADDR->sun_path with LEN limitation. This - should to be used whenever reading a unix socket address, to cope with - sun_path possibly not including a trailing \0. */ -#define _hurd_sun_path_dupa(addr, len) \ - strndupa ((addr)->sun_path, (len) - offsetof (struct sockaddr_un, sun_path)) - -#endif /* hurdsocket.h */ diff --git a/hurd/hurdstartup.c b/hurd/hurdstartup.c deleted file mode 100644 index d057ce1b18..0000000000 --- a/hurd/hurdstartup.c +++ /dev/null @@ -1,194 +0,0 @@ -/* Initial program startup for running under the GNU Hurd. - Copyright (C) 1991-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/>. */ - -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <hurd.h> -#include <hurd/exec_startup.h> -#include <sysdep.h> -#include <hurd/threadvar.h> -#include <unistd.h> -#include <elf.h> -#include <set-hooks.h> -#include "hurdstartup.h" -#include <argz.h> - -mach_port_t *_hurd_init_dtable; -mach_msg_type_number_t _hurd_init_dtablesize; - -extern void __mach_init (void); - -/* Entry point. This is the first thing in the text segment. - - The exec server started the initial thread in our task with this spot the - PC, and a stack that is presumably big enough. We do basic Mach - initialization so mig-generated stubs work, and then do an exec_startup - RPC on our bootstrap port, to which the exec server responds with the - information passed in the exec call, as well as our original bootstrap - port, and the base address and size of the preallocated stack. - - If using cthreads, we are given a new stack by cthreads initialization and - deallocate the stack set up by the exec server. On the new stack we call - `start1' (above) to do the rest of the startup work. Since the stack may - disappear out from under us in a machine-dependent way, we use a pile of - static variables to communicate the information from exec_startup to start1. - This is unfortunate but preferable to machine-dependent frobnication to copy - the state from the old stack to the new one. */ - - -void -_hurd_startup (void **argptr, void (*main) (intptr_t *data)) -{ - error_t err; - mach_port_t in_bootstrap; - char *args, *env; - mach_msg_type_number_t argslen, envlen; - struct hurd_startup_data data; - char **argv, **envp; - int argc, envc; - intptr_t *argcptr; - vm_address_t addr; - - /* Attempt to map page zero redzoned before we receive any RPC - data that might get allocated there. We can ignore errors. */ - addr = 0; - __vm_map (__mach_task_self (), - &addr, __vm_page_size, 0, 0, MACH_PORT_NULL, 0, 1, - VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY); - - if (err = __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT, - &in_bootstrap)) - LOSE; - - if (in_bootstrap != MACH_PORT_NULL) - { - /* Call the exec server on our bootstrap port and - get all our standard information from it. */ - - argslen = envlen = 0; - data.dtablesize = data.portarraysize = data.intarraysize = 0; - - err = __exec_startup_get_info (in_bootstrap, - &data.user_entry, - &data.phdr, &data.phdrsz, - &data.stack_base, &data.stack_size, - &data.flags, - &args, &argslen, - &env, &envlen, - &data.dtable, &data.dtablesize, - &data.portarray, &data.portarraysize, - &data.intarray, &data.intarraysize); - __mach_port_deallocate (__mach_task_self (), in_bootstrap); - } - - if (err || in_bootstrap == MACH_PORT_NULL || (data.flags & EXEC_STACK_ARGS)) - { - /* Either we have no bootstrap port, or the RPC to the exec server - failed, or whoever started us up passed the flag saying args are - on the stack. Try to snarf the args in the canonical Mach way. - Hopefully either they will be on the stack as expected, or the - stack will be zeros so we don't crash. */ - - argcptr = (intptr_t *) argptr; - argc = argcptr[0]; - argv = (char **) &argcptr[1]; - envp = &argv[argc + 1]; - envc = 0; - while (envp[envc]) - ++envc; - } - else - { - /* Turn the block of null-separated strings we were passed for the - arguments and environment into vectors of pointers to strings. */ - - /* Count up the arguments so we can allocate ARGV. */ - argc = __argz_count (args, argslen); - /* Count up the environment variables so we can allocate ENVP. */ - envc = __argz_count (env, envlen); - - /* There were some arguments. Allocate space for the vectors of - pointers and fill them in. We allocate the space for the - environment pointers immediately after the argv pointers because - the ELF ABI will expect it. */ - argcptr = __alloca (sizeof (intptr_t) + - (argc + 1 + envc + 1) * sizeof (char *) + - sizeof (struct hurd_startup_data)); - *argcptr = argc; - argv = (void *) (argcptr + 1); - __argz_extract (args, argslen, argv); - - /* There was some environment. */ - envp = &argv[argc + 1]; - __argz_extract (env, envlen, envp); - } - - if (err || in_bootstrap == MACH_PORT_NULL) - { - /* Either we have no bootstrap port, or the RPC to the exec server - failed. Set all our other variables to have empty information. */ - - data.flags = 0; - args = env = NULL; - argslen = envlen = 0; - data.dtable = NULL; - data.dtablesize = 0; - data.portarray = NULL; - data.portarraysize = 0; - data.intarray = NULL; - data.intarraysize = 0; - } - else if ((void *) &envp[envc + 1] == argv[0]) - { - /* The arguments arrived on the stack from the kernel, but our - protocol requires some space after them for a `struct - hurd_startup_data'. Move them. */ - struct - { - intptr_t count; - char *argv[argc + 1]; - char *envp[envc + 1]; - struct hurd_startup_data data; - } *args = alloca (sizeof *args); - if ((void *) &args[1] == (void *) argcptr) - args = alloca (-((char *) &args->data - (char *) args)); - memmove (args, argcptr, (char *) &args->data - (char *) args); - argcptr = (void *) args; - argv = args->argv; - envp = args->envp; - } - - { - struct hurd_startup_data *d = (void *) &envp[envc + 1]; - - if ((void *) d != argv[0]) - { - *d = data; - _hurd_init_dtable = d->dtable; - _hurd_init_dtablesize = d->dtablesize; - } - - (*main) (argcptr); - } - - /* Should never get here. */ - LOSE; - abort (); -} diff --git a/hurd/hurdstartup.h b/hurd/hurdstartup.h deleted file mode 100644 index f0d82d96a5..0000000000 --- a/hurd/hurdstartup.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Data from initial program startup for running under 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 _HURDSTARTUP_H -#define _HURDSTARTUP_H 1 - -# include <stdint.h> - -/* Interesting data saved from the exec_startup reply. - The DATA argument to *MAIN (see below) points to: - - int argc; - char *argv[argc]; - char *argv_terminator = NULL; - char *envp[?]; - char *envp_terminator = NULL; - struct hurd_startup_data data; - -*/ - -struct hurd_startup_data - { - int flags; - mach_port_t *dtable; - mach_msg_type_number_t dtablesize; - mach_port_t *portarray; - mach_msg_type_number_t portarraysize; - int *intarray; - mach_msg_type_number_t intarraysize; - vm_address_t stack_base; - vm_size_t stack_size; - vm_address_t phdr; - vm_size_t phdrsz; - vm_address_t user_entry; - }; - - -/* Initialize Mach RPCs; do initial handshake with the exec server (or - extract the arguments from the stack in the case of the bootstrap task); - finally, call *MAIN with the information gleaned. That function is not - expected to return. ARGPTR should be the address of the first argument - of the entry point function that is called with the stack exactly as the - exec server or kernel sets it. */ - -extern void _hurd_startup (void **argptr, void (*main) (intptr_t *data)); - - -#endif /* hurdstartup.h */ diff --git a/hurd/intern-fd.c b/hurd/intern-fd.c deleted file mode 100644 index 7e49028659..0000000000 --- a/hurd/intern-fd.c +++ /dev/null @@ -1,49 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/fd.h> - -/* Allocate a new file descriptor and install PORT in it. FLAGS are as for - `open'; only O_IGNORE_CTTY and O_CLOEXEC are meaningful. - - If the descriptor table is full, set errno, and return -1. - If DEALLOC is nonzero, deallocate PORT first. */ -int -_hurd_intern_fd (io_t port, int flags, int dealloc) -{ - int fd; - struct hurd_fd *d; - - HURD_CRITICAL_BEGIN; - d = _hurd_alloc_fd (&fd, 0); - if (d != NULL) - { - _hurd_port2fd (d, port, flags); - __spin_unlock (&d->port.lock); - } - HURD_CRITICAL_END; - - if (d == NULL) - { - if (dealloc) - __mach_port_deallocate (__mach_task_self (), port); - return -1; - } - - return fd; -} diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c deleted file mode 100644 index 636bd7b68d..0000000000 --- a/hurd/intr-msg.c +++ /dev/null @@ -1,424 +0,0 @@ -/* Replacement for mach_msg used in interruptible Hurd RPCs. - 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/>. */ - -#include <mach.h> -#include <mach/mig_errors.h> -#include <mach/mig_support.h> -#include <hurd/signal.h> -#include <assert.h> - -#include "intr-msg.h" - -#ifdef NDR_CHAR_ASCII /* OSF Mach flavors have different names. */ -# define mig_reply_header_t mig_reply_error_t -#endif - -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) -{ - error_t err; - struct hurd_sigstate *ss; - const mach_msg_option_t user_option = option; - const mach_msg_timeout_t user_timeout = timeout; - - struct clobber - { -#ifdef NDR_CHAR_ASCII - NDR_record_t ndr; -#else - mach_msg_type_t type; -#endif - error_t err; - }; - union msg - { - mach_msg_header_t header; - mig_reply_header_t reply; - struct - { - mach_msg_header_t header; -#ifdef NDR_CHAR_ASCII - NDR_record_t ndr; -#else - int type; -#endif - int code; - } check; - struct - { - mach_msg_header_t header; - struct clobber data; - } request; - }; - union msg *const m = (void *) msg; - mach_msg_bits_t msgh_bits; - mach_port_t remote_port; - mach_msg_id_t msgid; - struct clobber save_data; - - if ((option & (MACH_SEND_MSG|MACH_RCV_MSG)) != (MACH_SEND_MSG|MACH_RCV_MSG) - || _hurd_msgport_thread == MACH_PORT_NULL) - { - /* Either this is not an RPC (i.e., only a send or only a receive), - so it can't be interruptible; or, the signal thread is not set up - yet, so we cannot do the normal signal magic. Do a normal, - uninterruptible mach_msg call instead. */ - return __mach_msg (&m->header, option, send_size, rcv_size, rcv_name, - timeout, notify); - } - - ss = _hurd_self_sigstate (); - - /* Save state that gets clobbered by an EINTR reply message. - We will need to restore it if we want to retry the RPC. */ - msgh_bits = m->header.msgh_bits; - remote_port = m->header.msgh_remote_port; - msgid = m->header.msgh_id; - assert (rcv_size >= sizeof m->request); - save_data = m->request.data; - - /* Tell the signal thread that we are doing an interruptible RPC on - this port. If we get a signal and should return EINTR, the signal - thread will set this variable to MACH_PORT_NULL. The RPC might - return EINTR when some other thread gets a signal, in which case we - want to restart our call. */ - ss->intr_port = m->header.msgh_remote_port; - - /* A signal may arrive here, after intr_port is set, but before the - mach_msg system call. The signal handler might do an interruptible - RPC, and clobber intr_port; then it would not be set properly when we - actually did send the RPC, and a later signal wouldn't interrupt that - RPC. So, _hurd_setup_sighandler saves intr_port in the sigcontext, - and sigreturn restores it. */ - - message: - - /* XXX - At all points here (once SS->intr_port is set), the signal thread - thinks we are "about to enter the syscall", and might mutate our - return-value register. This is bogus. - */ - - if (ss->cancel) - { - /* We have been cancelled. Don't do an RPC at all. */ - ss->intr_port = MACH_PORT_NULL; - ss->cancel = 0; - return EINTR; - } - - /* Note that the signal trampoline code might modify our OPTION! */ - err = INTR_MSG_TRAP (msg, option, send_size, - rcv_size, rcv_name, timeout, notify); - - switch (err) - { - case MACH_RCV_TIMED_OUT: - if (user_option & MACH_RCV_TIMEOUT) - /* The real user RPC timed out. */ - break; - else - /* The operation was supposedly interrupted, but still has - not returned. Declare it interrupted. */ - goto interrupted; - - case MACH_SEND_INTERRUPTED: /* RPC didn't get out. */ - if (!(option & MACH_SEND_MSG)) - { - /* Oh yes, it did! Since we were not doing a message send, - this return code cannot have come from the kernel! - Instead, it was the signal thread mutating our state to tell - us not to enter this RPC. However, we are already in the receive! - Since the signal thread thought we weren't in the RPC yet, - it didn't do an interrupt_operation. - XXX */ - goto retry_receive; - } - /* FALLTHROUGH */ - - /* These are the other codes that mean a pseudo-receive modified - the message buffer and we might need to clean up the port rights. */ - case MACH_SEND_TIMED_OUT: - case MACH_SEND_INVALID_NOTIFY: -#ifdef MACH_SEND_NO_NOTIFY - case MACH_SEND_NO_NOTIFY: -#endif -#ifdef MACH_SEND_NOTIFY_IN_PROGRESS - case MACH_SEND_NOTIFY_IN_PROGRESS: -#endif - if (MACH_MSGH_BITS_REMOTE (msg->msgh_bits) == MACH_MSG_TYPE_MOVE_SEND) - { - __mach_port_deallocate (__mach_task_self (), msg->msgh_remote_port); - msg->msgh_bits - = (MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, - MACH_MSGH_BITS_LOCAL (msg->msgh_bits)) - | MACH_MSGH_BITS_OTHER (msg->msgh_bits)); - } - if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) - { -#ifndef MACH_MSG_PORT_DESCRIPTOR - /* Check for MOVE_SEND rights in the message. These hold refs - that we need to release in case the message is in fact never - re-sent later. Since it might in fact be re-sent, we turn - these into COPY_SEND's after deallocating the extra user ref; - the caller is responsible for still holding a ref to go with - the original COPY_SEND right, so the resend copies it again. */ - - mach_msg_type_long_t *ty = (void *) (msg + 1); - while ((void *) ty < (void *) msg + msg->msgh_size) - { - mach_msg_type_name_t name; - mach_msg_type_size_t size; - mach_msg_type_number_t number; - - inline void clean_ports (mach_port_t *ports, int dealloc) - { - mach_msg_type_number_t i; - switch (name) - { - case MACH_MSG_TYPE_MOVE_SEND: - for (i = 0; i < number; i++) - __mach_port_deallocate (__mach_task_self (), *ports++); - if (ty->msgtl_header.msgt_longform) - ty->msgtl_name = MACH_MSG_TYPE_COPY_SEND; - else - ty->msgtl_header.msgt_name = MACH_MSG_TYPE_COPY_SEND; - break; - case MACH_MSG_TYPE_COPY_SEND: - case MACH_MSG_TYPE_MOVE_RECEIVE: - break; - default: - if (MACH_MSG_TYPE_PORT_ANY (name)) - assert (! "unexpected port type in interruptible RPC"); - } - if (dealloc) - __vm_deallocate (__mach_task_self (), - (vm_address_t) ports, - number * sizeof (mach_port_t)); - } - - if (ty->msgtl_header.msgt_longform) - { - name = ty->msgtl_name; - size = ty->msgtl_size; - number = ty->msgtl_number; - ty = (void *) ty + sizeof (mach_msg_type_long_t); - } - else - { - name = ty->msgtl_header.msgt_name; - size = ty->msgtl_header.msgt_size; - number = ty->msgtl_header.msgt_number; - ty = (void *) ty + sizeof (mach_msg_type_t); - } - - if (ty->msgtl_header.msgt_inline) - { - clean_ports ((void *) ty, 0); - /* calculate length of data in bytes, rounding up */ - ty = (void *) ty + (((((number * size) + 7) >> 3) - + sizeof (mach_msg_type_t) - 1) - &~ (sizeof (mach_msg_type_t) - 1)); - } - else - { - clean_ports (*(void **) ty, - ty->msgtl_header.msgt_deallocate); - ty = (void *) ty + sizeof (void *); - } - } -#else /* Untyped Mach IPC flavor. */ - mach_msg_body_t *body = (void *) (msg + 1); - mach_msg_descriptor_t *desc = (void *) (body + 1); - mach_msg_descriptor_t *desc_end = desc + body->msgh_descriptor_count; - for (; desc < desc_end; ++desc) - switch (desc->type.type) - { - case MACH_MSG_PORT_DESCRIPTOR: - switch (desc->port.disposition) - { - case MACH_MSG_TYPE_MOVE_SEND: - __mach_port_deallocate (mach_task_self (), - desc->port.name); - desc->port.disposition = MACH_MSG_TYPE_COPY_SEND; - break; - case MACH_MSG_TYPE_COPY_SEND: - case MACH_MSG_TYPE_MOVE_RECEIVE: - break; - default: - assert (! "unexpected port type in interruptible RPC"); - } - break; - case MACH_MSG_OOL_DESCRIPTOR: - if (desc->out_of_line.deallocate) - __vm_deallocate (__mach_task_self (), - (vm_address_t) desc->out_of_line.address, - desc->out_of_line.size); - break; - case MACH_MSG_OOL_PORTS_DESCRIPTOR: - switch (desc->ool_ports.disposition) - { - case MACH_MSG_TYPE_MOVE_SEND: - { - mach_msg_size_t i; - const mach_port_t *ports = desc->ool_ports.address; - for (i = 0; i < desc->ool_ports.count; ++i) - __mach_port_deallocate (__mach_task_self (), ports[i]); - desc->ool_ports.disposition = MACH_MSG_TYPE_COPY_SEND; - break; - } - case MACH_MSG_TYPE_COPY_SEND: - case MACH_MSG_TYPE_MOVE_RECEIVE: - break; - default: - assert (! "unexpected port type in interruptible RPC"); - } - if (desc->ool_ports.deallocate) - __vm_deallocate (__mach_task_self (), - (vm_address_t) desc->ool_ports.address, - desc->ool_ports.count - * sizeof (mach_port_t)); - break; - default: - assert (! "unexpected descriptor type in interruptible RPC"); - } -#endif - } - break; - - case EINTR: - /* Either the process was stopped and continued, - or the server doesn't support interrupt_operation. */ - if (ss->intr_port != MACH_PORT_NULL) - /* If this signal was for us and it should interrupt calls, the - signal thread will have cleared SS->intr_port. - Since it's not cleared, the signal was for another thread, - or SA_RESTART is set. Restart the interrupted call. */ - { - /* Make sure we have a valid reply port. The one we were using - may have been destroyed by interruption. */ - m->header.msgh_local_port = rcv_name = __mig_get_reply_port (); - m->header.msgh_bits = msgh_bits; - option = user_option; - timeout = user_timeout; - goto message; - } - /* FALLTHROUGH */ - - case MACH_RCV_PORT_DIED: - /* Server didn't respond to interrupt_operation, - so the signal thread destroyed the reply port. */ - /* FALLTHROUGH */ - - interrupted: - err = EINTR; - - /* The EINTR return indicates cancellation, so clear the flag. */ - ss->cancel = 0; - break; - - case MACH_RCV_INTERRUPTED: /* RPC sent; no reply. */ - option &= ~MACH_SEND_MSG; /* Don't send again. */ - retry_receive: - if (ss->intr_port == MACH_PORT_NULL) - { - /* This signal or cancellation was for us. We need to wait for - the reply, but not hang forever. */ - option |= MACH_RCV_TIMEOUT; - /* Never decrease the user's timeout. */ - if (!(user_option & MACH_RCV_TIMEOUT) - || timeout > _hurd_interrupted_rpc_timeout) - timeout = _hurd_interrupted_rpc_timeout; - } - else - { - option = user_option; - timeout = user_timeout; - } - goto message; /* Retry the receive. */ - - case MACH_MSG_SUCCESS: - { - /* We got a reply. Was it EINTR? */ -#ifdef MACH_MSG_TYPE_BIT - const union - { - mach_msg_type_t t; - int i; - } check = - { t: { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, - 1, TRUE, FALSE, FALSE, 0 } }; -#endif - - if (m->reply.RetCode == EINTR && - m->header.msgh_size == sizeof m->reply && -#ifdef MACH_MSG_TYPE_BIT - m->check.type == check.i && -#endif - !(m->header.msgh_bits & MACH_MSGH_BITS_COMPLEX)) - { - /* It is indeed EINTR. Is the interrupt for us? */ - if (ss->intr_port != MACH_PORT_NULL) - { - /* Nope; repeat the RPC. - XXX Resources moved? */ - - assert (m->header.msgh_id == msgid + 100); - - /* We know we have a valid reply port, because we just - received the EINTR reply on it. Restore it and the - other fields in the message header needed for send, - since the header now reflects receipt of the reply. */ - m->header.msgh_local_port = rcv_name; - m->header.msgh_remote_port = remote_port; - m->header.msgh_id = msgid; - m->header.msgh_bits = msgh_bits; - /* Restore the two words clobbered by the reply data. */ - m->request.data = save_data; - - /* Restore the original mach_msg options. - OPTION may have had MACH_RCV_TIMEOUT added, - and/or MACH_SEND_MSG removed. */ - option = user_option; - timeout = user_timeout; - - /* Now we are ready to repeat the original message send. */ - goto message; - } - else - /* The EINTR return indicates cancellation, - so clear the flag. */ - ss->cancel = 0; - } - } - break; - - default: /* Quiet -Wswitch-enum. */ - break; - } - - ss->intr_port = MACH_PORT_NULL; - - return err; -} diff --git a/hurd/intr-rpc.defs b/hurd/intr-rpc.defs deleted file mode 100644 index 4acbcc8847..0000000000 --- a/hurd/intr-rpc.defs +++ /dev/null @@ -1,22 +0,0 @@ -/* Special MiG definitions for interruptible RPC stubs. - 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/>. */ - -/* Cause user stubs for interruptible RPCs to import a special header to - modify their behavior. */ - -#define INTR_INTERFACE uimport "intr-rpc.h"; diff --git a/hurd/intr-rpc.h b/hurd/intr-rpc.h deleted file mode 100644 index 208e42c2ee..0000000000 --- a/hurd/intr-rpc.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Special MiG definitions for interruptible RPC stubs. - 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/>. */ - -/* This file is imported by the MiG-generated user stubs for interruptible - RPCs. We modify them to use our own function in place of mach_msg. */ - -#include <hurd/signal.h> - -#define __mach_msg _hurd_intr_rpc_mach_msg diff --git a/hurd/longjmp-ts.c b/hurd/longjmp-ts.c deleted file mode 100644 index 0fea819a23..0000000000 --- a/hurd/longjmp-ts.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Perform a `longjmp' on a Mach thread_state. Stub version. - Copyright (C) 1991-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/>. */ - -#include <setjmp.h> -#include <mach/thread_status.h> - -/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */ - -void -_hurd_longjmp_thread_state (void *state, jmp_buf env, int val) -{ - /* Set all the registers in *STATE to the values described by ENV and - RETVAL. After this, setting that thread's state to STATE should be - just like calling `longjmp (ENV, RETVAL)'. */ - #error "Need to write sysdeps/mach/hurd/MACHINE/longjmp-ctx.c" -} diff --git a/hurd/lookup-at.c b/hurd/lookup-at.c deleted file mode 100644 index b5d605665d..0000000000 --- a/hurd/lookup-at.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Lookup helper function for Hurd implementation of *at functions. - Copyright (C) 2006-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/>. */ - -#include <hurd.h> -#include <hurd/lookup.h> -#include <hurd/fd.h> -#include <string.h> -#include <fcntl.h> - -file_t -__file_name_lookup_at (int fd, int at_flags, - const char *file_name, int flags, mode_t mode) -{ - error_t err; - file_t result; - - if ((at_flags & AT_SYMLINK_FOLLOW) && (at_flags & AT_SYMLINK_NOFOLLOW)) - return (__hurd_fail (EINVAL), MACH_PORT_NULL); - - flags |= (at_flags & AT_SYMLINK_NOFOLLOW) ? O_NOLINK : 0; - at_flags &= ~AT_SYMLINK_NOFOLLOW; - if (at_flags & AT_SYMLINK_FOLLOW) - flags &= ~O_NOLINK; - at_flags &= ~AT_SYMLINK_FOLLOW; - if (at_flags != 0) - return (__hurd_fail (EINVAL), MACH_PORT_NULL); - - if (fd == AT_FDCWD || file_name[0] == '/') - return __file_name_lookup (file_name, flags, mode); - - file_t startdir; - error_t use_init_port (int which, error_t (*operate) (mach_port_t)) - { - return (which == INIT_PORT_CWDIR ? (*operate) (startdir) : - _hurd_ports_use (which, operate)); - } - - err = HURD_DPORT_USE (fd, (startdir = port, - __hurd_file_name_lookup (&use_init_port, - &__getdport, NULL, - file_name, - flags, - mode & ~_hurd_umask, - &result))); - - return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result; -} - -file_t -__file_name_split_at (int fd, const char *file_name, char **name) -{ - error_t err; - file_t result; - - if (fd == AT_FDCWD || file_name[0] == '/') - return __file_name_split (file_name, name); - - err = __hurd_file_name_split (&_hurd_ports_use, &__getdport, 0, - file_name, &result, name); - - file_t startdir; - error_t use_init_port (int which, error_t (*operate) (mach_port_t)) - { - return (which == INIT_PORT_CWDIR ? (*operate) (startdir) : - _hurd_ports_use (which, operate)); - } - - err = HURD_DPORT_USE (fd, (startdir = port, - __hurd_file_name_split (&use_init_port, - &__getdport, 0, - file_name, - &result, name))); - - return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result; -} - -file_t -__directory_name_split_at (int fd, const char *directory_name, char **name) -{ - error_t err; - file_t result; - - if (fd == AT_FDCWD || directory_name[0] == '/') - return __directory_name_split (directory_name, name); - - file_t startdir; - error_t use_init_port (int which, error_t (*operate) (mach_port_t)) - { - return (which == INIT_PORT_CWDIR ? (*operate) (startdir) : - _hurd_ports_use (which, operate)); - } - - err = HURD_DPORT_USE (fd, (startdir = port, - __hurd_directory_name_split (&use_init_port, - &__getdport, 0, - directory_name, - &result, name))); - - return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result; -} diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c deleted file mode 100644 index 2d88b98e4f..0000000000 --- a/hurd/lookup-retry.c +++ /dev/null @@ -1,331 +0,0 @@ -/* hairy bits of Hurd file name lookup - Copyright (C) 1992-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/>. */ - -#include <hurd.h> -#include <hurd/lookup.h> -#include <hurd/term.h> -#include <hurd/paths.h> -#include <limits.h> -#include <fcntl.h> -#include <string.h> -#include <_itoa.h> -#include <eloop-threshold.h> - -/* Translate the error from dir_lookup into the error the user sees. */ -static inline error_t -lookup_error (error_t error) -{ - switch (error) - { - case EOPNOTSUPP: - case MIG_BAD_ID: - /* These indicate that the server does not understand dir_lookup - at all. If it were a directory, it would, by definition. */ - return ENOTDIR; - default: - return error; - } -} - -error_t -__hurd_file_name_lookup_retry (error_t (*use_init_port) - (int which, error_t (*operate) (file_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 err; - char *file_name; - int nloops; - - error_t lookup_op (file_t startdir) - { - if (file_name[0] == '/' && file_name[1] != '\0') - { - while (file_name[1] == '/') - /* Remove double leading slash. */ - file_name++; - if (file_name[1] != '\0') - /* Remove leading slash when we have more than the slash. */ - file_name++; - } - - return lookup_error ((*lookup) (startdir, file_name, flags, mode, - &doretry, retryname, result)); - } - error_t reauthenticate (file_t unauth) - { - error_t err; - mach_port_t ref = __mach_reply_port (); - error_t reauth (auth_t auth) - { - return __auth_user_authenticate (auth, ref, - MACH_MSG_TYPE_MAKE_SEND, - result); - } - err = __io_reauthenticate (unauth, ref, MACH_MSG_TYPE_MAKE_SEND); - if (! err) - err = (*use_init_port) (INIT_PORT_AUTH, &reauth); - __mach_port_destroy (__mach_task_self (), ref); - __mach_port_deallocate (__mach_task_self (), unauth); - return err; - } - - if (! lookup) - lookup = __dir_lookup; - - nloops = 0; - err = 0; - do - { - file_t startdir = MACH_PORT_NULL; - int dirport = INIT_PORT_CWDIR; - - switch (doretry) - { - case FS_RETRY_REAUTH: - if (err = reauthenticate (*result)) - return err; - /* Fall through. */ - - case FS_RETRY_NORMAL: - if (nloops++ >= __eloop_threshold ()) - { - __mach_port_deallocate (__mach_task_self (), *result); - return ELOOP; - } - - /* An empty RETRYNAME indicates we have the final port. */ - if (retryname[0] == '\0' && - /* If reauth'd, we must do one more retry on "" to give the new - translator a chance to make a new port for us. */ - doretry == FS_RETRY_NORMAL) - { - if (flags & O_NOFOLLOW) - { - /* In Linux, O_NOFOLLOW means to reject symlinks. If we - did an O_NOLINK lookup above and io_stat here to check - for S_IFLNK, a translator like firmlink could easily - spoof this check by not showing S_IFLNK, but in fact - redirecting the lookup to some other name - (i.e. opening the very same holes a symlink would). - - Instead we do an O_NOTRANS lookup above, and stat the - underlying node: if it has a translator set, and its - owner is not root (st_uid 0) then we reject it. - Since the motivation for this feature is security, and - that security presumes we trust the containing - directory, this check approximates the security of - refusing symlinks while accepting mount points. - Note that we actually permit something Linux doesn't: - we follow root-owned symlinks; if that is deemed - undesireable, we can add a final check for that - one exception to our general translator-based rule. */ - struct stat64 st; - err = __io_stat (*result, &st); - if (!err - && (st.st_mode & (S_IPTRANS|S_IATRANS))) - { - if (st.st_uid != 0) - err = ENOENT; - else if (st.st_mode & S_IPTRANS) - { - char buf[1024]; - char *trans = buf; - size_t translen = sizeof buf; - err = __file_get_translator (*result, - &trans, &translen); - if (!err - && translen > sizeof _HURD_SYMLINK - && !memcmp (trans, - _HURD_SYMLINK, sizeof _HURD_SYMLINK)) - err = ENOENT; - } - } - } - - /* We got a successful translation. Now apply any open-time - action flags we were passed. */ - - if (!err && (flags & O_TRUNC)) /* Asked to truncate the file. */ - err = __file_set_size (*result, 0); - - if (err) - __mach_port_deallocate (__mach_task_self (), *result); - return err; - } - - startdir = *result; - file_name = retryname; - break; - - case FS_RETRY_MAGICAL: - switch (retryname[0]) - { - case '/': - dirport = INIT_PORT_CRDIR; - if (*result != MACH_PORT_NULL) - __mach_port_deallocate (__mach_task_self (), *result); - if (nloops++ >= __eloop_threshold ()) - return ELOOP; - file_name = &retryname[1]; - break; - - case 'f': - if (retryname[1] == 'd' && retryname[2] == '/') - { - int fd; - char *end; - int save = errno; - errno = 0; - fd = (int) __strtoul_internal (&retryname[3], &end, 10, 0); - if (end == NULL || errno || /* Malformed number. */ - /* Check for excess text after the number. A slash - is valid; it ends the component. Anything else - does not name a numeric file descriptor. */ - (*end != '/' && *end != '\0')) - { - errno = save; - return ENOENT; - } - if (! get_dtable_port) - err = EGRATUITOUS; - else - { - *result = (*get_dtable_port) (fd); - if (*result == MACH_PORT_NULL) - { - /* If the name was a proper number, but the file - descriptor does not exist, we return EBADF instead - of ENOENT. */ - err = errno; - errno = save; - } - } - errno = save; - if (err) - return err; - if (*end == '\0') - return 0; - else - { - /* Do a normal retry on the remaining components. */ - startdir = *result; - file_name = end + 1; /* Skip the slash. */ - break; - } - } - else - goto bad_magic; - break; - - case 'm': - if (retryname[1] == 'a' && retryname[2] == 'c' && - retryname[3] == 'h' && retryname[4] == 't' && - retryname[5] == 'y' && retryname[6] == 'p' && - retryname[7] == 'e') - { - error_t err; - struct host_basic_info hostinfo; - mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT; - char *p; - /* XXX want client's host */ - if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO, - (integer_t *) &hostinfo, - &hostinfocnt)) - return err; - if (hostinfocnt != HOST_BASIC_INFO_COUNT) - return EGRATUITOUS; - p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0); - *--p = '/'; - p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0); - if (p < retryname) - abort (); /* XXX write this right if this ever happens */ - if (p > retryname) - strcpy (retryname, p); - startdir = *result; - } - else - goto bad_magic; - break; - - case 't': - if (retryname[1] == 't' && retryname[2] == 'y') - switch (retryname[3]) - { - error_t opentty (file_t *result) - { - error_t err; - error_t ctty_open (file_t port) - { - if (port == MACH_PORT_NULL) - return ENXIO; /* No controlling terminal. */ - return __termctty_open_terminal (port, - flags, - result); - } - err = (*use_init_port) (INIT_PORT_CTTYID, &ctty_open); - if (! err) - err = reauthenticate (*result); - return err; - } - - case '\0': - return opentty (result); - case '/': - if (err = opentty (&startdir)) - return err; - strcpy (retryname, &retryname[4]); - break; - default: - goto bad_magic; - } - else - goto bad_magic; - break; - - default: - bad_magic: - return EGRATUITOUS; - } - break; - - default: - return EGRATUITOUS; - } - - if (startdir != MACH_PORT_NULL) - { - err = lookup_op (startdir); - __mach_port_deallocate (__mach_task_self (), startdir); - startdir = MACH_PORT_NULL; - } - else - err = (*use_init_port) (dirport, &lookup_op); - } while (! err); - - return err; -} -weak_alias (__hurd_file_name_lookup_retry, hurd_file_name_lookup_retry) diff --git a/hurd/msgportdemux.c b/hurd/msgportdemux.c deleted file mode 100644 index 05f7117014..0000000000 --- a/hurd/msgportdemux.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Demux messages sent on the signal port. - Copyright (C) 1991-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/>. */ - -#include <hurd.h> -#include <hurd/signal.h> -#include <stddef.h> - -struct demux - { - struct demux *next; - boolean_t (*demux) (mach_msg_header_t *inp, - mach_msg_header_t *outp); - }; - -struct demux *_hurd_msgport_demuxers = NULL; - -extern boolean_t __msg_server (mach_msg_header_t *inp, - mach_msg_header_t *outp); - -static boolean_t -msgport_server (mach_msg_header_t *inp, - mach_msg_header_t *outp) -{ - extern boolean_t _S_msg_server (mach_msg_header_t *inp, - mach_msg_header_t *outp); - extern boolean_t _S_exc_server (mach_msg_header_t *inp, - mach_msg_header_t *outp); - struct demux *d; - - for (d = _hurd_msgport_demuxers; d != NULL; d = d->next) - if ((*d->demux) (inp, outp)) - return 1; - - return (_S_exc_server (inp, outp) || - _S_msg_server (inp, outp)); -} - -/* This is the code that the signal thread runs. */ -void -_hurd_msgport_receive (void) -{ - /* Get our own sigstate cached so we never again have to take a lock to - fetch it. There is much code in hurdsig.c that operates with some - sigstate lock held, which will deadlock with _hurd_thread_sigstate. - - Furthermore, in the cthreads case this is the convenient spot - to initialize _hurd_msgport_thread (see hurdsig.c:_hurdsig_init). */ - - _hurd_msgport_thread = _hurd_self_sigstate ()->thread; - - while (1) - (void) __mach_msg_server (msgport_server, __vm_page_size, _hurd_msgport); -} diff --git a/hurd/new-fd.c b/hurd/new-fd.c deleted file mode 100644 index 9ea95bbf38..0000000000 --- a/hurd/new-fd.c +++ /dev/null @@ -1,41 +0,0 @@ -/* 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/>. */ - -#include <hurd/fd.h> -#include <stdlib.h> -#include "hurdmalloc.h" /* XXX */ - -/* Allocate a new file descriptor structure - and initialize it with PORT and CTTY. */ - -struct hurd_fd * -_hurd_new_fd (io_t port, io_t ctty) -{ - struct hurd_fd *d = malloc (sizeof (struct hurd_fd)); - - if (d != NULL) - { - /* Initialize the port cells. */ - _hurd_port_init (&d->port, port); - _hurd_port_init (&d->ctty, ctty); - - /* And the fcntl flags. */ - d->flags = 0; - } - - return d; -} diff --git a/hurd/openport.c b/hurd/openport.c deleted file mode 100644 index da889f7225..0000000000 --- a/hurd/openport.c +++ /dev/null @@ -1,28 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/fd.h> - -/* User entry point for interning a port as a new FD. - Just like _hurd_intern_fd, but don't dealloc PORT on error. */ - -int -openport (io_t port, int flags) -{ - return _hurd_intern_fd (port, flags, 0); -} diff --git a/hurd/path-lookup.c b/hurd/path-lookup.c deleted file mode 100644 index f2061b0bff..0000000000 --- a/hurd/path-lookup.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Filename lookup using a search path - Copyright (C) 1995-2017 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader <miles@gnu.ai.mit.edu> - - 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/>. */ - -#include <string.h> -#include <hurd.h> -#include <hurd/lookup.h> - -/* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and - return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to - NULL). Otherwise, call FUN repeatedly with FILE_NAME prefixed with each - successive `:' separated element of PATH, returning whenever FUN returns - 0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting - prefixed path). If FUN never returns 0, return the first non-ENOENT - return value, or ENOENT if there is none. */ -error_t -file_name_path_scan (const char *file_name, const char *path, - error_t (*fun)(const char *name), - char **prefixed_name) -{ - if (path == NULL || strchr (file_name, '/')) - { - if (prefixed_name) - *prefixed_name = 0; - return (*fun)(file_name); - } - else - { - error_t real_err = 0; - size_t file_name_len = strlen (file_name); - - for (;;) - { - error_t err; - const char *next = strchr (path, ':') ?: path + strlen (path); - size_t pfx_len = next - path; - char pfxed_name[pfx_len + 2 + file_name_len + 1]; - - if (pfx_len == 0) - pfxed_name[pfx_len++] = '.'; - else - memcpy (pfxed_name, path, pfx_len); - if (pfxed_name[pfx_len - 1] != '/') - pfxed_name[pfx_len++] = '/'; - memcpy (pfxed_name + pfx_len, file_name, file_name_len + 1); - - err = (*fun)(pfxed_name); - if (err == 0) - { - if (prefixed_name) - *prefixed_name = strdup (pfxed_name); - return 0; - } - if (!real_err && err != ENOENT) - real_err = err; - - if (*next == '\0') - return real_err ?: ENOENT; - else - path = next + 1; - } - } -} - -/* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result - (see hurd_file_name_lookup for details), but a simple filename (without - any directory prefixes) will be 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) -{ - error_t scan_lookup (const char *name) - { - return - __hurd_file_name_lookup (use_init_port, get_dtable_port, lookup, - name, flags, mode, result); - } - return file_name_path_scan (file_name, path, scan_lookup, prefixed_name); -} - -file_t -file_name_path_lookup (const char *file_name, const char *path, - int flags, mode_t mode, char **prefixed_name) -{ - error_t err; - file_t result; - - err = hurd_file_name_path_lookup (&_hurd_ports_use, &__getdport, 0, - file_name, path, flags, mode, - &result, prefixed_name); - - return err ? (__hurd_fail (err), MACH_PORT_NULL) : result; -} diff --git a/hurd/pid2task.c b/hurd/pid2task.c deleted file mode 100644 index 5fd2de53c0..0000000000 --- a/hurd/pid2task.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> - -task_t -__pid2task (pid_t pid) -{ - error_t err; - task_t task; - - err = __USEPORT (PROC, __proc_pid2task (port, pid, &task)); - - return err ? (__hurd_fail (err), MACH_PORT_NULL) : task; -} - -weak_alias (__pid2task, pid2task) diff --git a/hurd/port-cleanup.c b/hurd/port-cleanup.c deleted file mode 100644 index 6dbd117980..0000000000 --- a/hurd/port-cleanup.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Cleanup function for `struct hurd_port' users who longjmp. - 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/>. */ - -#include <mach.h> -#include <hurd/port.h> - -/* The last user of the send right CLEANUP_DATA is now doing - `longjmp (ENV, VAL)', and this will unwind the frame of - that last user. Deallocate the right he will never get back to using. */ - -void -_hurd_port_cleanup (void *cleanup_data, jmp_buf env, int val) -{ - __mach_port_deallocate (__mach_task_self (), (mach_port_t) cleanup_data); -} diff --git a/hurd/port2fd.c b/hurd/port2fd.c deleted file mode 100644 index 83e7b9c47e..0000000000 --- a/hurd/port2fd.c +++ /dev/null @@ -1,63 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/fd.h> -#include <hurd/signal.h> -#include <hurd/term.h> -#include <fcntl.h> - -/* Store PORT in file descriptor D, doing appropriate ctty magic. - FLAGS are as for `open'; only O_IGNORE_CTTY and O_CLOEXEC are meaningful. - D should be locked, and will not be unlocked. */ - -void -_hurd_port2fd (struct hurd_fd *d, io_t dport, int flags) -{ - mach_port_t cttyid; - io_t ctty = MACH_PORT_NULL; - - if (!(flags & O_IGNORE_CTTY)) - __USEPORT (CTTYID, - ({ - if (port != MACH_PORT_NULL && /* Do we have a ctty? */ - ! __term_getctty (dport, &cttyid)) /* Could this be it? */ - { - __mach_port_deallocate (__mach_task_self (), cttyid); - /* This port is capable of being a controlling tty. - Is it ours? */ - if (cttyid == port) - __term_open_ctty (dport, _hurd_pid, _hurd_pgrp, &ctty); - /* XXX if this port is our ctty, but we are not doing - ctty style i/o because term_become_ctty barfed, - what to do? */ - } - 0; - })); - - /* Install PORT in the descriptor cell, leaving it locked. */ - { - mach_port_t old - = _hurd_userlink_clear (&d->port.users) ? d->port.port : MACH_PORT_NULL; - d->port.port = dport; - d->flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0; - if (old != MACH_PORT_NULL) - __mach_port_deallocate (__mach_task_self (), old); - } - - _hurd_port_set (&d->ctty, ctty); -} diff --git a/hurd/ports-get.c b/hurd/ports-get.c deleted file mode 100644 index 0735ac59b1..0000000000 --- a/hurd/ports-get.c +++ /dev/null @@ -1,45 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> - -static error_t -getbootstrap (mach_port_t *result) -{ - return __task_get_special_port (__mach_task_self (), - TASK_BOOTSTRAP_PORT, - result); -} - -error_t (*_hurd_ports_getters[INIT_PORT_MAX]) (mach_port_t *result) = - { - [INIT_PORT_BOOTSTRAP] = getbootstrap, - }; - -error_t -_hurd_ports_get (unsigned int which, mach_port_t *result) -{ - if (which >= _hurd_nports) - return EINVAL; - if (which >= INIT_PORT_MAX || _hurd_ports_getters[which] == NULL) - return HURD_PORT_USE (&_hurd_ports[which], - (*result = port) == MACH_PORT_NULL ? 0 - : __mach_port_mod_refs (__mach_task_self (), - port, MACH_PORT_RIGHT_SEND, - +1)); - return (*_hurd_ports_getters[which]) (result); -} diff --git a/hurd/ports-set.c b/hurd/ports-set.c deleted file mode 100644 index 30d47a4281..0000000000 --- a/hurd/ports-set.c +++ /dev/null @@ -1,56 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> - -static error_t -setbootstrap (mach_port_t newport) -{ - return __task_set_special_port (__mach_task_self (), - TASK_BOOTSTRAP_PORT, - newport); -} - -extern error_t _hurd_setauth (auth_t); -extern error_t _hurd_setproc (process_t); -extern error_t _hurd_setcttyid (mach_port_t); - -error_t (*_hurd_ports_setters[INIT_PORT_MAX]) (mach_port_t newport) = - { - [INIT_PORT_BOOTSTRAP] = setbootstrap, - [INIT_PORT_AUTH] = _hurd_setauth, - [INIT_PORT_PROC] = _hurd_setproc, - [INIT_PORT_CTTYID] = _hurd_setcttyid, - }; - - -error_t -_hurd_ports_set (unsigned int which, mach_port_t newport) -{ - error_t err; - if (which >= _hurd_nports) - return EINVAL; - if (err = __mach_port_mod_refs (__mach_task_self (), newport, - MACH_PORT_RIGHT_SEND, 1)) - return err; - if (which >= INIT_PORT_MAX || _hurd_ports_setters[which] == NULL) - { - _hurd_port_set (&_hurd_ports[which], newport); - return 0; - } - return (*_hurd_ports_setters[which]) (newport); -} diff --git a/hurd/preempt-sig.c b/hurd/preempt-sig.c deleted file mode 100644 index 81c4e905b4..0000000000 --- a/hurd/preempt-sig.c +++ /dev/null @@ -1,67 +0,0 @@ -/* 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/>. */ - -#include <hurd/sigpreempt.h> -#include <hurd/signal.h> -#include <assert.h> - -void -hurd_preempt_signals (struct hurd_signal_preemptor *preemptor) -{ - __mutex_lock (&_hurd_siglock); - preemptor->next = _hurdsig_preemptors; - _hurdsig_preemptors = preemptor; - _hurdsig_preempted_set |= preemptor->signals; - __mutex_unlock (&_hurd_siglock); -} - -void -hurd_unpreempt_signals (struct hurd_signal_preemptor *preemptor) -{ - struct hurd_signal_preemptor **p; - sigset_t preempted = 0; - - __mutex_lock (&_hurd_siglock); - - p = &_hurdsig_preemptors; - while (*p) - if (*p == preemptor) - { - /* Found it; take it off the chain. */ - *p = (*p)->next; - if ((preemptor->signals & preempted) != preemptor->signals) - { - /* This might have been the only preemptor for some - of those signals, so we must collect the full mask - from the others. */ - struct hurd_signal_preemptor *pp; - for (pp = *p; pp; pp = pp->next) - preempted |= pp->signals; - _hurdsig_preempted_set = preempted; - } - __mutex_unlock (&_hurd_siglock); - return; - } - else - { - preempted |= (*p)->signals; - p = &(*p)->next; - } - - __mutex_unlock (&_hurd_siglock); /* Avoid deadlock during death rattle. */ - assert (! "removing absent preemptor"); -} diff --git a/hurd/privports.c b/hurd/privports.c deleted file mode 100644 index 90467883a6..0000000000 --- a/hurd/privports.c +++ /dev/null @@ -1,70 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> - -/* The program might set these if it is the initial task - bootstrapped by the microkernel. */ - -mach_port_t _hurd_host_priv, _hurd_device_master; - - -kern_return_t -__get_privileged_ports (mach_port_t *host_priv_ptr, - device_t *device_master_ptr) -{ - if ((host_priv_ptr && _hurd_host_priv == MACH_PORT_NULL) - || (device_master_ptr && _hurd_device_master == MACH_PORT_NULL)) - { - error_t err; - - if (_hurd_ports) - /* We have gotten some initial ports, so perhaps - we have a proc server to talk to. */ - err = __USEPORT (PROC, __proc_getprivports (port, - &_hurd_host_priv, - &_hurd_device_master)); - else - return MACH_SEND_INVALID_DEST; - - if (err) - return err; - } - - if (host_priv_ptr) - { - error_t err = _hurd_host_priv == MACH_PORT_NULL ? 0 - : __mach_port_mod_refs (mach_task_self (), - _hurd_host_priv, MACH_PORT_RIGHT_SEND, +1); - if (err) - return err; - *host_priv_ptr = _hurd_host_priv; - } - - if (device_master_ptr) - { - error_t err = _hurd_device_master == MACH_PORT_NULL ? 0 - : __mach_port_mod_refs (mach_task_self (), - _hurd_device_master, MACH_PORT_RIGHT_SEND, +1); - if (err) - return err; - *device_master_ptr = _hurd_device_master; - } - - return KERN_SUCCESS; -} -weak_alias (__get_privileged_ports, get_privileged_ports) diff --git a/hurd/report-wait.c b/hurd/report-wait.c deleted file mode 100644 index 92e8aba71c..0000000000 --- a/hurd/report-wait.c +++ /dev/null @@ -1,243 +0,0 @@ -/* Report on what a thread in our task is waiting for. - 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/>. */ - -#include <hurd.h> -#include <hurd/signal.h> -#include <hurd/fd.h> -#include <string.h> -#include <assert.h> -#include <hurd/msg_server.h> -#include <thread_state.h> -#include <intr-msg.h> - -static char * -describe_number (string_t description, const char *flavor, long int i) -{ - unsigned long int j; - char *p = flavor == NULL ? description : __stpcpy (description, flavor); - char *end; - - /* Handle sign. */ - if (i < 0) - { - i = -i; - *p++ = '-'; - } - - /* Allocate space for the number at the end of DESCRIPTION. */ - for (j = i; j >= 10; j /= 10) - p++; - end = p + 1; - *end = '\0'; - - do - { - *p-- = '0' + i % 10; - i /= 10; - } while (i != 0); - - return end; -} - -static char * -describe_port (string_t description, mach_port_t port) -{ - int i; - - if (port == MACH_PORT_NULL) - return __stpcpy (description, "(null)"); - if (port == MACH_PORT_DEAD) - return __stpcpy (description, "(dead)"); - - if (port == __mach_task_self ()) - return __stpcpy (description, "task-self"); - - for (i = 0; i < _hurd_nports; ++i) - if (port == _hurd_ports[i].port) - return describe_number (description, "init#", i); - - if (_hurd_init_dtable) - { - for (i = 0; i < _hurd_init_dtablesize; ++i) - if (port == _hurd_init_dtable[i]) - return describe_number (description, "fd#", i); - } - else if (_hurd_dtable) - { - for (i = 0; i < _hurd_dtablesize; ++i) - if (_hurd_dtable[i] == NULL) - continue; - else if (port == _hurd_dtable[i]->port.port) - return describe_number (description, "fd#", i); - else if (port == _hurd_dtable[i]->ctty.port) - return describe_number (description, "bgfd#", i); - } - - return describe_number (description, "port#", port); -} - - -/* We want _HURD_ITIMER_THREAD, but don't want to link in the itimer code - unnecessarily. */ -#if 0 /* libc.so.0.0 needs this defined, so make it a weak alias for now. */ -extern thread_t _hurd_itimer_thread; /* XXX */ -weak_extern (_hurd_itimer_thread) -#else -static thread_t default_hurd_itimer_thread; -weak_alias (default_hurd_itimer_thread, _hurd_itimer_thread) -#endif - -kern_return_t -_S_msg_report_wait (mach_port_t msgport, thread_t thread, - string_t description, mach_msg_id_t *msgid) -{ - *msgid = 0; - - if (thread == _hurd_msgport_thread) - /* Cute. */ - strcpy (description, "msgport"); - else if (&_hurd_itimer_thread && thread == _hurd_itimer_thread) - strcpy (description, "itimer"); - else - { - /* Make sure this is really one of our threads. */ - - struct hurd_sigstate *ss; - - __mutex_lock (&_hurd_siglock); - for (ss = _hurd_sigstates; ss != NULL; ss = ss->next) - if (ss->thread == thread) - break; - __mutex_unlock (&_hurd_siglock); - if (ss == NULL) - /* To hell with you. */ - return EINVAL; - - if (ss->suspended != MACH_PORT_NULL) - strcpy (description, "sigsuspend"); - else - { - /* Examine the thread's state to see if it is blocked in an RPC. */ - - struct machine_thread_state state; - mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT; - error_t err; - - err = __thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR, - (natural_t *) &state, &count); - if (err) - return err; - assert (count == MACHINE_THREAD_STATE_COUNT); - if (SYSCALL_EXAMINE (&state, msgid)) - { - mach_port_t send_port, rcv_port; - mach_msg_option_t option; - mach_msg_timeout_t timeout; - - /* Blocked in a system call. */ - if (*msgid == -25 - /* mach_msg system call. Examine its parameters. */ - && MSG_EXAMINE (&state, msgid, &send_port, &rcv_port, - &option, &timeout) == 0) - { - char *p; - if (send_port != MACH_PORT_NULL && *msgid != 0) - { - /* For the normal case of RPCs, we consider the - destination port to be the interesting thing - whether we are in fact sending or receiving at the - moment. That tells us who we are waiting for the - reply from. */ - if (send_port == ss->intr_port) - { - /* This is a Hurd interruptible RPC. - Mark it by surrounding the port description - string with [...] brackets. */ - description[0] = '['; - p = describe_port (description + 1, send_port); - *p++ = ']'; - *p = '\0'; - } - else - (void) describe_port (description, send_port); - } - else if (rcv_port != MACH_PORT_NULL) - { - /* This system call had no send port, but had a - receive port. The msgid we extracted is then just - some garbage or perhaps the msgid of the last - message this thread received, but it's not a - helpful thing to return. */ - strcpy (describe_port (description, rcv_port), ":rcv"); - *msgid = 0; - } - else if ((option & (MACH_RCV_MSG|MACH_RCV_TIMEOUT)) - == (MACH_RCV_MSG|MACH_RCV_TIMEOUT)) - { - /* A receive with no valid port can be used for a - pure timeout. Report the timeout value (counted - in milliseconds); note this is the original total - time, not the time remaining. */ - strcpy (describe_number (description, 0, timeout), "ms"); - *msgid = 0; - } - else - { - strcpy (description, "mach_msg"); - *msgid = 0; - } - } - else /* Some other system call. */ - { - (void) describe_number (description, "syscall#", *msgid); - *msgid = 0; - } - } - else - description[0] = '\0'; - } - } - - __mach_port_deallocate (__mach_task_self (), thread); - return 0; -} - -kern_return_t -_S_msg_describe_ports (mach_port_t msgport, mach_port_t refport, - mach_port_t *ports, mach_msg_type_number_t nports, - char **desc, mach_msg_type_number_t *desclen) -{ - char *p, *end; - - if (__USEPORT (AUTH, msgport != port)) - return EPERM; - - end = *desc + *desclen; - p = *desc; - while (nports-- > 0) - { - char this[200]; - describe_port (this, *ports++); - p = __stpncpy (p, this, end - p); - if (p == end && p[-1] != '\0') - return ENOMEM; - } - - *desclen = p - *desc; - return 0; -} diff --git a/hurd/set-host.c b/hurd/set-host.c deleted file mode 100644 index e302d71fb7..0000000000 --- a/hurd/set-host.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Set a host configuration item kept as the whole contents of a file. - 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/>. */ - -#include <fcntl.h> -#include <hurd.h> -#include "hurdhost.h" - -ssize_t -_hurd_set_host_config (const char *item, const char *value, size_t valuelen) -{ - error_t err; - mach_msg_type_number_t nwrote; - file_t new, dir; - char *name; - - dir = __file_name_split (item, &name); - if (dir == MACH_PORT_NULL) - return -1; - - /* Create a new node. */ - err = __dir_mkfile (dir, O_WRONLY, 0644, &new); - if (! err) - { - /* Write the contents. */ - err = __io_write (new, value, valuelen, 0, &nwrote); - if (! err) - /* Atomically link the new node onto the name. */ - err = __dir_link (dir, new, name, 0); - __mach_port_deallocate (__mach_task_self (), new); - } - __mach_port_deallocate (__mach_task_self (), dir); - - return err ? __hurd_fail (err) : nwrote; -} diff --git a/hurd/setauth.c b/hurd/setauth.c deleted file mode 100644 index 77bf7ee741..0000000000 --- a/hurd/setauth.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> -#include <hurd/port.h> -#include <hurd/id.h> -#include "set-hooks.h" - -/* Things in the library which want to be run when the auth port changes. */ -DEFINE_HOOK (_hurd_reauth_hook, (auth_t new_auth)); - -#include <cthreads.h> -static struct mutex reauth_lock = MUTEX_INITIALIZER; - - -/* Set the auth port to NEW, and reauthenticate - everything used by the library. */ -error_t -_hurd_setauth (auth_t new) -{ - error_t err; - unsigned int d; - mach_port_t newport, ref; - - /* Give the new send right a user reference. - This is a good way to check that it is valid. */ - if (err = __mach_port_mod_refs (__mach_task_self (), new, - MACH_PORT_RIGHT_SEND, 1)) - return err; - - HURD_CRITICAL_BEGIN; - - /* We lock against another thread doing setauth. Anyone who sets - _hurd_ports[INIT_PORT_AUTH] some other way is asking to lose. */ - __mutex_lock (&reauth_lock); - - /* Install the new port in the cell. */ - __mutex_lock (&_hurd_id.lock); - _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], new); - _hurd_id.valid = 0; - if (_hurd_id.rid_auth) - { - __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth); - _hurd_id.rid_auth = MACH_PORT_NULL; - } - __mutex_unlock (&_hurd_id.lock); - - if (_hurd_init_dtable != NULL) - /* We just have the simple table we got at startup. - Otherwise, a reauth_hook in dtable.c takes care of this. */ - for (d = 0; d < _hurd_init_dtablesize; ++d) - if (_hurd_init_dtable[d] != MACH_PORT_NULL) - { - mach_port_t new; - ref = __mach_reply_port (); - if (! __io_reauthenticate (_hurd_init_dtable[d], - ref, MACH_MSG_TYPE_MAKE_SEND) && - ! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH], - __auth_user_authenticate - (port, - ref, MACH_MSG_TYPE_MAKE_SEND, - &new))) - { - __mach_port_deallocate (__mach_task_self (), - _hurd_init_dtable[d]); - _hurd_init_dtable[d] = new; - } - __mach_port_destroy (__mach_task_self (), ref); - } - - ref = __mach_reply_port (); - if (__USEPORT (CRDIR, - ! __io_reauthenticate (port, - ref, MACH_MSG_TYPE_MAKE_SEND) && - ! __auth_user_authenticate (new, - ref, MACH_MSG_TYPE_MAKE_SEND, - &newport))) - _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport); - __mach_port_destroy (__mach_task_self (), ref); - - ref = __mach_reply_port (); - if (__USEPORT (CWDIR, - ! __io_reauthenticate (port, - ref, MACH_MSG_TYPE_MAKE_SEND) && - ! __auth_user_authenticate (new, - ref, MACH_MSG_TYPE_MAKE_SEND, - &newport))) - _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport); - __mach_port_destroy (__mach_task_self (), ref); - - /* Run things which want to do reauthorization stuff. */ - RUN_HOOK (_hurd_reauth_hook, (new)); - - __mutex_unlock (&reauth_lock); - - HURD_CRITICAL_END; - - return 0; -} - -int -__setauth (auth_t new) -{ - error_t err = _hurd_setauth (new); - return err ? __hurd_fail (err) : 0; -} - -weak_alias (__setauth, setauth) diff --git a/hurd/seteuids.c b/hurd/seteuids.c deleted file mode 100644 index edefdf9c12..0000000000 --- a/hurd/seteuids.c +++ /dev/null @@ -1,58 +0,0 @@ -/* 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/>. */ - -#include <hurd.h> -#include <hurd/id.h> - -/* Set the uid set for the current user to UIDS (N of them). */ -int -seteuids (int n, const uid_t *uids) -{ - error_t err; - auth_t newauth; - int i; - gid_t new[n]; - - /* Fault before taking locks. */ - for (i = 0; i < n; ++i) - new[i] = uids[i]; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_id.lock); - err = _hurd_check_ids (); - if (! err) - { - /* Get a new auth port using those IDs. */ - err = __USEPORT (AUTH, - __auth_makeauth (port, NULL, 0, 0, - new, n, - _hurd_id.aux.uids, _hurd_id.aux.nuids, - _hurd_id.gen.gids, _hurd_id.gen.ngids, - _hurd_id.aux.gids, _hurd_id.aux.ngids, - &newauth)); - } - __mutex_unlock (&_hurd_id.lock); - HURD_CRITICAL_END; - - if (err) - return __hurd_fail (err); - - /* Install the new auth port and reauthenticate everything. */ - err = __setauth (newauth); - __mach_port_deallocate (__mach_task_self (), newauth); - return err; -} diff --git a/hurd/siginfo.c b/hurd/siginfo.c deleted file mode 100644 index 1db042e4d8..0000000000 --- a/hurd/siginfo.c +++ /dev/null @@ -1,26 +0,0 @@ -/* 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/>. */ - -#include <hurd/signal.h> -#include <stdio.h> - -void -_hurd_siginfo_handler (int signo) -{ - /* XXX */ - puts ("got a SIGINFO"); -} diff --git a/hurd/sigunwind.c b/hurd/sigunwind.c deleted file mode 100644 index 8025599665..0000000000 --- a/hurd/sigunwind.c +++ /dev/null @@ -1,149 +0,0 @@ -/* longjmp cleanup function for unwinding past signal handlers. - 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/>. */ - -#include <hurd.h> -#include <thread_state.h> -#include <jmpbuf-unwind.h> -#include <assert.h> -#include <stdint.h> - - -/* _hurd_setup_sighandler puts a link on the `active resources' chain so that - _longjmp_unwind will call this function with the `struct sigcontext *' - describing the context interrupted by the signal, when `longjmp' is jumping - to an environment that unwinds past the interrupted frame. */ - -void -_hurdsig_longjmp_from_handler (void *data, jmp_buf env, int val) -{ - struct sigcontext *scp = data; - struct hurd_sigstate *ss = _hurd_self_sigstate (); - int onstack; - inline void cleanup (void) - { - /* Destroy the MiG reply port used by the signal handler, and restore - the reply port in use by the thread when interrupted. */ - mach_port_t *reply_port = - (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY); - if (*reply_port) - { - mach_port_t port = *reply_port; - /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port - not to get another reply port, but avoids mig_dealloc_reply_port - trying to deallocate it after the receive fails (which it will, - because the reply port will be bogus, regardless). */ - *reply_port = MACH_PORT_DEAD; - __mach_port_destroy (__mach_task_self (), port); - } - if (scp->sc_reply_port) - __mach_port_destroy (__mach_task_self (), scp->sc_reply_port); - } - - __spin_lock (&ss->lock); - /* We should only ever be called from _longjmp_unwind (in jmp-unwind.c), - which calls us inside a critical section. */ - assert (__spin_lock_locked (&ss->critical_section_lock)); - /* Are we on the alternate signal stack now? */ - onstack = (ss->sigaltstack.ss_flags & SS_ONSTACK); - __spin_unlock (&ss->lock); - - if (onstack && ! scp->sc_onstack) - { - /* We are unwinding off the signal stack. We must use sigreturn to - do it robustly. Mutate the sigcontext so that when sigreturn - resumes from that context, it will be as if `__longjmp (ENV, VAL)' - were done. */ - - struct hurd_userlink *link; - - inline uintptr_t demangle_ptr (uintptr_t x) - { -# ifdef PTR_DEMANGLE - PTR_DEMANGLE (x); -# endif - return x; - } - - /* Continue _longjmp_unwind's job of running the unwind - forms for frames being unwound, since we will not - return to its loop like this one, which called us. */ - for (link = ss->active_resources; - link && _JMPBUF_UNWINDS (env[0].__jmpbuf, link, demangle_ptr); - link = link->thread.next) - if (_hurd_userlink_unlink (link)) - { - if (link->cleanup == &_hurdsig_longjmp_from_handler) - { - /* We are unwinding past another signal handler invocation. - Just finish the cleanup for this (inner) one, and then - swap SCP to restore to the outer context. */ - cleanup (); - scp = link->cleanup_data; - } - else - (*link->cleanup) (link->cleanup_data, env, val); - } - -#define sc_machine_thread_state paste(sc_,machine_thread_state) -#define paste(a,b) paste1(a,b) -#define paste1(a,b) a##b - - /* There are no more unwind forms to be run! - Now we can just have the sigreturn do the longjmp for us. */ - _hurd_longjmp_thread_state - ((struct machine_thread_state *) &scp->sc_machine_thread_state, - env, val); - - /* Restore to the same current signal mask. If sigsetjmp saved the - mask, longjmp has already restored it as desired; if not, we - should leave it as it is. */ - scp->sc_mask = ss->blocked; - - /* sigreturn expects the link added by _hurd_setup_sighandler - to still be there, but _longjmp_unwind removed it just before - calling us. Put it back now so sigreturn can find it. */ - link = (void *) &scp[1]; - assert (! link->resource.next && ! link->resource.prevp); - assert (link->thread.next == ss->active_resources); - assert (link->thread.prevp == &ss->active_resources); - if (link->thread.next) - link->thread.next->thread.prevp = &link->thread.next; - ss->active_resources = link; - - /* We must momentarily exit the critical section so that sigreturn - does not get upset with us. But we don't want signal handlers - running right now, because we are presently in the bogus state of - having run all the unwind forms back to ENV's frame, but our SP is - still inside those unwound frames. */ - __spin_lock (&ss->lock); - __spin_unlock (&ss->critical_section_lock); - ss->blocked = ~(sigset_t) 0 & ~_SIG_CANT_MASK; - __spin_unlock (&ss->lock); - - /* Restore to the modified signal context that now - performs `longjmp (ENV, VAL)'. */ - __sigreturn (scp); - assert (! "sigreturn returned!"); - } - - /* We are not unwinding off the alternate signal stack. So nothing - really funny is going on here. We can just clean up this handler - frame and let _longjmp_unwind continue unwinding. */ - cleanup (); - ss->intr_port = scp->sc_intr_port; -} diff --git a/hurd/task2pid.c b/hurd/task2pid.c deleted file mode 100644 index 86c5c659f8..0000000000 --- a/hurd/task2pid.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <hurd.h> - -pid_t -__task2pid (task_t task) -{ - error_t err; - pid_t pid; - err = __USEPORT (PROC, __proc_task2pid (port, task, &pid)); - return err ? (pid_t) __hurd_fail (err) : pid; -} - -weak_alias (__task2pid, task2pid) diff --git a/hurd/thread-cancel.c b/hurd/thread-cancel.c deleted file mode 100644 index 722b6adc74..0000000000 --- a/hurd/thread-cancel.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Thread cancellation support. - 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/>. */ - -#include <hurd/signal.h> -#include <hurd/interrupt.h> -#include <assert.h> -#include <thread_state.h> - - -/* See hurdsig.c. */ -extern mach_port_t _hurdsig_abort_rpcs (struct hurd_sigstate *ss, - int signo, int sigthread, - struct machine_thread_all_state *, - int *state_change, - mach_port_t *reply_port, - mach_msg_type_name_t reply_port_type, - int untraced); - -error_t -hurd_thread_cancel (thread_t thread) -{ - struct hurd_sigstate *ss = _hurd_thread_sigstate (thread); - struct machine_thread_all_state state; - int state_change; - error_t err; - - if (! ss) - return EINVAL; - if (ss == _hurd_self_sigstate ()) - { - /* We are cancelling ourselves, so it is easy to succeed - quickly. Since this function is not a cancellation point, we - just leave the flag set pending the next cancellation point - (hurd_check_cancel or RPC) and return success. */ - ss->cancel = 1; - return 0; - } - - assert (! __spin_lock_locked (&ss->critical_section_lock)); - __spin_lock (&ss->critical_section_lock); - __spin_lock (&ss->lock); - err = __thread_suspend (thread); - __spin_unlock (&ss->lock); - - if (! err) - { - /* Set the flag telling the thread its operation is being cancelled. */ - ss->cancel = 1; - - /* Interrupt any interruptible RPC now in progress. */ - state.set = 0; - _hurdsig_abort_rpcs (ss, 0, 0, &state, &state_change, NULL, 0, 0); - if (state_change) - err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR, - (natural_t *) &state.basic, - MACHINE_THREAD_STATE_COUNT); - - if (ss->cancel_hook) - /* The code being cancelled has a special wakeup function. - Calling this should make the thread wake up and check the - cancellation flag. */ - (*ss->cancel_hook) (); - - __thread_resume (thread); - } - - _hurd_critical_section_unlock (ss); - return err; -} - - -int -hurd_check_cancel (void) -{ - struct hurd_sigstate *ss = _hurd_self_sigstate (); - int cancel; - - __spin_lock (&ss->lock); - assert (! __spin_lock_locked (&ss->critical_section_lock)); - cancel = ss->cancel; - ss->cancel = 0; - __spin_unlock (&ss->lock); - - return cancel; -} diff --git a/hurd/thread-self.c b/hurd/thread-self.c deleted file mode 100644 index 3532caff91..0000000000 --- a/hurd/thread-self.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Cheap function to get current thread from sigstate without a syscall. - 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/>. */ - -#include <hurd/signal.h> - -thread_t -hurd_thread_self (void) -{ - return _hurd_self_sigstate ()->thread; -} diff --git a/hurd/trampoline.c b/hurd/trampoline.c deleted file mode 100644 index e506fd8c96..0000000000 --- a/hurd/trampoline.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Set thread_state for sighandler, and sigcontext to recover. Stub version. - 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/>. */ - -#include <hurd.h> -#include <mach/thread_status.h> - -/* Set up STATE to run a signal handler in the thread it describes. - This should save the original state in a `struct sigcontext' on the - thread's stack (or possibly a signal stack described by SIGALTSTACK, - if the SA_ONSTACK bit is set in FLAGS), and return the address of - that structure. */ - -struct sigcontext * -_hurd_setup_sighandler (int flags, - __sighandler_t handler, - stack_t *sigaltstack, - int signo, int sigcode, - void *state) -{ -#error "Need to write sysdeps/mach/hurd/MACHINE/trampoline.c" -} diff --git a/hurd/vpprintf.c b/hurd/vpprintf.c deleted file mode 100644 index 82cdadd5c7..0000000000 --- a/hurd/vpprintf.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (C) 1991-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/>. */ - -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <hurd.h> - -#include <libioP.h> - -static ssize_t -do_write (void *cookie, const char *buf, size_t n) -{ - error_t error = __io_write ((io_t) cookie, buf, n, -1, - (mach_msg_type_number_t *) &n); - if (error) - return __hurd_fail (error); - return n; -} - -/* Write formatted output to PORT, a Mach port supporting the i/o protocol, - according to the format string FORMAT, using the argument list in ARG. */ -int -vpprintf (io_t port, const char *format, va_list arg) -{ - int done; - - struct locked_FILE - { - struct _IO_cookie_file cfile; -#ifdef _IO_MTSAFE_IO - _IO_lock_t lock; -#endif - } temp_f; -#ifdef _IO_MTSAFE_IO - temp_f.cfile.__fp.file._lock = &temp_f.lock; -#endif - - _IO_cookie_init (&temp_f.cfile, _IO_NO_READS, - (void *) port, (cookie_io_functions_t) { write: do_write }); - - done = _IO_vfprintf (&temp_f.cfile.__fp.file, format, arg); - - return done; -} diff --git a/hurd/xattr.c b/hurd/xattr.c deleted file mode 100644 index 7deef291b4..0000000000 --- a/hurd/xattr.c +++ /dev/null @@ -1,200 +0,0 @@ -/* Support for *xattr interfaces on GNU/Hurd. - Copyright (C) 2006-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/>. */ - -#include <hurd.h> -#include <hurd/xattr.h> -#include <string.h> -#include <sys/mman.h> - -/* Right now we support only a fixed set of xattr names for Hurd features. - There are no RPC interfaces for free-form xattr names and values. - - Name Value encoding - ---- ----- -------- - gnu.author empty if st_author==st_uid - uid_t giving st_author value - gnu.translator empty if no passive translator - translator and arguments: "/hurd/foo\0arg1\0arg2\0" -*/ - -error_t -_hurd_xattr_get (io_t port, const char *name, void *value, size_t *size) -{ - if (strncmp (name, "gnu.", 4)) - return EOPNOTSUPP; - name += 4; - - if (!strcmp (name, "author")) - { - struct stat64 st; - error_t err = __io_stat (port, &st); - if (err) - return err; - if (st.st_author == st.st_uid) - *size = 0; - else if (value) - { - if (*size < sizeof st.st_author) - return ERANGE; - memcpy (value, &st.st_author, sizeof st.st_author); - } - *size = sizeof st.st_author; - return 0; - } - - if (!strcmp (name, "translator")) - { - char *buf = value; - size_t bufsz = value ? *size : 0; - error_t err = __file_get_translator (port, &buf, &bufsz); - if (err) - return err; - if (value != NULL && *size < bufsz) - { - if (buf != value) - munmap (buf, bufsz); - return -ERANGE; - } - if (buf != value && bufsz > 0) - { - if (value != NULL) - memcpy (value, buf, bufsz); - munmap (buf, bufsz); - } - *size = bufsz; - return 0; - } - - return EOPNOTSUPP; -} - -error_t -_hurd_xattr_set (io_t port, const char *name, const void *value, size_t size, - int flags) -{ - if (strncmp (name, "gnu.", 4)) - return EOPNOTSUPP; - name += 4; - - if (!strcmp (name, "author")) - switch (size) - { - default: - return EINVAL; - case 0: /* "Clear" author by setting to st_uid. */ - { - struct stat64 st; - error_t err = __io_stat (port, &st); - if (err) - return err; - if (st.st_author == st.st_uid) - { - /* Nothing to do. */ - if (flags & XATTR_REPLACE) - return ENODATA; - return 0; - } - if (flags & XATTR_CREATE) - return EEXIST; - return __file_chauthor (port, st.st_uid); - } - case sizeof (uid_t): /* Set the author. */ - { - uid_t id; - memcpy (&id, value, sizeof id); - if (flags & (XATTR_CREATE|XATTR_REPLACE)) - { - struct stat64 st; - error_t err = __io_stat (port, &st); - if (err) - return err; - if (st.st_author == st.st_uid) - { - if (flags & XATTR_REPLACE) - return ENODATA; - } - else if (flags & XATTR_CREATE) - return EEXIST; - if (st.st_author == id) - /* Nothing to do. */ - return 0; - } - return __file_chauthor (port, id); - } - } - - if (!strcmp (name, "translator")) - { - if (flags & XATTR_REPLACE) - { - /* Must make sure it's already there. */ - char *buf = NULL; - size_t bufsz = 0; - error_t err = __file_get_translator (port, &buf, &bufsz); - if (err) - return err; - if (bufsz > 0) - { - munmap (buf, bufsz); - return ENODATA; - } - } - return __file_set_translator (port, - FS_TRANS_SET | ((flags & XATTR_CREATE) - ? FS_TRANS_EXCL : 0), 0, 0, - value, size, - MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND); - } - - return EOPNOTSUPP; -} - -error_t -_hurd_xattr_remove (io_t port, const char *name) -{ - return _hurd_xattr_set (port, name, NULL, 0, XATTR_REPLACE); -} - -error_t -_hurd_xattr_list (io_t port, void *buffer, size_t *size) -{ - size_t total = 0; - char *bufp = buffer; - inline void add (const char *name, size_t len) - { - total += len; - if (bufp != NULL && total <= *size) - bufp = __mempcpy (bufp, name, len); - } -#define add(s) add (s, sizeof s) - - struct stat64 st; - error_t err = __io_stat (port, &st); - if (err) - return err; - - if (st.st_author != st.st_uid) - add ("gnu.author"); - if (st.st_mode & S_IPTRANS) - add ("gnu.translator"); - - if (buffer != NULL && total > *size) - return ERANGE; - *size = total; - return 0; -} |