Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: xz/src/xz/signals.c

Issue 2869016: Add an unpatched version of xz, XZ Utils, to /trunk/deps/third_party (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « xz/src/xz/signals.h ('k') | xz/src/xz/suffix.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file signals.c
4 /// \brief Handling signals to abort operation
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #include "private.h"
14
15
16 volatile sig_atomic_t user_abort = false;
17
18
19 #if !(defined(_WIN32) && !defined(__CYGWIN__))
20
21 /// If we were interrupted by a signal, we store the signal number so that
22 /// we can raise that signal to kill the program when all cleanups have
23 /// been done.
24 static volatile sig_atomic_t exit_signal = 0;
25
26 /// Mask of signals for which have have established a signal handler to set
27 /// user_abort to true.
28 static sigset_t hooked_signals;
29
30 /// True once signals_init() has finished. This is used to skip blocking
31 /// signals (with uninitialized hooked_signals) if signals_block() and
32 /// signals_unblock() are called before signals_init() has been called.
33 static bool signals_are_initialized = false;
34
35 /// signals_block() and signals_unblock() can be called recursively.
36 static size_t signals_block_count = 0;
37
38
39 static void
40 signal_handler(int sig)
41 {
42 exit_signal = sig;
43 user_abort = true;
44 return;
45 }
46
47
48 extern void
49 signals_init(void)
50 {
51 // List of signals for which we establish the signal handler.
52 static const int sigs[] = {
53 SIGINT,
54 SIGTERM,
55 #ifdef SIGHUP
56 SIGHUP,
57 #endif
58 #ifdef SIGPIPE
59 SIGPIPE,
60 #endif
61 #ifdef SIGXCPU
62 SIGXCPU,
63 #endif
64 #ifdef SIGXFSZ
65 SIGXFSZ,
66 #endif
67 };
68
69 // Mask of the signals for which we have established a signal handler.
70 sigemptyset(&hooked_signals);
71 for (size_t i = 0; i < ARRAY_SIZE(sigs); ++i)
72 sigaddset(&hooked_signals, sigs[i]);
73
74 struct sigaction sa;
75
76 // All the signals that we handle we also blocked while the signal
77 // handler runs.
78 sa.sa_mask = hooked_signals;
79
80 // Don't set SA_RESTART, because we want EINTR so that we can check
81 // for user_abort and cleanup before exiting. We block the signals
82 // for which we have established a handler when we don't want EINTR.
83 sa.sa_flags = 0;
84 sa.sa_handler = &signal_handler;
85
86 for (size_t i = 0; i < ARRAY_SIZE(sigs); ++i) {
87 // If the parent process has left some signals ignored,
88 // we don't unignore them.
89 struct sigaction old;
90 if (sigaction(sigs[i], NULL, &old) == 0
91 && old.sa_handler == SIG_IGN)
92 continue;
93
94 // Establish the signal handler.
95 if (sigaction(sigs[i], &sa, NULL))
96 message_signal_handler();
97 }
98
99 signals_are_initialized = true;
100
101 return;
102 }
103
104
105 #ifndef __VMS
106 extern void
107 signals_block(void)
108 {
109 if (signals_are_initialized) {
110 if (signals_block_count++ == 0) {
111 const int saved_errno = errno;
112 mythread_sigmask(SIG_BLOCK, &hooked_signals, NULL);
113 errno = saved_errno;
114 }
115 }
116
117 return;
118 }
119
120
121 extern void
122 signals_unblock(void)
123 {
124 if (signals_are_initialized) {
125 assert(signals_block_count > 0);
126
127 if (--signals_block_count == 0) {
128 const int saved_errno = errno;
129 mythread_sigmask(SIG_UNBLOCK, &hooked_signals, NULL);
130 errno = saved_errno;
131 }
132 }
133
134 return;
135 }
136 #endif
137
138
139 extern void
140 signals_exit(void)
141 {
142 const int sig = exit_signal;
143
144 if (sig != 0) {
145 struct sigaction sa;
146 sa.sa_handler = SIG_DFL;
147 sigfillset(&sa.sa_mask);
148 sa.sa_flags = 0;
149 sigaction(sig, &sa, NULL);
150 raise(exit_signal);
151 }
152
153 return;
154 }
155
156 #else
157
158 // While Windows has some very basic signal handling functions as required
159 // by C89, they are not really used, and e.g. SIGINT doesn't work exactly
160 // the way it does on POSIX (Windows creates a new thread for the signal
161 // handler). Instead, we use SetConsoleCtrlHandler() to catch user
162 // pressing C-c, because that seems to be the recommended way to do it.
163 //
164 // NOTE: This doesn't work under MSYS. Trying with SIGINT doesn't work
165 // either even if it appeared to work at first. So test using Windows
166 // console window.
167
168 static BOOL WINAPI
169 signal_handler(DWORD type lzma_attribute((unused)))
170 {
171 // Since we don't get a signal number which we could raise() at
172 // signals_exit() like on POSIX, just set the exit status to
173 // indicate an error, so that we cannot return with zero exit status.
174 set_exit_status(E_ERROR);
175 user_abort = true;
176 return TRUE;
177 }
178
179
180 extern void
181 signals_init(void)
182 {
183 if (!SetConsoleCtrlHandler(&signal_handler, TRUE))
184 message_signal_handler();
185
186 return;
187 }
188
189 #endif
OLDNEW
« no previous file with comments | « xz/src/xz/signals.h ('k') | xz/src/xz/suffix.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698