Rizin
unix-like reverse engineering framework and cli tools
signal.c File Reference
#include <assert.h>
#include <signal.h>
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "req-inl.h"

Go to the source code of this file.

Functions

 RB_HEAD (uv_signal_tree_s, uv_signal_s)
 
static BOOL WINAPI uv__signal_control_handler (DWORD type)
 
int uv__signal_start (uv_signal_t *handle, uv_signal_cb signal_cb, int signum, int oneshot)
 
void uv_signals_init (void)
 
void uv__signal_cleanup (void)
 
static int uv__signal_compare (uv_signal_t *w1, uv_signal_t *w2)
 
int uv__signal_dispatch (int signum)
 
int uv_signal_init (uv_loop_t *loop, uv_signal_t *handle)
 
int uv_signal_stop (uv_signal_t *handle)
 
int uv_signal_start (uv_signal_t *handle, uv_signal_cb signal_cb, int signum)
 
int uv_signal_start_oneshot (uv_signal_t *handle, uv_signal_cb signal_cb, int signum)
 
void uv_process_signal_req (uv_loop_t *loop, uv_signal_t *handle, uv_req_t *req)
 
void uv_signal_close (uv_loop_t *loop, uv_signal_t *handle)
 
void uv_signal_endgame (uv_loop_t *loop, uv_signal_t *handle)
 

Variables

static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree)
 
static CRITICAL_SECTION uv__signal_lock
 

Function Documentation

◆ RB_HEAD()

RB_HEAD ( uv_signal_tree_s  ,
uv_signal_s   
)

◆ uv__signal_cleanup()

void uv__signal_cleanup ( void  )

Definition at line 49 of file signal.c.

49  {
50  /* TODO(bnoordhuis) Undo effects of uv_signal_init()? */
51 }

◆ uv__signal_compare()

static int uv__signal_compare ( uv_signal_t w1,
uv_signal_t w2 
)
static

Definition at line 54 of file signal.c.

54  {
55  /* Compare signums first so all watchers with the same signnum end up
56  * adjacent. */
57  if (w1->signum < w2->signum) return -1;
58  if (w1->signum > w2->signum) return 1;
59 
60  /* Sort by loop pointer, so we can easily look up the first item after
61  * { .signum = x, .loop = NULL }. */
62  if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1;
63  if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1;
64 
65  if ((uintptr_t) w1 < (uintptr_t) w2) return -1;
66  if ((uintptr_t) w1 > (uintptr_t) w2) return 1;
67 
68  return 0;
69 }
_W64 unsigned int uintptr_t

References w1, and w2.

◆ uv__signal_control_handler()

static BOOL WINAPI uv__signal_control_handler ( DWORD  type)
static

Definition at line 116 of file signal.c.

116  {
117  switch (type) {
118  case CTRL_C_EVENT:
119  return uv__signal_dispatch(SIGINT);
120 
121  case CTRL_BREAK_EVENT:
122  return uv__signal_dispatch(SIGBREAK);
123 
124  case CTRL_CLOSE_EVENT:
126  /* Windows will terminate the process after the control handler
127  * returns. After that it will just terminate our process. Therefore
128  * block the signal handler so the main loop has some time to pick up
129  * the signal and do something for a few seconds. */
130  Sleep(INFINITE);
131  return TRUE;
132  }
133  return FALSE;
134 
135  case CTRL_LOGOFF_EVENT:
136  case CTRL_SHUTDOWN_EVENT:
137  /* These signals are only sent to services. Services have their own
138  * notification mechanism, so there's no point in handling these. */
139 
140  default:
141  /* We don't handle these. */
142  return FALSE;
143  }
144 }
int type
Definition: mipsasm.c:17
#define TRUE
Definition: mybfd.h:103
#define FALSE
Definition: mybfd.h:102
int uv__signal_dispatch(int signum)
Definition: signal.c:80
#define SIGHUP
Definition: win.h:86

References FALSE, SIGHUP, TRUE, type, and uv__signal_dispatch().

Referenced by uv_signals_init().

◆ uv__signal_dispatch()

int uv__signal_dispatch ( int  signum)

Definition at line 80 of file signal.c.

