1 /* Copyright 1996,1997,2001,2002,2007,2009 Alain Knaff.
2 * This file is part of mtools.
3 *
4 * Mtools is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Mtools 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
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "sysincludes.h"
19 #include "mtools.h"
20
21 #undef got_signal
22
23 int got_signal = 0;
24
signal_handler(int dummy UNUSEDP)25 static void signal_handler(int dummy UNUSEDP)
26 {
27 got_signal = 1;
28 #if 0
29 signal(SIGHUP, SIG_IGN);
30 signal(SIGINT, SIG_IGN);
31 signal(SIGTERM, SIG_IGN);
32 signal(SIGQUIT, SIG_IGN);
33 #endif
34 }
35
36 #if 0
37 int do_gotsignal(char *f, int n)
38 {
39 if(got_signal)
40 fprintf(stderr, "file=%s line=%d\n", f, n);
41 return got_signal;
42 }
43 #endif
44
setup_signal(void)45 void setup_signal(void)
46 {
47 /* catch signals */
48 #ifdef SIGHUP
49 signal(SIGHUP, signal_handler);
50 #endif
51 #ifdef SIGINT
52 signal(SIGINT, signal_handler);
53 #endif
54 #ifdef SIGTERM
55 signal(SIGTERM, signal_handler);
56 #endif
57 #ifdef SIGQUIT
58 signal(SIGQUIT, signal_handler);
59 #endif
60 }
61
62 #ifdef HAVE_SIGACTION
_allow_interrupt(saved_sig_state * ss,int sig,int slot)63 static void _allow_interrupt(saved_sig_state *ss, int sig, int slot)
64 {
65 struct sigaction new;
66
67 bzero(&new, sizeof(new));
68 new.sa_handler = signal_handler;
69 new.sa_flags &= ~SA_RESTART;
70
71 if(sigaction(sig, &new, &ss->sa[slot]) < 0) {
72 perror("sigaction");
73 exit(1);
74 }
75 }
76 #endif
77
78 /* Allow syscalls to be interrupted by signal */
allow_interrupts(saved_sig_state * ss)79 void allow_interrupts(saved_sig_state *ss)
80 {
81 #ifdef HAVE_SIGACTION
82
83 # ifdef SIGHUP
84 _allow_interrupt(ss, SIGINT, 0);
85 # endif
86
87 # ifdef SIGINT
88 _allow_interrupt(ss, SIGINT, 1);
89 # endif
90
91 # ifdef SIGTERM
92 _allow_interrupt(ss, SIGINT, 2);
93 # endif
94
95 # ifdef SIGQUIT
96 _allow_interrupt(ss, SIGINT, 3);
97 # endif
98
99 #endif
100 }
101
102 #ifdef HAVE_SIGACTION
_restore_interrupt(saved_sig_state * ss,int sig,int slot)103 static void _restore_interrupt(saved_sig_state *ss, int sig, int slot)
104 {
105 if(sigaction(sig, &ss->sa[slot], NULL) < 0) {
106 perror("restore sigaction");
107 exit(1);
108 }
109 }
110 #endif
111
112 /* Restore syscalls to be interrupted by signal */
restore_interrupts(saved_sig_state * ss)113 void restore_interrupts(saved_sig_state *ss)
114 {
115 #ifdef HAVE_SIGACTION
116
117 # ifdef SIGHUP
118 _restore_interrupt(ss, SIGINT, 0);
119 # endif
120
121 # ifdef SIGINT
122 _restore_interrupt(ss, SIGINT, 1);
123 # endif
124
125 # ifdef SIGTERM
126 _restore_interrupt(ss, SIGINT, 2);
127 # endif
128
129 # ifdef SIGQUIT
130 _restore_interrupt(ss, SIGINT, 3);
131 # endif
132
133 #endif
134 }
135