47ZEND_API size_t zend_signal_globals_offset;
49ZEND_API zend_signal_globals_t zend_signal_globals;
52#define SIGNAL_BEGIN_CRITICAL() \
54 zend_sigprocmask(SIG_BLOCK, &global_sigmask, &oldmask);
55#define SIGNAL_END_CRITICAL() \
56 zend_sigprocmask(SIG_SETMASK, &oldmask, NULL);
59# define zend_sigprocmask(signo, set, oldset) tsrm_sigmask((signo), (set), (oldset))
61# define zend_sigprocmask(signo, set, oldset) sigprocmask((signo), (set), (oldset))
64static void zend_signal_handler(
int signo, siginfo_t *siginfo,
void *
context);
65static zend_result zend_signal_register(
int signo,
void (*
handler)(
int, siginfo_t*,
void*));
67#if defined(__CYGWIN__) || defined(__PASE__)
69#define TIMEOUT_SIG SIGALRM
71#define TIMEOUT_SIG SIGPROF
76#define SA_FLAGS_MASK ~(SA_NODEFER | SA_RESETHAND)
79static zend_signal_entry_t global_orig_handlers[
NSIG];
80static sigset_t global_sigmask;
84static void zend_signal_handler_defer(
int signo, siginfo_t *siginfo,
void *
context)
86 int errno_save =
errno;
87 zend_signal_queue_t *queue, *qtmp;
93 if (tsrm_is_shutdown() || !tsrm_is_managed_thread()) {
95 zend_signal_handler(signo, siginfo,
context);
107 zend_signal_handler(signo, siginfo,
context);
113 zend_signal_handler(queue->zend_signal.signo, queue->zend_signal.siginfo, queue->zend_signal.context);
115 queue->next = SIGG(pavail);
116 queue->zend_signal.signo = 0;
117 SIGG(pavail) = queue;
125 if ((queue = SIGG(pavail))) {
126 SIGG(pavail) = queue->next;
127 queue->zend_signal.signo = signo;
128 queue->zend_signal.siginfo = siginfo;
129 queue->zend_signal.context =
context;
132 if (SIGG(phead) && SIGG(ptail)) {
133 SIGG(ptail)->next = queue;
147 zend_signal_handler(signo, siginfo,
context);
155ZEND_API void zend_signal_handler_unblock(
void)
157 zend_signal_queue_t *queue;
161 SIGNAL_BEGIN_CRITICAL();
163 SIGG(phead) = queue->next;
165 queue->next = SIGG(pavail);
166 queue->zend_signal.signo = 0;
167 SIGG(pavail) = queue;
170 SIGNAL_END_CRITICAL();
178static void zend_signal_handler(
int signo, siginfo_t *siginfo,
void *
context)
180 int errno_save =
errno;
183 zend_signal_entry_t p_sig;
185 if (tsrm_is_shutdown() || !tsrm_is_managed_thread()) {
186 p_sig = global_orig_handlers[signo-1];
191 if (p_sig.handler ==
SIG_DFL) {
192 if (sigaction(signo,
NULL, &sa) == 0) {
194 sigemptyset(&sa.sa_mask);
196 sigemptyset(&sigset);
197 sigaddset(&sigset, signo);
199 if (sigaction(signo, &sa,
NULL) == 0) {
203# define RAISE_ERROR "raise() failed\n"
204 if (raise(signo) != 0) {
206 kill(getpid(), signo);
209 kill(getpid(), signo);
213 }
else if (p_sig.handler !=
SIG_IGN) {
214 if (p_sig.flags & SA_SIGINFO) {
215 if (p_sig.flags & SA_RESETHAND) {
219 (*(
void (*)(int, siginfo_t*,
void*))p_sig.handler)(signo, siginfo,
context);
221 (*(
void (*)(int))p_sig.handler)(signo);
235 if (oldact !=
NULL) {
236 oldact->sa_flags = SIGG(
handlers)[signo-1].flags;
237 oldact->sa_handler = (
void *) SIGG(
handlers)[signo-1].handler;
238 oldact->sa_mask = global_sigmask;
241 SIGG(
handlers)[signo-1].flags = act->sa_flags;
242 if (act->sa_flags & SA_SIGINFO) {
243 SIGG(
handlers)[signo-1].handler = (
void *) act->sa_sigaction;
245 SIGG(
handlers)[signo-1].handler = (
void *) act->sa_handler;
248 memset(&sa, 0,
sizeof(sa));
250 sa.sa_sigaction = (
void *)
SIG_IGN;
252 sa.sa_flags = SA_ONSTACK | SA_SIGINFO | (act->sa_flags & SA_FLAGS_MASK);
253 sa.sa_sigaction = zend_signal_handler_defer;
254 sa.sa_mask = global_sigmask;
257 if (sigaction(signo, &sa,
NULL) < 0) {
262 sigemptyset(&sigset);
263 sigaddset(&sigset, signo);
275 memset(&sa, 0,
sizeof(sa));
278 sa.sa_mask = global_sigmask;
288static zend_result zend_signal_register(
int signo,
void (*
handler)(
int, siginfo_t*,
void*))
292 if (sigaction(signo,
NULL, &sa) == 0) {
293 if ((sa.sa_flags & SA_SIGINFO) && sa.sa_sigaction ==
handler) {
297 SIGG(
handlers)[signo-1].flags = sa.sa_flags;
298 if (sa.sa_flags & SA_SIGINFO) {
299 SIGG(
handlers)[signo-1].handler = (
void *)sa.sa_sigaction;
301 SIGG(
handlers)[signo-1].handler = (
void *)sa.sa_handler;
304 sa.sa_flags = SA_SIGINFO;
306 sa.sa_mask = global_sigmask;
308 if (sigaction(signo, &sa,
NULL) < 0) {
323 memcpy(&SIGG(
handlers), &global_orig_handlers,
sizeof(global_orig_handlers));
326 for (x = 0; x <
sizeof(zend_sigs) /
sizeof(*zend_sigs); x++) {
327 zend_signal_register(zend_sigs[x], zend_signal_handler_defer);
342 if (SIGG(depth) != 0) {
347 for (x = 0; x <
sizeof(zend_sigs) /
sizeof(*zend_sigs); x++) {
348 sigaction(zend_sigs[x],
NULL, &sa);
349 if (sa.sa_sigaction != zend_signal_handler_defer &&
350 sa.sa_sigaction != (
void *)
SIG_IGN) {
358 *((
volatile int *) &SIGG(
active)) = 0;
365 if (SIGG(phead) && SIGG(ptail)) {
366 SIGG(ptail)->next = SIGG(pavail);
367 SIGG(pavail) = SIGG(phead);
374static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals)
378 memset(zend_signal_globals, 0,
sizeof(*zend_signal_globals));
379 zend_signal_globals->reset = 1;
381 for (x = 0; x <
sizeof(zend_signal_globals->pstorage) /
sizeof(*zend_signal_globals->pstorage); ++x) {
382 zend_signal_queue_t *queue = &zend_signal_globals->pstorage[x];
383 queue->zend_signal.signo = 0;
384 queue->next = zend_signal_globals->pavail;
385 zend_signal_globals->pavail = queue;
396 memset(&global_orig_handlers, 0,
sizeof(global_orig_handlers));
397 for (signo = 1; signo <
NSIG; ++signo) {
398 if (sigaction(signo,
NULL, &sa) == 0) {
399 global_orig_handlers[signo-1].flags = sa.sa_flags;
400 if (sa.sa_flags & SA_SIGINFO) {
401 global_orig_handlers[signo-1].handler = (
void *) sa.sa_sigaction;
403 global_orig_handlers[signo-1].handler = (
void *) sa.sa_handler;
416 ts_allocate_fast_id(&zend_signal_globals_id, &zend_signal_globals_offset,
sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor,
NULL);
418 zend_signal_globals_ctor(&zend_signal_globals);
422 sigfillset(&global_sigmask);
423 sigdelset(&global_sigmask,
SIGILL);
424 sigdelset(&global_sigmask,
SIGABRT);
425 sigdelset(&global_sigmask,
SIGFPE);
426 sigdelset(&global_sigmask,
SIGKILL);
427 sigdelset(&global_sigmask,
SIGSEGV);
428 sigdelset(&global_sigmask,
SIGCONT);
429 sigdelset(&global_sigmask,
SIGSTOP);
430 sigdelset(&global_sigmask,
SIGTSTP);
431 sigdelset(&global_sigmask,
SIGTTIN);
432 sigdelset(&global_sigmask,
SIGTTOU);
434 sigdelset(&global_sigmask,
SIGBUS);
437 sigdelset(&global_sigmask,
SIGSYS);
440 sigdelset(&global_sigmask,
SIGTRAP);
reset(array|object &$array)
memset(ptr, 0, type->size)
php_output_handler * active
php_output_handler * running
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format,...)
ZEND_API ZEND_COLD void zend_output_debug_string(bool trigger_break, const char *format,...)
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
#define EXPECTED(condition)
#define UNEXPECTED(condition)
#define zend_signal_activate()
#define zend_signal_deactivate()
#define zend_signal_startup()
#define zend_sigaction(signo, act, oldact)
#define zend_signal_init()
#define zend_signal(signo, handler)
ZEND_RESULT_CODE zend_result
fbc internal_function handler(call, ret)