80  {
81  uv_signal_t lookup;
83  int dispatched;
84 
85  dispatched = 0;
86 
87  EnterCriticalSection(&uv__signal_lock);
88 
89  lookup.signum = signum;
90  lookup.loop = NULL;
91 
92  for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup);
93  handle != NULL && handle->signum == signum;
94  handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) {
95  unsigned long previous = InterlockedExchange(
96  (volatile LONG*) &handle->pending_signum, signum);
97 
99  continue;
100 
101  if (!previous) {
102  POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req);
103  }
104 
105  dispatched = 1;
106  if (handle->flags & UV_SIGNAL_ONE_SHOT)
108  }
109 
110  LeaveCriticalSection(&uv__signal_lock);
111 
112  return dispatched;
113 }
static mcore_handle handle
Definition: asm_mcore.c:8
#define NULL
Definition: cris-opc.c:27
#define LONG
InterlockedExchange
Definition: kernel.h:57
#define RB_NEXT(name, x, y)
Definition: tree.h:731
#define RB_NFIND(name, x, y)
Definition: tree.h:730
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment signum
Definition: sflib.h:79
#define POST_COMPLETION_FOR_REQ(loop, req)
Definition: req-inl.h:76
int signum
Definition: uv.h:1577
static CRITICAL_SECTION uv__signal_lock
Definition: signal.c:33
static struct uv_signal_tree_s uv__signal_tree
Definition: signal.c:32
@ UV_SIGNAL_ONE_SHOT
Definition: uv-common.h:129
@ UV_SIGNAL_ONE_SHOT_DISPATCHED
Definition: uv-common.h:128

References handle, InterlockedExchange, LONG, NULL, POST_COMPLETION_FOR_REQ, RB_NEXT, RB_NFIND, signum, uv_signal_s::signum, uv__signal_lock, uv__signal_tree, UV_SIGNAL_ONE_SHOT, and UV_SIGNAL_ONE_SHOT_DISPATCHED.

Referenced by uv__signal_control_handler(), and uv__tty_console_signal_resize().

◆ uv__signal_start()

int uv__signal_start ( uv_signal_t handle,
uv_signal_cb  signal_cb,
int  signum,
int  oneshot 
)

Definition at line 193 of file signal.c.

196  {
197  /* Test for invalid signal values. */
198  if (signum <= 0 || signum >= NSIG)
199  return UV_EINVAL;
200 
201  /* Short circuit: if the signal watcher is already watching {signum} don't go
202  * through the process of deregistering and registering the handler.
203  * Additionally, this avoids pending signals getting lost in the (small) time
204  * frame that handle->signum == 0. */
205  if (signum == handle->signum) {
206  handle->signal_cb = signal_cb;
207  return 0;
208  }
209 
210  /* If the signal handler was already active, stop it first. */
211  if (handle->signum != 0) {
212  int r = uv_signal_stop(handle);
213  /* uv_signal_stop is infallible. */
214  assert(r == 0);
215  }
216 
217  EnterCriticalSection(&uv__signal_lock);
218 
219  handle->signum = signum;
220  if (oneshot)
221  handle->flags |= UV_SIGNAL_ONE_SHOT;
222 
223  RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
224 
225  LeaveCriticalSection(&uv__signal_lock);
226 
227  handle->signal_cb = signal_cb;
229 
230  return 0;
231 }
static RzBinXtrData * oneshot(RzBin *bin, const ut8 *buf, ut64 size, int subbin_type)
#define r
Definition: crypto_rc6.c:12
#define RB_INSERT(name, x, y)
Definition: tree.h:727
assert(limit<=UINT32_MAX/2)
int uv_signal_stop(uv_signal_t *handle)
Definition: signal.c:513
#define uv__handle_start(h)
Definition: uv-common.h:258
#define NSIG
Definition: win.h:95

References assert(), handle, NSIG, oneshot(), r, RB_INSERT, signum, uv__handle_start, uv__signal_lock, uv__signal_tree, UV_SIGNAL_ONE_SHOT, and uv_signal_stop().

Referenced by uv_signal_start(), and uv_signal_start_oneshot().

◆ uv_process_signal_req()

void uv_process_signal_req ( uv_loop_t loop,
uv_signal_t handle,
uv_req_t req 
)

Definition at line 234 of file signal.c.

