diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/mach/hurd/access.c | 5 | ||||
-rw-r--r-- | sysdeps/mach/hurd/errnos.awk | 5 | ||||
-rw-r--r-- | sysdeps/mach/hurd/errnos.h | 2 | ||||
-rw-r--r-- | sysdeps/mach/hurd/fork.c | 6 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/sigreturn.c | 2 | ||||
-rw-r--r-- | sysdeps/mach/hurd/jmp-unwind.c | 5 | ||||
-rw-r--r-- | sysdeps/mach/hurd/kill.c | 2 | ||||
-rw-r--r-- | sysdeps/mach/hurd/ptrace.c | 24 | ||||
-rw-r--r-- | sysdeps/mach/hurd/select.c | 189 | ||||
-rw-r--r-- | sysdeps/mach/hurd/sigaction.c | 8 | ||||
-rw-r--r-- | sysdeps/mach/hurd/sigprocmask.c | 4 | ||||
-rw-r--r-- | sysdeps/mach/hurd/sigsuspend.c | 8 | ||||
-rw-r--r-- | sysdeps/stub/nanosleep.c | 2 |
13 files changed, 131 insertions, 131 deletions
diff --git a/sysdeps/mach/hurd/access.c b/sysdeps/mach/hurd/access.c index 98e2bba3b0..eb57d92f27 100644 --- a/sysdeps/mach/hurd/access.c +++ b/sysdeps/mach/hurd/access.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -44,7 +44,6 @@ DEFUN(__access, (file, type), CONST char *file AND int type) err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND); if (!err) err = __auth_user_authenticate (_hurd_id.rid_auth, - port, ref, MACH_MSG_TYPE_MAKE_SEND, result); err; @@ -106,7 +105,7 @@ DEFUN(__access, (file, type), CONST char *file AND int type) &_hurd_id.rid_auth))) goto lose; } - + if (!err) /* Look up the file name using the modified init ports. */ err = __hurd_file_name_lookup (&init_port, &__getdport, diff --git a/sysdeps/mach/hurd/errnos.awk b/sysdeps/mach/hurd/errnos.awk index 95cfe10da6..e3ff7a843b 100644 --- a/sysdeps/mach/hurd/errnos.awk +++ b/sysdeps/mach/hurd/errnos.awk @@ -23,10 +23,7 @@ # @comment errno 123 BEGIN { - printf "/* This file generated by"; - for (i = 0; i < ARGC; ++i) - printf " %s", ARGV[i]; - printf ". */\n"; + print "/* This file generated by errnos.awk. */"; print ""; print "/* The Hurd uses Mach error system 0x10, currently only subsystem 0. */"; print "#ifndef _HURD_ERRNO"; diff --git a/sysdeps/mach/hurd/errnos.h b/sysdeps/mach/hurd/errnos.h index 31aa3104a5..2ec061596a 100644 --- a/sysdeps/mach/hurd/errnos.h +++ b/sysdeps/mach/hurd/errnos.h @@ -1,4 +1,4 @@ -/* This file generated by gawk ../manual/errno.texi ../../mach/mach/message.h ../../mach/mach/kern_return.h ../../mach/mach/mig_errors.h ../../mach/device/device_types.h. */ +/* This file generated by errnos.awk. */ /* The Hurd uses Mach error system 0x10, currently only subsystem 0. */ #ifndef _HURD_ERRNO diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c index 5814cc2db2..234e377609 100644 --- a/sysdeps/mach/hurd/fork.c +++ b/sysdeps/mach/hurd/fork.c @@ -61,9 +61,7 @@ __fork (void) struct hurd_sigstate *volatile ss; ss = _hurd_self_sigstate (); - __spin_lock (&ss->lock); - ss->critical_section = 1; - __spin_unlock (&ss->lock); + __spin_lock (&ss->critical_section_lock); #undef LOSE #define LOSE assert_perror (err) /* XXX */ @@ -606,7 +604,7 @@ __fork (void) &_hurd_orphaned)); /* Forking clears the trace flag. */ - _hurd_exec_flags &= ~EXEC_TRACED; + __sigemptyset (&_hurdsig_traced); /* Run things that want to run in the child task to set up. */ RUN_HOOK (_hurd_fork_child_hook, ()); diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c index d47b863fe1..7adcadfb52 100644 --- a/sysdeps/mach/hurd/i386/sigreturn.c +++ b/sysdeps/mach/hurd/i386/sigreturn.c @@ -58,7 +58,7 @@ __sigreturn (struct sigcontext *scp) arrange to have us called over again in the new reality. */ ss->context = scp; __spin_unlock (&ss->lock); - __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); /* If a pending signal was handled, sig_post never returned. If it did return, the pending signal didn't run a handler; proceed as usual. */ diff --git a/sysdeps/mach/hurd/jmp-unwind.c b/sysdeps/mach/hurd/jmp-unwind.c index 20ca5f8aa6..fcb09119ce 100644 --- a/sysdeps/mach/hurd/jmp-unwind.c +++ b/sysdeps/mach/hurd/jmp-unwind.c @@ -41,14 +41,15 @@ _longjmp_unwind (jmp_buf env, int val) /* All access to SS->active_resources must take place inside a critical section where signal handlers cannot run. */ __spin_lock (&ss->lock); - assert (! ss->critical_section); - ss->critical_section = 1; + assert (! __spin_lock_locked (&ss->critical_section_lock)); + __spin_lock (&ss->critical_section_lock); /* Remove local signal preempters being unwound past. */ while (ss->preempters && _JMPBUF_UNWINDS (env[0].__jmpbuf, ss->preempters)) ss->preempters = ss->preempters->next; + __spin_unlock (&ss->critical_section_lock); __spin_unlock (&ss->lock); /* Iterate over the current thread's list of active resources. diff --git a/sysdeps/mach/hurd/kill.c b/sysdeps/mach/hurd/kill.c index 1f10613b09..6dcc5b530f 100644 --- a/sysdeps/mach/hurd/kill.c +++ b/sysdeps/mach/hurd/kill.c @@ -65,7 +65,7 @@ __kill (pid_t pid, int sig) { if (msgport != MACH_PORT_NULL) /* Send a signal message to his message port. */ - return __msg_sig_post (msgport, sig, refport); + return __msg_sig_post (msgport, sig, 0, refport); /* The process has no message port. Perhaps try direct frobnication of the task. */ diff --git a/sysdeps/mach/hurd/ptrace.c b/sysdeps/mach/hurd/ptrace.c index f68d3b41ed..24cf9469d5 100644 --- a/sysdeps/mach/hurd/ptrace.c +++ b/sysdeps/mach/hurd/ptrace.c @@ -1,5 +1,5 @@ /* Process tracing interface `ptrace' for GNU Hurd. -Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc. +Copyright (C) 1991, 1992, 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -93,7 +93,7 @@ ptrace (enum __ptrace_request request, ... ) { case PTRACE_TRACEME: /* Make this process be traced. */ - _hurd_exec_flags |= EXEC_TRACED; + __sigfillset (&_hurdsig_traced); __USEPORT (PROC, __proc_mark_traced (port)); break; @@ -144,7 +144,7 @@ ptrace (enum __ptrace_request request, ... ) /* Tell the process to take the signal (or just resume if 0). */ err = HURD_MSGPORT_RPC (__USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)), - 0, 0, __msg_sig_post_untraced (msgport, data, task)); + 0, 0, __msg_sig_post_untraced (msgport, data, 0, task)); } __mach_port_deallocate (__mach_task_self (), task); return err ? __hurd_fail (err) : 0; @@ -178,25 +178,17 @@ ptrace (enum __ptrace_request request, ... ) err = __USEPORT (PROC, __proc_getmsgport (port, pid, &msgport)); if (! err) { - err = (request == PTRACE_ATTACH ? - __msg_set_some_exec_flags : - __msg_clear_some_exec_flags) (msgport, task, EXEC_TRACED); -#ifdef notyet /* XXX */ - if (! err) - /* Request (or request an end to) SIGCHLD notification - when PID stops or dies, and proc_wait working on PID. */ - err = __USEPORT (PROC, - __proc_trace_pid (port, pid, - request == PTRACE_ATTACH)); -#endif + err = __msg_set_init_int (msgport, task, INIT_TRACEMASK, + request == PTRACE_DETACH ? 0 : + ~(sigset_t) 0); if (! err) { if (request == PTRACE_ATTACH) /* Now stop the process. */ - err = __msg_sig_post (msgport, SIGSTOP, task); + err = __msg_sig_post (msgport, SIGSTOP, 0, task); else /* Resume the process from tracing stop. */ - err = __msg_sig_post_untraced (msgport, 0, task); + err = __msg_sig_post_untraced (msgport, 0, 0, task); } __mach_port_deallocate (__mach_task_self (), msgport); } diff --git a/sysdeps/mach/hurd/select.c b/sysdeps/mach/hurd/select.c index 8e78adb1bc..188f65b3c0 100644 --- a/sysdeps/mach/hurd/select.c +++ b/sysdeps/mach/hurd/select.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,6 +22,7 @@ Cambridge, MA 02139, USA. */ #include <hurd/fd.h> #include <stdlib.h> #include <string.h> +#include <assert.h> /* All user select types. */ #define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG) @@ -41,12 +42,8 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), fd_set *exceptfds AND struct timeval *timeout) { int i; - mach_port_t port; + mach_port_t portset; int got; - int *types; - struct hurd_userlink *ulink; - mach_port_t *ports; - struct hurd_fd **cells; error_t err; fd_set rfds, wfds, xfds; int firstfd, lastfd; @@ -54,6 +51,14 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : 0); + struct + { + struct hurd_userlink ulink; + struct hurd_fd *cell; + mach_port_t io_port; + int type; + mach_port_t reply_port; + } d[nfds]; /* Use local copies so we can't crash from user bogosity. */ if (readfds == NULL) @@ -76,10 +81,6 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), nfds = _hurd_dtablesize; /* Collect the ports for interesting FDs. */ - cells = __alloca (nfds * sizeof (*cells)); - ports = __alloca (nfds * sizeof (*ports)); - types = __alloca (nfds * sizeof (*types)); - ulink = __alloca (nfds * sizeof (*ulink)); firstfd = lastfd = -1; for (i = 0; i < nfds; ++i) { @@ -90,16 +91,16 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), type |= SELECT_WRITE; if (exceptfds != NULL && FD_ISSET (i, &xfds)) type |= SELECT_URG; - types[i] = type; + d[i].type = type; if (type) { - cells[i] = _hurd_dtable[i]; - ports[i] = _hurd_port_get (&cells[i]->port, &ulink[i]); - if (ports[i] == MACH_PORT_NULL) + d[i].cell = _hurd_dtable[i]; + d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink); + if (d[i].io_port == MACH_PORT_NULL) { /* If one descriptor is bogus, we fail completely. */ while (i-- > 0) - _hurd_port_free (&cells[i]->port, &ulink[i], ports[i]); + _hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port); errno = EBADF; break; } @@ -115,58 +116,63 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), if (i < nfds) return -1; - /* Get a port to receive the io_select_reply messages on. */ - port = __mach_reply_port (); - /* Send them all io_select request messages. */ - got = 0; err = 0; + got = 0; + portset = MACH_PORT_NULL; for (i = firstfd; i <= lastfd; ++i) - if (types[i]) + if (d[i].type) { - if (!err) + int type = d[i].type; + d[i].reply_port = __mach_reply_port (); + err = __io_select (d[i].io_port, d[i].reply_port, + /* Poll for each but the last. */ + (i == lastfd && got == 0) ? to : 0, + &type); + switch (err) { - int tag = i; - int type = types[i]; - err = __io_select (ports[i], port, - /* Poll for each but the last. */ - (i == lastfd && got == 0) ? to : 0, - &type, &tag); - switch (err) + case MACH_RCV_TIMED_OUT: + /* No immediate response. This is normal. */ + err = 0; + if (got == 0) { - case MACH_RCV_TIMED_OUT: - /* No immediate response. This is normal. */ - err = 0; - break; - - case 0: - /* We got an answer. This is not necessarily the answer to - the query we sent just now. It may correspond to any - prior query which timed out before its answer arrived. */ - if (tag < 0 || tag > i || (type & SELECT_ALL) == 0) - /* This is not a proper answer to any query we have yet - made. */ - err = EGRATUITOUS; - else - { - /* Some port is ready. TAG tells us which. */ - types[tag] &= type; - types[tag] |= SELECT_RETURNED; - ++got; - } - break; - - default: - /* Any other error kills us. - But we must continue to loop to free the ports. */ - break; + /* We will wait again for a reply later. */ + if (portset == MACH_PORT_NULL) + /* Create the portset to receive all the replies on. */ + err = __mach_port_allocate (__mach_task_self (), + MACH_PORT_RIGHT_PORT_SET, + &portset); + if (! err) + /* Put this reply port in the port set. */ + __mach_port_move_member (__mach_task_self (), + d[i].reply_port, portset); } + break; + + default: + /* No other error should happen. Callers of select don't + expect to see errors, so we simulate readiness of the erring + object and the next call hopefully will get the error again. */ + type = SELECT_ALL; + /* FALLTHROUGH */ + + case 0: + /* We got an answer. */ + if ((type & SELECT_ALL) == 0) + /* Bogus answer; treat like an error, as a fake positive. */ + type = SELECT_ALL; + + /* This port is already ready already. */ + d[i].type &= type; + d[i].type |= SELECT_RETURNED; + ++got; + break; } - _hurd_port_free (&cells[i]->port, &ulink[i], ports[i]); + _hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port); } /* Now wait for reply messages. */ - if (!err && got == 0 && port != MACH_PORT_NULL) + if (!err && got == 0) { /* Now wait for io_select_reply messages on PORT, timing out as appropriate. */ @@ -187,15 +193,13 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), error_t err; mach_msg_type_t result_type; int result; - mach_msg_type_t tag_type; - int tag; } success; } msg; mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT); error_t msgerr; while ((msgerr = __mach_msg (&msg.head, MACH_RCV_MSG | options, - 0, sizeof msg, port, to, + 0, sizeof msg, portset, to, MACH_PORT_NULL)) == MACH_MSG_SUCCESS) { /* We got a message. Decode it. */ @@ -209,34 +213,45 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), { /* This is a properly formatted message so far. See if it is a success or a failure. */ - if (msg.error.err) + if (msg.error.err == EINTR && + msg.head.msgh_size == sizeof msg.error) { - err = msg.error.err; - if (msg.head.msgh_size != sizeof msg.error) - __mach_msg_destroy (&msg); + /* EINTR response; poll for further responses + and then return quickly. */ + err = EINTR; + goto poll; } - else if (msg.head.msgh_size != sizeof msg.success || - *(int *) &msg.success.tag_type != *(int *) &inttype || - *(int *) &msg.success.result_type != *(int *) &inttype) - __mach_msg_destroy (&msg); - else if ((msg.success.result & SELECT_ALL) == 0 || - msg.success.tag < firstfd || msg.success.tag > lastfd) - err = EGRATUITOUS; - else + if (msg.error.err || + msg.head.msgh_size != sizeof msg.success || + *(int *) &msg.success.result_type != *(int *) &inttype || + (msg.success.result & SELECT_ALL) == 0) { - /* This is a winning io_select_reply message! - Record the readiness it indicates and send a reply. */ - types[msg.success.tag] &= msg.success.result; - types[msg.success.tag] |= SELECT_RETURNED; - ++got; + /* Error or bogus reply. Simulate readiness. */ + __mach_msg_destroy (&msg); + msg.success.result = SELECT_ALL; } + + /* Look up the respondant's reply port and record its + readiness. */ + { + int had = got; + for (i = firstfd; i <= lastfd; ++i) + if (d[i].type && d[i].reply_port == msg.head.msgh_local_port) + { + d[i].type &= msg.success.result; + d[i].type |= SELECT_RETURNED; + ++got; + } + assert (got > had); + } } if (msg.head.msgh_remote_port != MACH_PORT_NULL) __mach_port_deallocate (__mach_task_self (), msg.head.msgh_remote_port); - if (got || err == EINTR) + if (got) + poll: { /* Poll for another message. */ to = 0; @@ -252,19 +267,17 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), message waiting. */ err = 0; - if (got && err == EINTR) - /* Some calls were interrupted, but at least one descriptor - is known to be ready now, so we will return success. */ + if (got) + /* At least one descriptor is known to be ready now, so we will + return success. */ err = 0; } - if (port != MACH_PORT_NULL) - /* We must destroy the port if we made some select requests - that might send notification on that port after we no longer care. - If the port were reused, that notification could confuse the next - select call to use the port. The notification might be valid, - but the descriptor may have changed to a different server. */ - __mach_port_destroy (__mach_task_self (), port); + for (i = firstfd; i <= lastfd; ++i) + if (d[i].type) + __mach_port_destroy (__mach_task_self (), d[i].reply_port); + if (portset != MACH_PORT_NULL) + __mach_port_destroy (__mach_task_self (), portset); if (err) return __hurd_fail (err); @@ -277,7 +290,7 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout), ones are initially set. */ for (i = firstfd; i <= lastfd; ++i) { - int type = types[i]; + int type = d[i].type; if ((type & SELECT_RETURNED) == 0) type = 0; diff --git a/sysdeps/mach/hurd/sigaction.c b/sysdeps/mach/hurd/sigaction.c index 957068b168..ebe70664be 100644 --- a/sysdeps/mach/hurd/sigaction.c +++ b/sysdeps/mach/hurd/sigaction.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -47,6 +47,7 @@ DEFUN(__sigaction, (sig, act, oact), ss = _hurd_self_sigstate (); + __spin_lock (&ss->critical_section_lock); __spin_lock (&ss->lock); old = ss->actions[sig]; if (act != NULL) @@ -55,7 +56,6 @@ DEFUN(__sigaction, (sig, act, oact), if (act != NULL && sig == SIGCHLD && (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP)) { - ss->critical_section = 1; __spin_unlock (&ss->lock); /* Inform the proc server whether or not it should send us SIGCHLD for @@ -65,16 +65,16 @@ DEFUN(__sigaction, (sig, act, oact), __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP))); __spin_lock (&ss->lock); - ss->critical_section = 0; pending = ss->pending & ~ss->blocked; } else pending = 0; __spin_unlock (&ss->lock); + __spin_unlock (&ss->critical_section_lock); if (pending) - __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); if (oact != NULL) *oact = old; diff --git a/sysdeps/mach/hurd/sigprocmask.c b/sysdeps/mach/hurd/sigprocmask.c index bae3266708..36edd2bfd5 100644 --- a/sysdeps/mach/hurd/sigprocmask.c +++ b/sysdeps/mach/hurd/sigprocmask.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -79,7 +79,7 @@ DEFUN(__sigprocmask, (how, set, oset), if (pending) /* Send a message to the signal thread so it will wake up and check for pending signals. */ - __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); return 0; } diff --git a/sysdeps/mach/hurd/sigsuspend.c b/sysdeps/mach/hurd/sigsuspend.c index aa0b2876a4..d8ac97032d 100644 --- a/sysdeps/mach/hurd/sigsuspend.c +++ b/sysdeps/mach/hurd/sigsuspend.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -57,7 +57,7 @@ DEFUN(sigsuspend, (set), CONST sigset_t *set) if (pending) /* Tell the signal thread to check for pending signals. */ - __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); /* Wait for the signal thread's message. */ __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait, @@ -71,8 +71,8 @@ DEFUN(sigsuspend, (set), CONST sigset_t *set) if (pending) /* Tell the signal thread to check for pending signals. */ - __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); - + __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); + /* We've been interrupted! And a good thing, too. Otherwise we'd never return. That's right; this function always returns an error. */ diff --git a/sysdeps/stub/nanosleep.c b/sysdeps/stub/nanosleep.c index 7728bf2a42..97cdd50da0 100644 --- a/sysdeps/stub/nanosleep.c +++ b/sysdeps/stub/nanosleep.c @@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */ /* Pause execution for a number of nanoseconds. */ int -nanosleep (const struct timespec *requested_time, struct time_spec *remaining) +nanosleep (const struct timespec *requested_time, struct timespec *remaining) { errno = ENOSYS; return -1; |