diff options
Diffstat (limited to 'hurd')
-rw-r--r-- | hurd/Makefile | 3 | ||||
-rw-r--r-- | hurd/hurdexec.c | 6 | ||||
-rw-r--r-- | hurd/hurdinit.c | 2 | ||||
-rw-r--r-- | hurd/hurdsig.c | 112 |
4 files changed, 71 insertions, 52 deletions
diff --git a/hurd/Makefile b/hurd/Makefile index 8d1f19464b..69f9e96031 100644 --- a/hurd/Makefile +++ b/hurd/Makefile @@ -33,7 +33,8 @@ distribute := hurdstartup.h hurdfault.h intr-rpc.defs STATUS # The RPC interfaces go in a separate library. interface-library := libhurduser user-interfaces := $(addprefix hurd/,\ - auth process startup \ + auth startup \ + process process_request \ msg msg_reply msg_request \ exec exec_startup crash interrupt \ fs fsys io term socket ifsock) diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c index 0ac18e42da..149e95ccec 100644 --- a/hurd/hurdexec.c +++ b/hurd/hurdexec.c @@ -30,7 +30,7 @@ Cambridge, MA 02139, USA. */ 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, +_hurd_exec (task_t task, file_t file, char *const argv[], char *const envp[]) { error_t err; @@ -129,7 +129,7 @@ _hurd_exec (task_t task, file_t file, 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. */ - + ss->critical_section = 1; __spin_unlock (&ss->lock); @@ -224,7 +224,7 @@ _hurd_exec (task_t task, file_t file, ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports, ints, INIT_INT_MAX, please_dealloc, pdp - please_dealloc, - NULL, 0); + &_hurd_msgport, task == __mach_task_self () ? 1 : 0); } /* Release references to the standard ports. */ diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c index 409d2d19a0..bed78b8321 100644 --- a/hurd/hurdinit.c +++ b/hurd/hurdinit.c @@ -151,7 +151,7 @@ _hurd_proc_init (char **argv) /* 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. */ - _hurd_raise_signal (NULL, SIGTRAP, 0, 0); + __msg_sig_post (_hurd_msgport, SIGTRAP, __mach_task_self ()); } /* Called when we get a message telling us to change our proc server port. */ diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index 7affb906d5..68be2e9bd0 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -265,11 +265,14 @@ interrupted_reply_port_location (struct machine_thread_all_state *thread_state, 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, +_hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread, struct machine_thread_all_state *state, int *state_change, mach_port_t *reply_port, mach_msg_type_name_t reply_port_type, @@ -480,6 +483,52 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, })); _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; + /* 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: @@ -514,8 +563,6 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, __spin_lock (&ss->lock); - handler = ss->actions[signo].sa_handler; - if (!untraced && (_hurd_exec_flags & EXEC_TRACED)) { /* We are being traced. Stop to tell the debugger of the signal. */ @@ -530,6 +577,8 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, return; } + handler = ss->actions[signo].sa_handler; + if (handler == SIG_DFL) /* Figure out the default action for this signal. */ switch (signo) @@ -604,35 +653,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, ss->pending &= ~STOPSIGS; if (_hurd_stopped && act != stop && (untraced || signo == SIGCONT)) - { - /* Resume the process from being stopped. */ - thread_t *threads; - mach_msg_type_number_t nthreads, i; - error_t err; - /* 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; - /* The thread that will run the handler is already suspended. */ - ss_suspended = 1; - } + resume (); } } @@ -648,10 +669,8 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, act = term; } - /* Handle receipt of a blocked signal, or any signal while stopped. - It matters that we test ACT first here, because we must never pass - SIGNO==0 to __sigismember. */ - if ((act != ignore && __sigismember (&ss->blocked, signo)) || + /* Handle receipt of a blocked signal, or any signal while stopped. */ + if (__sigismember (&ss->blocked, signo) || (signo != SIGKILL && _hurd_stopped)) { mark_pending (); @@ -754,7 +773,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, 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); @@ -772,7 +791,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, else { wait_for_reply - = (_hurdsig_abort_rpcs (ss, signo, 1, + = (_hurdsig_abort_rpcs (ss, signo, 1, &thread_state, &state_changed, &reply_port, reply_port_type, untraced) != MACH_PORT_NULL); @@ -851,12 +870,8 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, } /* The signal has either been ignored or is now being handled. We can - consider it delivered and reply to the killer. The exception is - signal 0, which can be sent by a user thread to make us check for - pending signals. In that case we want to deliver the pending signals - before replying. */ - if (signo != 0) - reply (); + 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. */ @@ -874,6 +889,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, return pending = ss->pending & ~ss->blocked; } + check_pending_signals: + untraced = 0; + if (signals_pending ()) { pending: @@ -974,7 +992,7 @@ signal_allowed (int signo, mach_port_t refport) /* 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; @@ -1099,7 +1117,7 @@ _hurdsig_init (void) MACH_PORT_RIGHT_RECEIVE, &_hurd_msgport)) __libc_fatal ("hurd: Can't create message port receive right\n"); - + /* Make a send right to the signal port. */ if (err = __mach_port_insert_right (__mach_task_self (), _hurd_msgport, @@ -1135,7 +1153,7 @@ _hurdsig_init (void) if (err = __thread_resume (_hurd_msgport_thread)) __libc_fatal ("hurd: Can't resume signal thread\n"); - + #if 0 /* Don't confuse poor gdb. */ /* Receive exceptions on the signal port. */ __task_set_special_port (__mach_task_self (), |