]>
sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/signal.cc
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
7 Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
9 This file is part of Cygwin.
11 This software is a copyrighted work licensed under the terms of the
12 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
17 #include <sys/cygwin.h>
27 #define _SA_NORESTART 0x8000
29 static int sigaction_worker (int, const struct sigaction
*, struct sigaction
*, bool, const char *)
30 __attribute__ ((regparm (3)));
32 #define sigtrapped(func) ((func) != SIG_IGN && (func) != SIG_DFL)
34 extern "C" _sig_func_ptr
35 signal (int sig
, _sig_func_ptr func
)
37 sig_dispatch_pending ();
40 /* check that sig is in right range */
41 if (sig
< 0 || sig
>= NSIG
|| sig
== SIGKILL
|| sig
== SIGSTOP
)
44 syscall_printf ("SIG_ERR = signal (%d, %p)", sig
, func
);
45 return (_sig_func_ptr
) SIG_ERR
;
48 prev
= global_sigs
[sig
].sa_handler
;
49 struct sigaction
& gs
= global_sigs
[sig
];
50 if (gs
.sa_flags
& _SA_NORESTART
)
51 gs
.sa_flags
&= ~SA_RESTART
;
53 gs
.sa_flags
|= SA_RESTART
;
55 gs
.sa_mask
= SIGTOMASK (sig
);
57 gs
.sa_flags
&= ~SA_SIGINFO
;
59 syscall_printf ("%p = signal (%d, %p)", prev
, sig
, func
);
64 clock_nanosleep (clockid_t clk_id
, int flags
, const struct timespec
*rqtp
,
65 struct timespec
*rmtp
)
67 const bool abstime
= (flags
& TIMER_ABSTIME
) ? true : false;
69 sig_dispatch_pending ();
70 pthread_testcancel ();
72 if (rqtp
->tv_sec
< 0 || rqtp
->tv_nsec
< 0 || rqtp
->tv_nsec
> 999999999L)
75 /* Explicitly disallowed by POSIX. Needs to be checked first to avoid
76 being caught by the following test. */
77 if (clk_id
== CLOCK_THREAD_CPUTIME_ID
)
80 /* support for CPU-time clocks is optional */
81 if (CLOCKID_IS_PROCESS (clk_id
) || CLOCKID_IS_THREAD (clk_id
))
90 /* unknown or illegal clock ID */
94 LARGE_INTEGER timeout
;
96 timeout
.QuadPart
= (LONGLONG
) rqtp
->tv_sec
* NSPERSEC
97 + ((LONGLONG
) rqtp
->tv_nsec
+ 99LL) / 100LL;
103 clock_gettime (clk_id
, &tp
);
104 /* Check for immediate timeout */
105 if (tp
.tv_sec
> rqtp
->tv_sec
106 || (tp
.tv_sec
== rqtp
->tv_sec
&& tp
.tv_nsec
> rqtp
->tv_nsec
))
109 if (clk_id
== CLOCK_REALTIME
)
110 timeout
.QuadPart
+= FACTOR
;
113 /* other clocks need to be handled with a relative timeout */
114 timeout
.QuadPart
-= tp
.tv_sec
* NSPERSEC
+ tp
.tv_nsec
/ 100LL;
115 timeout
.QuadPart
*= -1LL;
119 timeout
.QuadPart
*= -1LL;
121 syscall_printf ("clock_nanosleep (%ld.%09ld)", rqtp
->tv_sec
, rqtp
->tv_nsec
);
123 int rc
= cancelable_wait (NULL
, &timeout
, cw_sig
| cw_cancel
| cw_cancel_self
);
124 if (rc
== WAIT_SIGNALED
)
127 /* according to POSIX, rmtp is used only if !abstime */
128 if (rmtp
&& !abstime
)
130 rmtp
->tv_sec
= (time_t) (timeout
.QuadPart
/ NSPERSEC
);
131 rmtp
->tv_nsec
= (long) ((timeout
.QuadPart
% NSPERSEC
) * 100LL);
134 syscall_printf ("%d = clock_nanosleep(%lu, %d, %ld.%09ld, %ld.%09.ld)",
135 res
, clk_id
, flags
, rqtp
->tv_sec
, rqtp
->tv_nsec
,
136 rmtp
? rmtp
->tv_sec
: 0, rmtp
? rmtp
->tv_nsec
: 0);
141 nanosleep (const struct timespec
*rqtp
, struct timespec
*rmtp
)
143 int res
= clock_nanosleep (CLOCK_REALTIME
, 0, rqtp
, rmtp
);
152 extern "C" unsigned int
153 sleep (unsigned int seconds
)
155 struct timespec req
, rem
;
156 req
.tv_sec
= seconds
;
158 if (clock_nanosleep (CLOCK_REALTIME
, 0, &req
, &rem
))
159 return rem
.tv_sec
+ (rem
.tv_nsec
> 0);
163 extern "C" unsigned int
164 usleep (useconds_t useconds
)
167 req
.tv_sec
= useconds
/ 1000000;
168 req
.tv_nsec
= (useconds
% 1000000) * 1000;
169 int res
= clock_nanosleep (CLOCK_REALTIME
, 0, &req
, NULL
);
179 sigprocmask (int how
, const sigset_t
*set
, sigset_t
*oldset
)
181 int res
= handle_sigprocmask (how
, set
, oldset
, _my_tls
.sigmask
);
187 syscall_printf ("%R = sigprocmask (%d, %p, %p)", res
, set
, oldset
);
192 handle_sigprocmask (int how
, const sigset_t
*set
, sigset_t
*oldset
, sigset_t
& opmask
)
194 /* check that how is in right range */
195 if (how
!= SIG_BLOCK
&& how
!= SIG_UNBLOCK
&& how
!= SIG_SETMASK
)
197 syscall_printf ("Invalid how value %d", how
);
202 if (efault
.faulted (EFAULT
))
210 sigset_t newmask
= opmask
;
214 /* add set to current mask */
218 /* remove set from current mask */
226 set_signal_mask (newmask
, opmask
);
232 _pinfo::kill (siginfo_t
& si
)
235 DWORD this_process_state
;
238 sig_dispatch_pending ();
243 this_process_state
= process_state
;
244 if ((sendSIGCONT
= (si
.si_signo
< 0)))
245 si
.si_signo
= -si
.si_signo
;
247 if (si
.si_signo
== 0)
249 else if ((res
= sig_send (this, si
)))
251 sigproc_printf ("%d = sig_send, %E ", res
);
254 else if (sendSIGCONT
)
257 si2
.si_signo
= SIGCONT
;
258 si2
.si_code
= SI_KERNEL
;
259 sig_send (this, si2
);
263 else if (si
.si_signo
== 0 && this && process_state
== PID_EXITED
)
265 this_process_state
= process_state
;
272 this_process_state
= 0;
277 syscall_printf ("%d = _pinfo::kill (%d), pid %d, process_state %p", res
,
278 si
.si_signo
, this_pid
, this_process_state
);
285 return kill (myself
->pid
, sig
);
289 kill0 (pid_t pid
, siginfo_t
& si
)
291 syscall_printf ("kill (%d, %d)", pid
, si
.si_signo
);
292 /* check that sig is in right range */
293 if (si
.si_signo
< 0 || si
.si_signo
>= NSIG
)
296 syscall_printf ("signal %d out of range", si
.si_signo
);
300 return (pid
> 0) ? pinfo (pid
)->kill (si
) : kill_pgrp (-pid
, si
);
304 killsys (pid_t pid
, int sig
)
308 si
.si_code
= SI_KERNEL
;
309 return kill0 (pid
, si
);
313 kill (pid_t pid
, int sig
)
317 si
.si_code
= SI_USER
;
318 return kill0 (pid
, si
);
322 kill_pgrp (pid_t pid
, siginfo_t
& si
)
328 sigproc_printf ("pid %d, signal %d", pid
, si
.si_signo
);
330 winpids
pids ((DWORD
) PID_MAP_RW
);
331 for (unsigned i
= 0; i
< pids
.npids
; i
++)
338 /* Is it a process we want to kill? */
339 if ((pid
== 0 && (p
->pgid
!= myself
->pgid
|| p
->ctty
!= myself
->ctty
)) ||
340 (pid
> 1 && p
->pgid
!= pid
) ||
341 (si
.si_signo
< 0 && NOTSTATE (p
, PID_STOPPED
)))
343 sigproc_printf ("killing pid %d, pgrp %d, p->%s, %s", p
->pid
, p
->pgid
,
344 p
->__ctty (), myctty ());
347 else if (p
->kill (si
))
352 if (killself
&& !exit_state
&& myself
->kill (si
))
360 syscall_printf ("%R = kill(%d, %d)", res
, pid
, si
.si_signo
);
365 killpg (pid_t pgrp
, int sig
)
367 return kill (-pgrp
, sig
);
374 sig_dispatch_pending ();
375 /* Ensure that SIGABRT can be caught regardless of blockage. */
377 sigfillset (&sig_mask
);
378 sigdelset (&sig_mask
, SIGABRT
);
379 set_signal_mask (sig_mask
, _my_tls
.sigmask
);
382 _my_tls
.call_signal_handler (); /* Call any signal handler */
384 /* Flush all streams as per SUSv2. */
385 if (_GLOBAL_REENT
->__cleanup
)
386 _GLOBAL_REENT
->__cleanup (_GLOBAL_REENT
);
387 do_exit (SIGABRT
); /* signal handler didn't exit. Goodbye. */
391 sigaction_worker (int sig
, const struct sigaction
*newact
,
392 struct sigaction
*oldact
, bool isinternal
, const char *fnname
)
396 if (!efault
.faulted (EFAULT
))
398 sig_dispatch_pending ();
399 /* check that sig is in right range */
400 if (sig
< 0 || sig
>= NSIG
)
404 struct sigaction oa
= global_sigs
[sig
];
407 sigproc_printf ("signal %d, newact %p, oa %p", sig
, newact
, oa
, oa
.sa_handler
);
410 sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig
, newact
, newact
->sa_handler
, oa
, oa
.sa_handler
);
411 if (sig
== SIGKILL
|| sig
== SIGSTOP
)
416 struct sigaction na
= *newact
;
417 struct sigaction
& gs
= global_sigs
[sig
];
419 na
.sa_flags
&= ~_SA_INTERNAL_MASK
;
421 if (!(gs
.sa_flags
& SA_NODEFER
))
422 gs
.sa_mask
|= SIGTOMASK(sig
);
423 if (gs
.sa_handler
== SIG_IGN
)
425 if (gs
.sa_handler
== SIG_DFL
&& sig
== SIGCHLD
)
429 myself
->process_state
&= ~PID_NOCLDSTOP
;
430 if (gs
.sa_flags
& SA_NOCLDSTOP
)
431 myself
->process_state
|= PID_NOCLDSTOP
;
438 oa
.sa_flags
&= ~_SA_INTERNAL_MASK
;
445 syscall_printf ("%R = %s(%d, %p, %p)", res
, fnname
, sig
, newact
, oldact
);
450 sigaction (int sig
, const struct sigaction
*newact
, struct sigaction
*oldact
)
452 return sigaction_worker (sig
, newact
, oldact
, false, "sigaction");
456 sigaddset (sigset_t
*set
, const int sig
)
458 /* check that sig is in right range */
459 if (sig
<= 0 || sig
>= NSIG
)
462 syscall_printf ("SIG_ERR = sigaddset signal %d out of range", sig
);
466 *set
|= SIGTOMASK (sig
);
471 sigdelset (sigset_t
*set
, const int sig
)
473 /* check that sig is in right range */
474 if (sig
<= 0 || sig
>= NSIG
)
477 syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig
);
481 *set
&= ~SIGTOMASK (sig
);
486 sigismember (const sigset_t
*set
, int sig
)
488 /* check that sig is in right range */
489 if (sig
<= 0 || sig
>= NSIG
)
492 syscall_printf ("SIG_ERR = sigdelset signal %d out of range", sig
);
496 if (*set
& SIGTOMASK (sig
))
503 sigemptyset (sigset_t
*set
)
510 sigfillset (sigset_t
*set
)
512 *set
= ~((sigset_t
) 0);
517 sigsuspend (const sigset_t
*set
)
519 return handle_sigsuspend (*set
);
523 sigpause (int signal_mask
)
525 return handle_sigsuspend ((sigset_t
) signal_mask
);
531 return handle_sigsuspend (_my_tls
.sigmask
);
535 siginterrupt (int sig
, int flag
)
537 struct sigaction act
;
538 sigaction (sig
, NULL
, &act
);
541 act
.sa_flags
&= ~SA_RESTART
;
542 act
.sa_flags
|= _SA_NORESTART
;
546 act
.sa_flags
&= ~_SA_NORESTART
;
547 act
.sa_flags
|= SA_RESTART
;
549 return sigaction_worker (sig
, &act
, NULL
, true, "siginterrupt");
553 sigwait (const sigset_t
*set
, int *sig_ptr
)
555 int sig
= sigwaitinfo (set
, NULL
);
558 return sig
> 0 ? 0 : -1;
562 sigwaitinfo (const sigset_t
*set
, siginfo_t
*info
)
564 pthread_testcancel ();
566 _my_tls
.sigwait_mask
= *set
;
567 sig_dispatch_pending (true);
570 switch (cancelable_wait (NULL
, NULL
, cw_sig
| cw_cancel
| cw_cancel_self
))
573 if (!sigismember (set
, _my_tls
.infodata
.si_signo
))
581 *info
= _my_tls
.infodata
;
582 res
= _my_tls
.infodata
.si_signo
;
583 InterlockedExchange ((LONG
*) &_my_tls
.sig
, (LONG
) 0);
591 sigproc_printf ("returning signal %d", res
);
595 /* FIXME: SUSv3 says that this function should block until the signal has
596 actually been delivered. Currently, this will only happen when sending
597 signals to the current process. It will not happen when sending signals
598 to other processes. */
600 sigqueue (pid_t pid
, int sig
, const union sigval value
)
610 si
.si_code
= SI_QUEUE
;
612 return sig_send (dest
, si
);
This page took 0.061849 seconds and 5 git commands to generate.