3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
5 Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
6 Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
8 This file is part of Cygwin.
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
17 #include <sys/cygwin.h>
22 int sigcatchers; /* FIXME: Not thread safe. */
24 #define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL)
27 set_sigcatchers (void (*oldsig) (int), void (*cursig) (int))
30 int last_sigcatchers = sigcatchers;
32 if (!sigtrapped (oldsig) && sigtrapped (cursig))
34 else if (sigtrapped (oldsig) && !sigtrapped (cursig))
37 if (last_sigcatchers != sigcatchers)
38 sigproc_printf ("last %d, old %d, cur %p, cur %p", last_sigcatchers,
39 sigcatchers, oldsig, cursig);
43 extern "C" _sig_func_ptr
44 signal (int sig, _sig_func_ptr func)
46 sig_dispatch_pending ();
49 /* check that sig is in right range */
50 if (sig < 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
53 syscall_printf ("SIG_ERR = signal (%d, %p)", sig, func);
54 return (_sig_func_ptr) SIG_ERR;
57 prev = myself->getsig (sig).sa_handler;
58 myself->getsig (sig).sa_handler = func;
59 myself->getsig (sig).sa_mask = 0;
60 /* SA_RESTART is set to maintain BSD compatible signal behaviour by default.
61 This is also compatible with the behaviour of signal(2) in Linux. */
62 myself->getsig (sig).sa_flags |= SA_RESTART;
63 set_sigcatchers (prev, func);
65 syscall_printf ("%p = signal (%d, %p)", prev, sig, func);
70 nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
73 sig_dispatch_pending ();
74 sigframe thisframe (mainthread);
75 pthread_testcancel ();
77 if ((unsigned int) rqtp->tv_sec > (HIRES_DELAY_MAX / 1000 - 1)
78 || (unsigned int) rqtp->tv_nsec > 999999999)
83 DWORD resolution = gtod.resolution ();
84 DWORD req = ((rqtp->tv_sec * 1000 + (rqtp->tv_nsec + 999999) / 1000000
85 + resolution - 1) / resolution) * resolution;
86 DWORD end_time = gtod.dmsecs () + req;
87 syscall_printf ("nanosleep (%ld)", req);
89 int rc = pthread::cancelable_wait (signal_arrived, req);
91 if ((rem = end_time - gtod.dmsecs ()) > HIRES_DELAY_MAX)
93 if (rc == WAIT_OBJECT_0)
95 (void) thisframe.call_signal_handler ();
102 rmtp->tv_sec = rem / 1000;
103 rmtp->tv_nsec = (rem % 1000) * 1000000;
106 syscall_printf ("%d = nanosleep (%ld, %ld)", res, req, rem);
110 extern "C" unsigned int
111 sleep (unsigned int seconds)
113 struct timespec req, rem;
114 req.tv_sec = seconds;
116 nanosleep (&req, &rem);
117 return rem.tv_sec + (rem.tv_nsec > 0);
120 extern "C" unsigned int
121 usleep (unsigned int useconds)
124 req.tv_sec = useconds / 1000000;
125 req.tv_nsec = (useconds % 1000000) * 1000;
126 int res = nanosleep (&req, 0);
131 sigprocmask (int sig, const sigset_t *set, sigset_t *oldset)
133 sig_dispatch_pending ();
134 /* check that sig is in right range */
135 if (sig < 0 || sig >= NSIG)
138 syscall_printf ("SIG_ERR = sigprocmask signal %d out of range", sig);
143 *oldset = myself->getsigmask ();
146 sigset_t newmask = myself->getsigmask ();
150 /* add set to current mask */
154 /* remove set from current mask */
165 (void) set_process_mask (newmask);
171 kill_worker (pid_t pid, int sig)
173 sig_dispatch_pending ();
176 pinfo dest (pid, PID_MAP_RW);
185 if ((sendSIGCONT = (sig < 0)))
189 if (dest == myself && !sendSIGCONT)
190 dest = myself_nowait_nonmain;
194 res = proc_exists (dest) ? 0 : -1;
198 else if ((res = sig_send (dest, sig)))
200 sigproc_printf ("%d = sig_send, %E ", res);
203 else if (sendSIGCONT)
204 (void) sig_send (dest, SIGCONT);
206 syscall_printf ("%d = kill_worker (%d, %d)", res, pid, sig);
213 return kill (myself->pid, sig);
217 kill (pid_t pid, int sig)
219 sigframe thisframe (mainthread);
220 syscall_printf ("kill (%d, %d)", pid, sig);
221 /* check that sig is in right range */
222 if (sig < 0 || sig >= NSIG)
225 syscall_printf ("signal %d out of range", sig);
229 /* Silently ignore stop signals from a member of orphaned process group.
231 if (ISSTATE (myself, PID_ORPHANED) &&
232 (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU))
235 return (pid > 0) ? kill_worker (pid, sig) : kill_pgrp (-pid, sig);
239 kill_pgrp (pid_t pid, int sig)
244 sigframe thisframe (mainthread);
246 sigproc_printf ("pid %d, signal %d", pid, sig);
248 winpids pids ((DWORD) PID_MAP_RW);
249 for (unsigned i = 0; i < pids.npids; i++)
253 if (!proc_exists (p))
256 /* Is it a process we want to kill? */
257 if ((pid == 0 && (p->pgid != myself->pgid || p->ctty != myself->ctty)) ||
258 (pid > 1 && p->pgid != pid) ||
259 (sig < 0 && NOTSTATE (p, PID_STOPPED)))
261 sigproc_printf ("killing pid %d, pgrp %d, p->ctty %d, myself->ctty %d",
262 p->pid, p->pgid, p->ctty, myself->ctty);
265 else if (kill_worker (p->pid, sig))
270 if (killself && kill_worker (myself->pid, sig))
278 syscall_printf ("%d = kill (%d, %d)", res, pid, sig);
283 killpg (pid_t pgrp, int sig)
285 return kill (-pgrp, sig);
291 sig_dispatch_pending ();
292 sigframe thisframe (mainthread);
293 /* Flush all streams as per SUSv2.
294 From my reading of this document, this isn't strictly correct.
295 The streams are supposed to be flushed prior to exit. However,
296 if there is I/O in any signal handler that will not necessarily
298 However this is the way FreeBSD does it, and it is much easier to
299 do things this way, so... */
300 if (_REENT->__cleanup)
301 _REENT->__cleanup (_REENT);
303 /* Ensure that SIGABRT can be caught regardless of blockage. */
305 sigfillset (&sig_mask);
306 sigdelset (&sig_mask, SIGABRT);
307 set_process_mask (sig_mask);
310 (void) thisframe.call_signal_handler (); /* Call any signal handler */
311 do_exit (1); /* signal handler didn't exit. Goodbye. */
315 sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
317 sig_dispatch_pending ();
318 sigproc_printf ("signal %d, newact %p, oldact %p", sig, newact, oldact);
319 /* check that sig is in right range */
320 if (sig < 0 || sig >= NSIG)
323 syscall_printf ("SIG_ERR = sigaction signal %d out of range", sig);
327 struct sigaction oa = myself->getsig (sig);
331 if (sig == SIGKILL || sig == SIGSTOP)
336 myself->getsig (sig) = *newact;
337 if (newact->sa_handler == SIG_IGN)
339 if (newact->sa_handler == SIG_DFL && sig == SIGCHLD)
341 set_sigcatchers (oa.sa_handler, newact->sa_handler);
344 myself->process_state &= ~PID_NOCLDSTOP;
345 if (newact->sa_flags & SA_NOCLDSTOP);
346 myself->process_state |= PID_NOCLDSTOP;
357 sigaddset (sigset_t *set, const int sig)
359 /* check that sig is in right range */
360 if (sig <= 0 || sig >= NSIG)
363 syscall_printf ("SIG_ERR = sigaddset signal %d out of range", sig);
367 *set |= SIGTOMASK (sig);
372 sigdelset (sigset_t *set, const int sig)
374 /* check that sig is in right range */
375 if (sig <= 0 || sig >= NSIG)
378 syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig);
382 *set &= ~SIGTOMASK (sig);
387 sigismember (const sigset_t *set, int sig)
389 /* check that sig is in right range */
390 if (sig <= 0 || sig >= NSIG)
393 syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig);
397 if (*set & SIGTOMASK (sig))
404 sigemptyset (sigset_t *set)
411 sigfillset (sigset_t *set)
413 *set = ~((sigset_t) 0);
418 sigsuspend (const sigset_t *set)
420 return handle_sigsuspend (*set);
424 sigpause (int signal_mask)
426 return handle_sigsuspend ((sigset_t) signal_mask);
432 return handle_sigsuspend (myself->getsigmask ());
436 siginterrupt (int sig, int flag)
438 struct sigaction act;
439 (void)sigaction(sig, NULL, &act);
441 act.sa_flags &= ~SA_RESTART;
443 act.sa_flags |= SA_RESTART;
444 return sigaction(sig, &act, NULL);