77d61ce0e08d55b1504681f809fcfb4b8e3519cc
[mmh] / sbr / signals.c
1 /*
2 ** signals.c -- general signals interface for nmh
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <h/mh.h>
10 #include <h/signals.h>
11
12
13 int
14 SIGPROCMASK(int how, const sigset_t *set, sigset_t *oset)
15 {
16 #ifdef POSIX_SIGNALS
17         return sigprocmask(how, set, oset);
18 #else
19 # ifdef BSD_SIGNALS
20         switch(how) {
21         case SIG_BLOCK:
22                 *oset = sigblock(*set);
23                 break;
24         case SIG_UNBLOCK:
25                 sigfillset(*oset);
26                 *oset = sigsetmask(*oset);
27                 sigsetmask(*oset & ~(*set));
28                 break;
29         case SIG_SETMASK:
30                 *oset = sigsetmask(*set);
31                 break;
32         default:
33                 adios(NULL, "unknown flag in SIGPROCMASK");
34                 break;
35         }
36         return 0;
37 # endif
38 #endif
39 }
40
41
42 /*
43 ** A version of the function `signal' that uses reliable
44 ** signals, if the machine supports them.  Also, (assuming
45 ** OS support), it restarts interrupted system calls for all
46 ** signals except SIGALRM.
47 */
48
49 SIGNAL_HANDLER
50 SIGNAL(int sig, SIGNAL_HANDLER func)
51 {
52 #ifdef POSIX_SIGNALS
53         struct sigaction act, oact;
54
55         act.sa_handler = func;
56         sigemptyset(&act.sa_mask);
57         act.sa_flags = 0;
58
59         if (sig == SIGALRM) {
60 # ifdef SA_INTERRUPT
61                 act.sa_flags |= SA_INTERRUPT;  /* SunOS */
62 # endif
63         } else {
64 # ifdef SA_RESTART
65                 act.sa_flags |= SA_RESTART;  /* SVR4, BSD4.4 */
66 # endif
67         }
68         if (sigaction(sig, &act, &oact) < 0)
69                 return (SIG_ERR);
70         return (oact.sa_handler);
71 #else
72         return signal(sig, func);
73 #endif
74 }
75
76
77 /*
78 ** A version of the function `signal' that will set
79 ** the handler of `sig' to `func' if the signal is
80 ** not currently set to SIG_IGN.  Also uses reliable
81 ** signals if available.
82 */
83 SIGNAL_HANDLER
84 SIGNAL2(int sig, SIGNAL_HANDLER func)
85 {
86 #ifdef POSIX_SIGNALS
87         struct sigaction act, oact;
88
89         if (sigaction(sig, NULL, &oact) < 0)
90                 return (SIG_ERR);
91         if (oact.sa_handler != SIG_IGN) {
92                 act.sa_handler = func;
93                 sigemptyset(&act.sa_mask);
94                 act.sa_flags = 0;
95
96                 if (sig == SIGALRM) {
97 # ifdef SA_INTERRUPT
98                         act.sa_flags |= SA_INTERRUPT;  /* SunOS */
99 # endif
100                 } else {
101 # ifdef SA_RESTART
102                         act.sa_flags |= SA_RESTART;  /* SVR4, BSD4.4 */
103 # endif
104                 }
105                 if (sigaction(sig, &act, &oact) < 0)
106                         return (SIG_ERR);
107         }
108         return (oact.sa_handler);
109 #else
110         SIGNAL_HANDLER ofunc;
111
112         if ((ofunc = signal(sig, SIG_IGN)) != SIG_IGN)
113                 signal(sig, func);
114         return ofunc;
115 #endif
116 }