235  {
236  long dispatched_signum;
237 
238  assert(handle->type == UV_SIGNAL);
239  assert(req->type == UV_SIGNAL_REQ);
240 
241  dispatched_signum = InterlockedExchange(
242  (volatile LONG*) &handle->pending_signum, 0);
243  assert(dispatched_signum != 0);
244 
245  /* Check if the pending signal equals the signum that we are watching for.
246  * These can get out of sync when the handler is stopped and restarted while
247  * the signal_req is pending. */
248  if (dispatched_signum == handle->signum)
249  handle->signal_cb(handle, dispatched_signum);
250 
251  if (handle->flags & UV_SIGNAL_ONE_SHOT)
253 
254  if (handle->flags & UV_HANDLE_CLOSING) {
255  /* When it is closing, it must be stopped at this point. */
256  assert(handle->signum == 0);
258  }
259 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
static INLINE void uv_want_endgame(uv_loop_t *loop, uv_handle_t *handle)
Definition: handle-inl.h:88
uv_loop_t * loop
Definition: main.c:7
@ UV_HANDLE_CLOSING
Definition: uv-common.h:74

References assert(), handle, InterlockedExchange, LONG, loop, req, UV_HANDLE_CLOSING, UV_SIGNAL_ONE_SHOT, uv_signal_stop(), and uv_want_endgame().

Referenced by uv_process_reqs().

◆ uv_signal_close()

void uv_signal_close ( uv_loop_t loop,
uv_signal_t handle 
)

Definition at line 262 of file signal.c.

262  {
265 
266  if (handle->pending_signum == 0) {
268  }
269 }
#define uv__handle_closing(handle)
Definition: handle-inl.h:63

References handle, loop, uv__handle_closing, uv_signal_stop(), and uv_want_endgame().

Referenced by uv_close().

◆ uv_signal_endgame()

void uv_signal_endgame ( uv_loop_t loop,
uv_signal_t handle 
)

Definition at line 272 of file signal.c.

272  {
273  assert(handle->flags & UV_HANDLE_CLOSING);
274  assert(!(handle->flags & UV_HANDLE_CLOSED));
275 
276  assert(handle->signum == 0);
277  assert(handle->pending_signum == 0);
278 
279  handle->flags |= UV_HANDLE_CLOSED;
280 
282 }
#define uv__handle_close(handle)
Definition: handle-inl.h:76
@ UV_HANDLE_CLOSED
Definition: uv-common.h:75

References assert(), handle, uv__handle_close, UV_HANDLE_CLOSED, and UV_HANDLE_CLOSING.

Referenced by uv_process_endgames().

◆ uv_signal_init()

int uv_signal_init ( uv_loop_t loop,
uv_signal_t handle 
)

Definition at line 147 of file signal.c.

147  {
148  uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
149  handle->pending_signum = 0;
150  handle->signum = 0;
151  handle->signal_cb = NULL;
152 
153  UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ);
154  handle->signal_req.data = handle;
155 
156  return 0;
157 }
#define UV_REQ_INIT(req, typ)
Definition: uv-common.h:322
#define uv__handle_init(loop_, h, type_)
Definition: uv-common.h:301

References err, handle, loop, NULL, uv__handle_init, uv__signal_loop_once_init(), and UV_REQ_INIT.

Referenced by main(), thread1_worker(), thread2_worker(), and uv_loop_init().

◆ uv_signal_start()

int uv_signal_start ( uv_signal_t handle,
uv_signal_cb  signal_cb,
int  signum 
)

Definition at line 181 of file signal.c.

181  {
182  return uv__signal_start(handle, signal_cb, signum, 0);
183 }
int uv__signal_start(uv_signal_t *handle, uv_signal_cb signal_cb, int signum, int oneshot)
Definition: signal.c:193

References handle, signum, and uv__signal_start().

Referenced by main(), thread1_worker(), thread2_worker(), and uv_spawn().

◆ uv_signal_start_oneshot()

int uv_signal_start_oneshot ( uv_signal_t handle,
uv_signal_cb  signal_cb,
int  signum 
)

Definition at line 186 of file signal.c.

188  {
189  return uv__signal_start(handle, signal_cb, signum, 1);
190 }

References handle, signum, and uv__signal_start().

◆ uv_signal_stop()

int uv_signal_stop ( uv_signal_t handle)

Definition at line 160 of file signal.c.

160  {
161  uv_signal_t* removed_handle;
162 
163  /* If the watcher wasn't started, this is a no-op. */
164  if (handle->signum == 0)
165  return 0;
166 
167  EnterCriticalSection(&uv__signal_lock);
168 
169  removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle);
170  assert(removed_handle == handle);
171 
172  LeaveCriticalSection(&uv__signal_lock);
173 
174  handle->signum = 0;
176 
177  return 0;
178 }
#define RB_REMOVE(name, x, y)
Definition: tree.h:728
#define uv__handle_stop(h)
Definition: uv-common.h:266

References assert(), handle, RB_REMOVE, uv__handle_stop, uv__is_closing, uv__signal_lock, uv__signal_stop(), and uv__signal_tree.

Referenced by signal_handler(), and uv__process_close().

◆ uv_signals_init()

void uv_signals_init ( void  )

Definition at line 42 of file signal.c.

42  {
43  InitializeCriticalSection(&uv__signal_lock);
44  if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
45  abort();
46 }
static BOOL WINAPI uv__signal_control_handler(DWORD type)
Definition: signal.c:116

References TRUE, uv__signal_control_handler(), and uv__signal_lock.

Referenced by uv_init().

Variable Documentation

◆ uv__signal_lock

CRITICAL_SECTION uv__signal_lock ( void  )
static

Definition at line 33 of file signal.c.

Referenced by uv__signal_dispatch(), uv__signal_start(), uv_signal_stop(), and uv_signals_init().

◆ uv__signal_tree

struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree)
static

Definition at line 30 of file signal.c.

Referenced by uv__signal_dispatch(), uv__signal_start(), and uv_signal_stop().