/* void catch_signal(int sig, int code, struct sigcontext *scp) { */ void catch_signal(int sig) { char *sptr; cStr *sigstr; cData arg1; Bool do_shutdown = NO; signal(sig, catch_signal); sptr = sig_name(sig); sigstr = string_from_chars(sptr, strlen(sptr)); write_err("Caught signal %d: %S", sig, sigstr); string_discard(sigstr); /* figure out what to do */ switch (sig) { #ifdef __UNIX__ case SIGHUP: atomic = NO; handle_connection_output(); flush_files(); #endif #ifndef __MSVC__ case SIGUSR2: /* let the db do what it wants from here */ break; case SIGUSR1: { cData *d; cList *l; /* First cancel all preempted and suspended tasks */ l = vm_list(); for (d = list_first(l); d; d = list_next(l, d)) { /* boggle */ if (d->type != INTEGER) continue; vm_cancel(d->u.val); } list_discard(l); /* now cancel the current task if it is valid */ if (vm_lookup(task_id) != NULL) { vm_cancel(task_id); } /* jump back to the main loop */ longjmp(main_jmp, 1); break; } #endif case SIGILL: /* lets panic and hopefully shutdown without frobbing the db */ panic(sig_name(sig)); break; case SIGTERM: if (running) { write_err("*** Attempting normal shutdown ***"); running = NO; /* jump back to the main loop, ignore any current tasks; *drip*, *drip*, leaky */ longjmp(main_jmp, 1); } else { panic(sig_name(sig)); } break; default: do_shutdown = YES; break; } /* only pass onto the db if we are 'executing' */ if (!running) return; /* send a message to the system object */ arg1.type = SYMBOL; arg1.u.symbol = ident_get(sptr); vm_task(SYSTEM_OBJNUM, signal_id, 1, &arg1); if (do_shutdown) running = NO; }
static void vm_list_handler(RPC* rpc, int size, void* context, void(*callback)(RPC* rpc, uint32_t* ids, int size)) { uint32_t ids[16]; size = vm_list(ids, size <= 16 ? size : 16); callback(rpc, ids, size); }