aboutsummaryrefslogtreecommitdiff
path: root/hurd
diff options
context:
space:
mode:
Diffstat (limited to 'hurd')
-rw-r--r--hurd/Makefile3
-rw-r--r--hurd/hurdexec.c6
-rw-r--r--hurd/hurdinit.c2
-rw-r--r--hurd/hurdsig.c112
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 (),