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