Rizin
unix-like reverse engineering framework and cli tools
signals.h File Reference

Handling signals to abort operation. More...

Go to the source code of this file.

Functions

void signals_init (void)
 
void signals_block (void)
 
void signals_unblock (void)
 Unblock the signals blocked by signals_block(). More...
 
void signals_exit (void)
 

Variables

volatile sig_atomic_t user_abort
 

Detailed Description

Handling signals to abort operation.

Definition in file signals.h.

Function Documentation

◆ signals_block()

void signals_block ( void  )

Block the signals which don't have SA_RESTART and which would just set user_abort to true. This is handy when we don't want to handle EINTR and don't want SA_RESTART either.

Definition at line 120 of file signals.c.

121 {
123  if (signals_block_count++ == 0) {
124  const int saved_errno = errno;
125  mythread_sigmask(SIG_BLOCK, &hooked_signals, NULL);
126  errno = saved_errno;
127  }
128  }
129 
130  return;
131 }
#define NULL
Definition: cris-opc.c:27
static void mythread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset)
Definition: mythread.h:87
static size_t signals_block_count
signals_block() and signals_unblock() can be called recursively.
Definition: signals.c:36
static bool signals_are_initialized
Definition: signals.c:33
static sigset_t hooked_signals
Definition: signals.c:28

References hooked_signals, mythread_sigmask(), NULL, signals_are_initialized, and signals_block_count.

Referenced by io_close(), io_open_dest(), io_open_src(), io_open_src_real(), message_progress_update(), print_filename(), progress_flush(), and vmessage().

◆ signals_exit()

void signals_exit ( void  )

If user has sent us a signal earlier to terminate the process, re-raise that signal to actually terminate the process.

Definition at line 153 of file signals.c.

154 {
155  const int sig = (int)exit_signal;
156 
157  if (sig != 0) {
158 #if defined(TUKLIB_DOSLIKE) || defined(__VMS)
159  // Don't raise(), set only exit status. This avoids
160  // printing unwanted message about SIGINT when the user
161  // presses C-c.
163 #else
164  struct sigaction sa;
165  sa.sa_handler = SIG_DFL;
166  sigfillset(&sa.sa_mask);
167  sa.sa_flags = 0;
168  sigaction(sig, &sa, NULL);
169  raise(sig);
170 #endif
171  }
172 
173  return;
174 }
static int
Definition: sfsocketcall.h:114
static volatile sig_atomic_t exit_signal
Definition: signals.c:24
void set_exit_status(enum exit_status_type new_status)
Definition: main.c:31
@ E_ERROR
Definition: transport.h:23

References E_ERROR, exit_signal, int, NULL, and set_exit_status().

Referenced by main().

◆ signals_init()

void signals_init ( void  )

Initialize the signal handler, which will set user_abort to true when user e.g. presses C-c.

Definition at line 54 of file signals.c.

55 {
56  // List of signals for which we establish the signal handler.
57  static const int sigs[] = {
58  SIGINT,
59  SIGTERM,
60 #ifdef SIGHUP
61  SIGHUP,
62 #endif
63 #ifdef SIGPIPE
64  SIGPIPE,
65 #endif
66 #ifdef SIGXCPU
67  SIGXCPU,
68 #endif
69 #ifdef SIGXFSZ
70  SIGXFSZ,
71 #endif
72  };
73 
74  // Mask of the signals for which we have established a signal handler.
75  sigemptyset(&hooked_signals);
76  for (size_t i = 0; i < ARRAY_SIZE(sigs); ++i)
77  sigaddset(&hooked_signals, sigs[i]);
78 
79 #ifdef SIGALRM
80  // Add also the signals from message.c to hooked_signals.
81  for (size_t i = 0; message_progress_sigs[i] != 0; ++i)
83 #endif
84 
85  // Using "my_sa" because "sa" may conflict with a sockaddr variable
86  // from system headers on Solaris.
87  struct sigaction my_sa;
88 
89  // All the signals that we handle we also blocked while the signal
90  // handler runs.
91  my_sa.sa_mask = hooked_signals;
92 
93  // Don't set SA_RESTART, because we want EINTR so that we can check
94  // for user_abort and cleanup before exiting. We block the signals
95  // for which we have established a handler when we don't want EINTR.
96  my_sa.sa_flags = 0;
97  my_sa.sa_handler = &signal_handler;
98 
99  for (size_t i = 0; i < ARRAY_SIZE(sigs); ++i) {
100  // If the parent process has left some signals ignored,
101  // we don't unignore them.
102  struct sigaction old;
103  if (sigaction(sigs[i], NULL, &old) == 0
104  && old.sa_handler == SIG_IGN)
105  continue;
106 
107  // Establish the signal handler.
108  if (sigaction(sigs[i], &my_sa, NULL))
110  }
111 
113 
114  return;
115 }
#define ARRAY_SIZE(a)
lzma_index ** i
Definition: index.h:629
void message_signal_handler(void)
Definition: message.c:796
const int message_progress_sigs[]
Signals used for progress message handling.
static void signal_handler(int sig)
Definition: signals.c:40
#define SIGHUP
Definition: win.h:86

References ARRAY_SIZE, hooked_signals, i, message_progress_sigs, message_signal_handler(), NULL, SIGHUP, signal_handler(), and signals_are_initialized.

Referenced by main().

◆ signals_unblock()

void signals_unblock ( void  )

Unblock the signals blocked by signals_block().

Definition at line 135 of file signals.c.

136 {
139 
140  if (--signals_block_count == 0) {
141  const int saved_errno = errno;
142  mythread_sigmask(SIG_UNBLOCK, &hooked_signals, NULL);
143  errno = saved_errno;
144  }
145  }
146 
147  return;
148 }
assert(limit<=UINT32_MAX/2)

References assert(), hooked_signals, mythread_sigmask(), NULL, signals_are_initialized, and signals_block_count.

Referenced by io_close(), io_open_dest(), io_open_src(), io_open_src_real(), message_progress_update(), print_filename(), progress_flush(), and vmessage().

Variable Documentation

◆ user_abort

volatile sig_atomic_t user_abort
extern

If this is true, we will clean up the possibly incomplete output file, return to main() as soon as practical. That is, the code needs to poll this variable in various places.

Definition at line 16 of file signals.c.

Referenced by coder_normal(), coder_passthru(), coder_run(), io_read(), io_wait(), io_write_buf(), main(), read_name(), and signal_handler().