1 /* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
22 #include <hurd/signal.h>
23 #include <cthreads.h> /* For `struct mutex'. */
25 #include "hurdfault.h"
26 #include "hurdmalloc.h" /* XXX */
28 const char *_hurdsig_getenv (const char *);
30 struct mutex _hurd_siglock
;
33 /* Port that receives signals and other miscellaneous messages. */
34 mach_port_t _hurd_msgport
;
36 /* Thread listening on it. */
37 thread_t _hurd_msgport_thread
;
39 /* Thread which receives task-global signals. */
40 thread_t _hurd_sigthread
;
42 /* Linked-list of per-thread signal state. */
43 struct hurd_sigstate
*_hurd_sigstates
;
46 default_sigaction (struct sigaction actions
[NSIG
])
50 __sigemptyset (&actions
[0].sa_mask
);
51 actions
[0].sa_flags
= SA_RESTART
;
52 actions
[0].sa_handler
= SIG_DFL
;
54 for (signo
= 1; signo
< NSIG
; ++signo
)
55 actions
[signo
] = actions
[0];
58 struct hurd_sigstate
*
59 _hurd_thread_sigstate (thread_t thread
)
61 struct hurd_sigstate
*ss
;
62 __mutex_lock (&_hurd_siglock
);
63 for (ss
= _hurd_sigstates
; ss
!= NULL
; ss
= ss
->next
)
64 if (ss
->thread
== thread
)
68 ss
= malloc (sizeof (*ss
));
70 __libc_fatal ("hurd: Can't allocate thread sigstate\n");
72 __spin_lock_init (&ss
->lock
);
74 /* Initialze default state. */
75 __sigemptyset (&ss
->blocked
);
76 __sigemptyset (&ss
->pending
);
77 memset (&ss
->sigaltstack
, 0, sizeof (ss
->sigaltstack
));
80 __condition_init (&ss
->arrived
);
82 ss
->intr_port
= MACH_PORT_NULL
;
85 /* Initialize the sigaction vector from the default signal receiving
86 thread's state, and its from the system defaults. */
87 if (thread
== _hurd_sigthread
)
88 default_sigaction (ss
->actions
);
91 struct hurd_sigstate
*s
;
92 for (s
= _hurd_sigstates
; s
!= NULL
; s
= s
->next
)
93 if (s
->thread
== _hurd_sigthread
)
97 __spin_lock (&s
->lock
);
98 memcpy (ss
->actions
, s
->actions
, sizeof (s
->actions
));
99 __spin_unlock (&s
->lock
);
102 default_sigaction (ss
->actions
);
105 ss
->next
= _hurd_sigstates
;
106 _hurd_sigstates
= ss
;
108 __mutex_unlock (&_hurd_siglock
);
112 /* Signal delivery itself is on this page. */
115 #include <hurd/core.h>
116 #include <hurd/paths.h>
119 #include <sys/wait.h>
120 #include "thread_state.h"
121 #include <hurd/msg_server.h>
122 #include <hurd/msg_reply.h> /* For __msg_sig_post_reply. */
124 #include <hurd/interrupt.h>
126 int _hurd_core_limit
; /* XXX */
128 /* Call the core server to mummify us before we die.
129 Returns nonzero if a core file was written. */
131 write_corefile (int signo
, long int sigcode
, int sigerror
)
134 mach_port_t coreserver
;
135 file_t file
, coredir
;
139 When we have a protocol to make the server return an error
140 for RLIMIT_FSIZE, then tell the corefile fs server the RLIMIT_CORE
141 value in place of the RLIMIT_FSIZE value. */
143 /* First get a port to the core dumping server. */
144 coreserver
= MACH_PORT_NULL
;
145 name
= _hurdsig_getenv ("CORESERVER");
147 coreserver
= __file_name_lookup (name
, 0, 0);
148 if (coreserver
== MACH_PORT_NULL
)
149 coreserver
= __file_name_lookup (_SERVERS_CORE
, 0, 0);
150 if (coreserver
== MACH_PORT_NULL
)
153 /* Get a port to the directory where the new core file will reside. */
154 name
= _hurdsig_getenv ("COREFILE");
157 coredir
= __file_name_split (name
, (char **) &name
);
158 if (coredir
== MACH_PORT_NULL
)
160 /* Create the new file, but don't link it into the directory yet. */
161 if (err
= __dir_mkfile (coredir
, O_WRONLY
|O_CREAT
,
162 0600 & ~_hurd_umask
, /* XXX ? */
166 /* Call the core dumping server to write the core file. */
167 err
= __core_dump_task (coreserver
,
169 file
, _hurdsig_getenv ("GNUTARGET"),
170 signo
, sigcode
, sigerror
);
171 __mach_port_deallocate (__mach_task_self (), coreserver
);
173 /* The core dump into FILE succeeded, so now link it into the
175 err
= __dir_link (file
, coredir
, name
);
176 __mach_port_deallocate (__mach_task_self (), file
);
177 __mach_port_deallocate (__mach_task_self (), coredir
);
182 /* Send a sig_post reply message if it hasn't already been sent. */
184 post_reply (mach_port_t
*reply_port
, mach_msg_type_name_t reply_port_type
,
188 if (reply_port
== NULL
|| *reply_port
== MACH_PORT_NULL
)
190 (untraced
? __msg_sig_post_untraced_reply
: __msg_sig_post_reply
)
191 (*reply_port
, reply_port_type
, result
);
192 *reply_port
= MACH_PORT_NULL
;
196 /* The lowest-numbered thread state flavor value is 1,
197 so we use bit 0 in machine_thread_all_state.set to
198 record whether we have done thread_abort. */
199 #define THREAD_ABORTED 1
201 /* SS->thread is suspended. Abort the thread and get its basic state. If
202 REPLY_PORT is not NULL, send a reply on *REPLY_PORT after aborting the
205 abort_thread (struct hurd_sigstate
*ss
, struct machine_thread_all_state
*state
,
206 mach_port_t
*reply_port
, mach_msg_type_name_t reply_port_type
,
209 if (!(state
->set
& THREAD_ABORTED
))
211 __thread_abort (ss
->thread
);
212 /* Clear all thread state flavor set bits, because thread_abort may
213 have changed the state. */
214 state
->set
= THREAD_ABORTED
;
218 post_reply (reply_port
, reply_port_type
, untraced
, 0);
220 machine_get_basic_state (ss
->thread
, state
);
223 /* Find the location of the MiG reply port cell in use by the thread whose
224 state is described by THREAD_STATE. Make sure that this location can be
225 set without faulting, or else return NULL. */
228 interrupted_reply_port_location (struct machine_thread_all_state
*thread_state
)
230 mach_port_t
*portloc
= (mach_port_t
*) __hurd_threadvar_location_from_sp
231 (_HURD_THREADVAR_MIG_REPLY
, (void *) thread_state
->basic
.SP
);
233 if (_hurdsig_catch_fault (SIGSEGV
))
235 assert (_hurdsig_fault_sigcode
== (long int) portloc
);
236 /* Faulted trying to read the stack. */
240 /* Fault now if this pointer is bogus. */
241 *(volatile mach_port_t
*) portloc
= *portloc
;
243 _hurdsig_end_catch_fault ();
249 /* SS->thread is suspended.
251 Abort any interruptible RPC operation the thread is doing.
253 This uses only the constant member SS->thread and the unlocked, atomically
254 set member SS->intr_port, so no locking is needed.
256 If successfully sent an interrupt_operation and therefore the thread should
257 wait for its pending RPC to return (possibly EINTR) before taking the
258 incoming signal, returns the reply port to be received on. Otherwise
259 returns MACH_PORT_NULL.
261 *STATE_CHANGE is set nonzero if STATE->basic was modified and should
262 be applied back to the thread if it might ever run again, else zero. */
265 abort_rpcs (struct hurd_sigstate
*ss
, int signo
,
266 struct machine_thread_all_state
*state
, int *state_change
,
267 mach_port_t
*reply_port
, mach_msg_type_name_t reply_port_type
,
270 mach_port_t msging_port
;
271 mach_port_t intr_port
;
275 intr_port
= ss
->intr_port
;
276 if (intr_port
== MACH_PORT_NULL
)
277 /* No interruption needs done. */
278 return MACH_PORT_NULL
;
280 /* Abort the thread's kernel context, so any pending message send or
281 receive completes immediately or aborts. */
282 abort_thread (ss
, state
, reply_port
, reply_port_type
, untraced
);
284 if (_hurdsig_rcv_interrupted_p (state
, &msging_port
))
288 /* The RPC request message was sent and the thread was waiting for
289 the reply message; now the message receive has been aborted, so
290 the mach_msg_call will return MACH_RCV_INTERRUPTED. We must tell
291 the server to interrupt the pending operation. The thread must
292 wait for the reply message before running the signal handler (to
293 guarantee that the operation has finished being interrupted), so
294 our nonzero return tells the trampoline code to finish the message
295 receive operation before running the handler. */
297 err
= __interrupt_operation (intr_port
);
303 /* The interrupt didn't work.
304 Destroy the receive right the thread is blocked on. */
305 __mach_port_destroy (__mach_task_self (), msging_port
);
307 /* The system call return value register now contains
308 MACH_RCV_INTERRUPTED; when mach_msg resumes, it will retry the
309 call. Since we have just destroyed the receive right, the
310 retry will fail with MACH_RCV_INVALID_NAME. Instead, just
311 change the return value here to EINTR so mach_msg will not
312 retry and the EINTR error code will propagate up. */
313 state
->basic
.SYSRETURN
= EINTR
;
316 /* If that was the thread's MiG reply port (which I think should
317 always be the case), clear the reply port cell so it won't be
319 reply
= interrupted_reply_port_location (state
);
320 if (reply
!= NULL
&& *reply
== msging_port
)
321 *reply
= MACH_PORT_NULL
;
324 /* All threads whose RPCs were interrupted by the interrupt_operation
325 call above will retry their RPCs unless we clear SS->intr_port.
326 So we clear it for the thread taking a signal when SA_RESTART is
327 clear, so that its call returns EINTR. */
328 if (!(ss
->actions
[signo
].sa_flags
& SA_RESTART
))
329 ss
->intr_port
= MACH_PORT_NULL
;
331 return err
? MACH_PORT_NULL
: msging_port
;
334 /* One of the following is true:
336 1. The RPC has not yet been sent. The thread will start its operation
337 after the signal has been handled.
339 2. The RPC has finished, but not yet cleared SS->intr_port.
340 The thread will clear SS->intr_port after running the handler.
342 3. The RPC request message was being sent was aborted. The mach_msg
343 system call will return MACH_SEND_INTERRUPTED, and HURD_EINTR_RPC will
344 notice the interruption (either retrying the RPC or returning EINTR). */
346 return MACH_PORT_NULL
;
349 /* Abort the RPCs being run by all threads but this one;
350 all other threads should be suspended. If LIVE is nonzero, those
351 threads may run again, so they should be adjusted as necessary to be
352 happy when resumed. STATE is clobbered as a scratch area; its initial
353 contents are ignored, and its contents on return are not useful. */
356 abort_all_rpcs (int signo
, struct machine_thread_all_state
*state
, int live
)
358 /* We can just loop over the sigstates. Any thread doing something
359 interruptible must have one. We needn't bother locking because all
360 other threads are stopped. */
362 struct hurd_sigstate
*ss
;
364 mach_port_t
*reply_ports
;
366 /* First loop over the sigstates to count them.
367 We need to know how big a vector we will need for REPLY_PORTS. */
369 for (ss
= _hurd_sigstates
; ss
!= NULL
; ss
= ss
->next
)
372 reply_ports
= alloca (nthreads
* sizeof *reply_ports
);
375 for (ss
= _hurd_sigstates
; ss
!= NULL
; ss
= ss
->next
)
376 if (ss
->thread
== _hurd_msgport_thread
)
377 reply_ports
[nthreads
++] = MACH_PORT_NULL
;
381 state
->set
= 0; /* Reset scratch area. */
383 /* Abort any operation in progress with interrupt_operation.
384 Record the reply port the thread is waiting on.
385 We will wait for all the replies below. */
386 reply_ports
[nthreads
++] = abort_rpcs (ss
, signo
, state
, &state_changed
,
388 if (state_changed
&& live
)
389 /* Aborting the RPC needed to change this thread's state,
390 and it might ever run again. So write back its state. */
391 __thread_set_state (ss
->thread
, MACHINE_THREAD_STATE_FLAVOR
,
392 (natural_t
*) &state
->basic
,
393 MACHINE_THREAD_STATE_COUNT
);
396 /* Wait for replies from all the successfully interrupted RPCs. */
397 while (nthreads
-- > 0)
398 if (reply_ports
[nthreads
] != MACH_PORT_NULL
)
401 mach_msg_header_t head
;
402 err
= __mach_msg (&head
, MACH_RCV_MSG
, 0, sizeof head
,
403 reply_ports
[nthreads
],
404 MACH_MSG_TIMEOUT_NONE
, MACH_PORT_NULL
);
405 if (err
!= MACH_RCV_TOO_LARGE
)
411 struct hurd_signal_preempt
*_hurd_signal_preempt
[NSIG
];
412 struct mutex _hurd_signal_preempt_lock
;
414 /* Mask of stop signals. */
415 #define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \
416 sigmask (SIGSTOP) | sigmask (SIGTSTP))
418 /* Deliver a signal. SS is not locked. */
420 _hurd_internal_post_signal (struct hurd_sigstate
*ss
,
421 int signo
, long int sigcode
, int sigerror
,
422 mach_port_t reply_port
,
423 mach_msg_type_name_t reply_port_type
,
426 struct machine_thread_all_state thread_state
;
427 enum { stop
, ignore
, core
, term
, handle
} act
;
428 sighandler_t handler
;
429 struct hurd_signal_preempt
*pe
;
430 sighandler_t (*preempt
) (thread_t
, int, long int, int) = NULL
;
434 /* Reply to this sig_post message. */
435 inline void reply (void)
437 post_reply (&reply_port
, reply_port_type
, untraced
, 0);
440 /* Mark the signal as pending. */
441 void mark_pending (void)
443 __sigaddset (&ss
->pending
, signo
);
444 /* Save the code to be given to the handler when SIGNO is
446 ss
->pending_data
[signo
].code
= sigcode
;
447 ss
->pending_data
[signo
].error
= sigerror
;
450 /* Suspend the process with SIGNO. */
453 /* Stop all other threads and mark ourselves stopped. */
456 /* Hold the siglock while stopping other threads to be
457 sure it is not held by another thread afterwards. */
458 __mutex_lock (&_hurd_siglock
);
459 __proc_dostop (port
, _hurd_msgport_thread
);
460 __mutex_unlock (&_hurd_siglock
);
461 abort_all_rpcs (signo
, &thread_state
, 1);
462 __proc_mark_stop (port
, signo
);
469 thread_state
.set
= 0; /* We know nothing. */
471 /* Check for a preempted signal. Preempted signals
472 can arrive during critical sections. */
473 __mutex_lock (&_hurd_signal_preempt_lock
);
474 for (pe
= _hurd_signal_preempt
[signo
]; pe
!= NULL
; pe
= pe
->next
)
475 if (sigcode
>= pe
->first
&& sigcode
<= pe
->last
)
477 preempt
= pe
->handler
;
480 __mutex_unlock (&_hurd_signal_preempt_lock
);
484 /* Let the preempting handler examine the thread.
485 If it returns SIG_DFL, we run the normal handler;
486 otherwise we use the handler it returns. */
487 handler
= (*preempt
) (ss
->thread
, signo
, sigcode
, sigerror
);
491 if (handler
!= SIG_DFL
)
492 /* Run the preemption-provided handler. */
496 /* No preemption. Do normal handling. */
498 __spin_lock (&ss
->lock
);
500 handler
= ss
->actions
[signo
].sa_handler
;
502 if (!untraced
&& (_hurd_exec_flags
& EXEC_TRACED
))
504 /* We are being traced. Stop to tell the debugger of the signal. */
506 /* Already stopped. Mark the signal as pending;
507 when resumed, we will notice it and stop again. */
511 __spin_unlock (&ss
->lock
);
516 if (handler
== SIG_DFL
)
517 /* Figure out the default action for this signal. */
521 /* A sig_post msg with SIGNO==0 is sent to
522 tell us to check for pending signals. */
554 if (_hurd_pgrp
== _hurd_pid
)
556 /* We are the process group leader. Since there is no
557 user-specified handler for SIGINFO, we use a default one
558 which prints something interesting. We use the normal
559 handler mechanism instead of just doing it here to avoid
560 the signal thread faulting or blocking in this
561 potentially hairy operation. */
563 handler
= _hurd_siginfo_handler
;
573 else if (handler
== SIG_IGN
)
578 if (__sigmask (signo
) & STOPSIGS
)
579 /* Stop signals clear a pending SIGCONT even if they
580 are handled or ignored (but not if preempted). */
581 ss
->pending
&= ~sigmask (SIGCONT
);
584 if (signo
== SIGCONT
)
585 /* Even if handled or ignored (but not preempted), SIGCONT clears
586 stop signals and resumes the process. */
587 ss
->pending
&= ~STOPSIGS
;
589 if (_hurd_stopped
&& act
!= stop
&& (untraced
|| signo
== SIGCONT
))
591 /* Resume the process from being stopped. */
593 mach_msg_type_number_t nthreads
, i
;
595 /* Tell the proc server we are continuing. */
596 __USEPORT (PROC
, __proc_mark_cont (port
));
597 /* Fetch ports to all our threads and resume them. */
598 err
= __task_threads (__mach_task_self (), &threads
, &nthreads
);
600 for (i
= 0; i
< nthreads
; ++i
)
602 if (threads
[i
] != _hurd_msgport_thread
&&
603 (act
!= handle
|| threads
[i
] != ss
->thread
))
604 __thread_resume (threads
[i
]);
605 __mach_port_deallocate (__mach_task_self (), threads
[i
]);
607 __vm_deallocate (__mach_task_self (),
608 (vm_address_t
) threads
,
609 nthreads
* sizeof *threads
);
611 /* The thread that will run the handler is already suspended. */
617 if (_hurd_orphaned
&& act
== stop
&&
618 (__sigmask (signo
) & (__sigmask (SIGTTIN
) | __sigmask (SIGTTOU
) |
619 __sigmask (SIGTSTP
))))
621 /* If we would ordinarily stop for a job control signal, but we are
622 orphaned so noone would ever notice and continue us again, we just
623 quietly die, alone and in the dark. */
629 /* Handle receipt of a blocked signal, or any signal while stopped.
630 It matters that we test ACT first here, because we must never pass
631 SIGNO==0 to __sigismember. */
632 if ((act
!= ignore
&& __sigismember (&ss
->blocked
, signo
)) ||
633 (signo
!= SIGKILL
&& _hurd_stopped
))
639 /* Perform the chosen action for the signal. */
644 /* We are already stopped, but receiving an untraced stop
645 signal. Instead of resuming and suspending again, just
646 notify the proc server of the new stop signal. */
647 __USEPORT (PROC
, __proc_mark_stop (port
, signo
));
649 /* Suspend the process. */
654 /* Nobody cares about this signal. */
657 case term
: /* Time to die. */
658 case core
: /* And leave a rotting corpse. */
660 /* Have the proc server stop all other threads in our task. */
661 __USEPORT (PROC
, __proc_dostop (port
, _hurd_msgport_thread
));
662 /* No more user instructions will be executed.
663 The signal can now be considered delivered. */
665 /* Abort all server operations now in progress. */
666 abort_all_rpcs (signo
, &thread_state
, 0);
669 int status
= W_EXITCODE (0, signo
);
670 /* Do a core dump if desired. Only set the wait status bit saying we
671 in fact dumped core if the operation was actually successful. */
672 if (act
== core
&& write_corefile (signo
, sigcode
, sigerror
))
674 /* Tell proc how we died and then stick the saber in the gut. */
680 /* Call a handler for this signal. */
682 struct sigcontext
*scp
;
683 int wait_for_reply
, state_changed
;
685 /* Stop the thread and abort its pending RPC operations. */
687 __thread_suspend (ss
->thread
);
689 /* Abort the thread's kernel context, so any pending message send
690 or receive completes immediately or aborts. If an interruptible
691 RPC is in progress, abort_rpcs will do this. But we must always
692 do it before fetching the thread's state, because
693 thread_get_state is never kosher before thread_abort. */
694 abort_thread (ss
, &thread_state
, NULL
, 0, 0);
696 wait_for_reply
= (abort_rpcs (ss
, signo
, &thread_state
, &state_changed
,
697 &reply_port
, reply_port_type
, untraced
)
700 if (ss
->critical_section
)
702 /* The thread is in a critical section. Mark the signal as
703 pending. When it finishes the critical section, it will
704 check for pending signals. */
706 assert (! state_changed
);
707 __thread_resume (ss
->thread
);
711 /* Call the machine-dependent function to set the thread up
712 to run the signal handler, and preserve its old context. */
713 scp
= _hurd_setup_sighandler (ss
, handler
,
715 wait_for_reply
, &thread_state
);
718 /* We got a fault setting up the stack frame for the handler.
719 Nothing to do but die; BSD gets SIGILL in this case. */
720 sigcode
= signo
; /* XXX ? */
726 /* Set the machine-independent parts of the signal context. */
728 scp
->sc_error
= sigerror
;
730 /* Fetch the thread variable for the MiG reply port,
731 and set it to MACH_PORT_NULL. */
732 mach_port_t
*loc
= interrupted_reply_port_location (&thread_state
);
735 scp
->sc_reply_port
= *loc
;
736 *loc
= MACH_PORT_NULL
;
739 scp
->sc_reply_port
= MACH_PORT_NULL
;
742 /* Block SIGNO and requested signals while running the handler. */
743 scp
->sc_mask
= ss
->blocked
;
744 ss
->blocked
|= __sigmask (signo
) | ss
->actions
[signo
].sa_mask
;
746 /* Save the intr_port in use by the interrupted code,
747 and clear the cell before running the trampoline. */
748 scp
->sc_intr_port
= ss
->intr_port
;
749 ss
->intr_port
= MACH_PORT_NULL
;
751 /* Start the thread running the handler (or possibly waiting for an
752 RPC reply before running the handler). */
753 __thread_set_state (ss
->thread
, MACHINE_THREAD_STATE_FLAVOR
,
754 (natural_t
*) &thread_state
.basic
,
755 MACHINE_THREAD_STATE_COUNT
);
756 __thread_resume (ss
->thread
);
757 thread_state
.set
= 0; /* Everything we know is now wrong. */
762 /* The signal has either been ignored or is now being handled. We can
763 consider it delivered and reply to the killer. The exception is
764 signal 0, which can be sent by a user thread to make us check for
765 pending signals. In that case we want to deliver the pending signals
770 /* We get here unless the signal was fatal. We still hold SS->lock.
771 Check for pending signals, and loop to post them. */
772 #define PENDING (!_hurd_stopped && (pending = ss->pending & ~ss->blocked))
776 for (signo
= 1; signo
< NSIG
; ++signo
)
777 if (__sigismember (&pending
, signo
))
779 __sigdelset (&ss
->pending
, signo
);
780 sigcode
= ss
->pending_data
[signo
].code
;
781 sigerror
= ss
->pending_data
[signo
].error
;
782 __spin_unlock (&ss
->lock
);
787 /* No pending signals left undelivered for this thread.
788 If we were sent signal 0, we need to check for pending
789 signals for all threads. */
792 __spin_unlock (&ss
->lock
);
793 __mutex_lock (&_hurd_siglock
);
794 for (ss
= _hurd_sigstates
; ss
!= NULL
; ss
= ss
->next
)
796 __spin_lock (&ss
->lock
);
799 __spin_unlock (&ss
->lock
);
801 __mutex_unlock (&_hurd_siglock
);
805 /* No more signals pending; SS->lock is still locked.
806 Wake up any sigsuspend call that is blocking SS->thread. */
807 if (ss
->suspended
!= MACH_PORT_NULL
)
809 /* There is a sigsuspend waiting. Tell it to wake up. */
811 mach_msg_header_t msg
;
812 err
= __mach_port_insert_right (__mach_task_self (),
813 ss
->suspended
, ss
->suspended
,
814 MACH_MSG_TYPE_MAKE_SEND
);
816 msg
.msgh_bits
= MACH_MSGH_BITS (MACH_MSG_TYPE_MOVE_SEND
, 0);
817 msg
.msgh_remote_port
= ss
->suspended
;
818 msg
.msgh_local_port
= MACH_PORT_NULL
;
819 /* These values do not matter. */
820 msg
.msgh_id
= 8675309; /* Jenny, Jenny. */
821 msg
.msgh_seqno
= 17; /* Random. */
822 ss
->suspended
= MACH_PORT_NULL
;
823 err
= __mach_msg (&msg
, MACH_SEND_MSG
, sizeof msg
, 0,
824 MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
,
828 __spin_unlock (&ss
->lock
);
831 /* All pending signals delivered to all threads.
832 Now we can send the reply message even for signal 0. */
836 /* Decide whether REFPORT enables the sender to send us a SIGNO signal.
837 Returns zero if so, otherwise the error code to return to the sender. */
840 signal_allowed (int signo
, mach_port_t refport
)
842 if (signo
< 0 || signo
>= NSIG
)
845 if (refport
== __mach_task_self ())
846 /* Can send any signal. */
849 /* Avoid needing to check for this below. */
850 if (refport
== MACH_PORT_NULL
)
862 /* Job control signals can be sent by the controlling terminal. */
863 if (__USEPORT (CTTYID
, port
== refport
))
869 /* A continue signal can be sent by anyone in the session. */
870 mach_port_t sessport
;
871 if (! __USEPORT (PROC
, __proc_getsidport (port
, &sessport
)))
873 __mach_port_deallocate (__mach_task_self (), sessport
);
874 if (refport
== sessport
)
883 /* Any io object a file descriptor refers to might send us
884 one of these signals using its async ID port for REFPORT.
886 This is pretty wide open; it is not unlikely that some random
887 process can at least open for reading something we have open,
888 get its async ID port, and send us a spurious SIGIO or SIGURG
889 signal. But BSD is actually wider open than that!--you can set
890 the owner of an io object to any process or process group
891 whatsoever and send them gratuitous signals.
893 Someday we could implement some reasonable scheme for
894 authorizing SIGIO and SIGURG signals properly. */
897 __mutex_lock (&_hurd_dtable_lock
);
898 for (d
= 0; (unsigned int) d
< (unsigned int) _hurd_dtablesize
; ++d
)
900 struct hurd_userlink ulink
;
903 if (_hurd_dtable
[d
] == NULL
)
905 port
= _hurd_port_get (&_hurd_dtable
[d
]->port
, &ulink
);
906 if (! __io_get_icky_async_id (port
, &asyncid
))
908 if (refport
== asyncid
)
909 /* Break out of the loop on the next iteration. */
911 __mach_port_deallocate (__mach_task_self (), asyncid
);
913 _hurd_port_free (&_hurd_dtable
[d
]->port
, &ulink
, port
);
915 /* If we found a lucky winner, we've set D to -1 in the loop. */
921 /* If this signal is legit, we have done `goto win' by now.
922 When we return the error, mig deallocates REFPORT. */
926 /* Deallocate the REFPORT send right; we are done with it. */
927 __mach_port_deallocate (__mach_task_self (), refport
);
932 /* Implement the sig_post RPC from <hurd/msg.defs>;
933 sent when someone wants us to get a signal. */
935 _S_msg_sig_post (mach_port_t me
,
936 mach_port_t reply_port
, mach_msg_type_name_t reply_port_type
,
942 if (err
= signal_allowed (signo
, refport
))
945 /* Post the signal to the designated signal-receiving thread. This will
946 reply when the signal can be considered delivered. */
947 _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread
),
948 signo
, 0, 0, reply_port
, reply_port_type
,
949 0); /* Stop if traced. */
951 return MIG_NO_REPLY
; /* Already replied. */
954 /* Implement the sig_post_untraced RPC from <hurd/msg.defs>;
955 sent when the debugger wants us to really get a signal
956 even if we are traced. */
958 _S_msg_sig_post_untraced (mach_port_t me
,
959 mach_port_t reply_port
,
960 mach_msg_type_name_t reply_port_type
,
966 if (err
= signal_allowed (signo
, refport
))
969 /* Post the signal to the designated signal-receiving thread. This will
970 reply when the signal can be considered delivered. */
971 _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread
),
972 signo
, 0, 0, reply_port
, reply_port_type
,
973 1); /* Untraced flag. */
975 return MIG_NO_REPLY
; /* Already replied. */
978 extern void __mig_init (void *);
980 #include <mach/task_special_ports.h>
982 /* Initialize the message port and _hurd_sigthread and start the signal
991 __mutex_init (&_hurd_siglock
);
993 if (err
= __mach_port_allocate (__mach_task_self (),
994 MACH_PORT_RIGHT_RECEIVE
,
996 __libc_fatal ("hurd: Can't create message port receive right\n");
998 /* Make a send right to the signal port. */
999 if (err
= __mach_port_insert_right (__mach_task_self (),
1002 MACH_MSG_TYPE_MAKE_SEND
))
1003 __libc_fatal ("hurd: Can't create send right to message port\n");
1005 /* Set the default thread to receive task-global signals
1006 to this one, the main (first) user thread. */
1007 _hurd_sigthread
= __mach_thread_self ();
1009 /* Start the signal thread listening on the message port. */
1011 if (err
= __thread_create (__mach_task_self (), &_hurd_msgport_thread
))
1012 __libc_fatal ("hurd: Can't create signal thread\n");
1014 stacksize
= __vm_page_size
* 4; /* Small stack for signal thread. */
1015 if (err
= __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread
,
1016 _hurd_msgport_receive
,
1017 (vm_address_t
*) &__hurd_sigthread_stack_base
,
1019 __libc_fatal ("hurd: Can't setup signal thread\n");
1021 __hurd_sigthread_stack_end
= __hurd_sigthread_stack_base
+ stacksize
;
1022 __hurd_sigthread_variables
=
1023 malloc (__hurd_threadvar_max
* sizeof (unsigned long int));
1024 if (__hurd_sigthread_variables
== NULL
)
1025 __libc_fatal ("hurd: Can't allocate thread variables for signal thread\n");
1027 /* Reinitialize the MiG support routines so they will use a per-thread
1028 variable for the cached reply port. */
1029 __mig_init ((void *) __hurd_sigthread_stack_base
);
1031 if (err
= __thread_resume (_hurd_msgport_thread
))
1032 __libc_fatal ("hurd: Can't resume signal thread\n");
1034 #if 0 /* Don't confuse poor gdb. */
1035 /* Receive exceptions on the signal port. */
1036 __task_set_special_port (__mach_task_self (),
1037 TASK_EXCEPTION_PORT
, _hurd_msgport
);
1041 /* Reauthenticate with the proc server. */
1044 reauth_proc (mach_port_t
new)
1046 mach_port_t ref
, ignore
;
1048 ref
= __mach_reply_port ();
1049 if (! HURD_PORT_USE (&_hurd_ports
[INIT_PORT_PROC
],
1050 __proc_reauthenticate (port
, ref
,
1051 MACH_MSG_TYPE_MAKE_SEND
) ||
1052 __auth_user_authenticate (new, port
, ref
,
1053 MACH_MSG_TYPE_MAKE_SEND
,
1055 && ignore
!= MACH_PORT_NULL
)
1056 __mach_port_deallocate (__mach_task_self (), ignore
);
1057 __mach_port_destroy (__mach_task_self (), ref
);
1059 (void) &reauth_proc
; /* Silence compiler warning. */
1061 text_set_element (_hurd_reauth_hook
, reauth_proc
);
1063 /* Like `getenv', but safe for the signal thread to run.
1064 If the environment is trashed, this will just return NULL. */
1067 _hurdsig_getenv (const char *variable
)
1069 if (_hurdsig_catch_fault (SIGSEGV
))
1070 /* We bombed in getenv. */
1074 const char *value
= getenv (variable
);
1075 /* Fault now if VALUE is a bogus string. */
1076 (void) strlen (value
);
1077 _hurdsig_end_catch_fault ();