blob: 175876a16e783b46696bfeae183c420375e57819 [file] [log] [blame]
Alistair Delvabeaee832021-02-24 11:27:23 -08001/* 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
23int got_signal = 0;
24
25static 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
37int 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
45void 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
63static void _allow_interrupt(saved_sig_state *ss, int sig, int slot)
64{
65 struct sigaction new;
66
Yi Kong39bbd962022-01-09 19:41:38 +080067 memset(&new, 0, sizeof(new));
Alistair Delvabeaee832021-02-24 11:27:23 -080068 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 */
79void 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
103static 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 */
113void 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}