void delegate_signal_to_ruby(int signal) { VALUE signal_module = rb_const_get(rb_cObject, rb_intern("Signal")); if (rb_funcall(signal_module, rb_intern("handles?"), 1, INT2FIX(signal)) == Qtrue) { rb_funcall(signal_module, rb_intern("handle"), 1, INT2FIX(signal)); } else { ruby_default_signal(signal); } }
int ruby_cleanup(int ex) { int state; volatile VALUE errs[2]; rb_thread_t *th = GET_THREAD(); int nerr; errs[1] = th->errinfo; th->safe_level = 0; Init_stack((void*)&errs[STACK_UPPER(errs, 0, 1)]); PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { SAVE_ROOT_JMPBUF(th, ruby_finalize_0()); } POP_TAG(); errs[0] = th->errinfo; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all()); } else if (ex == 0) { ex = state; } th->errinfo = errs[1]; ex = error_handle(ex); ruby_finalize_1(); POP_TAG(); rb_thread_stop_timer_thread(); for (nerr = 0; nerr < sizeof(errs) / sizeof(errs[0]); ++nerr) { VALUE err = errs[nerr]; if (!RTEST(err)) continue; /* th->errinfo contains a NODE while break'ing */ if (TYPE(err) == T_NODE) continue; if (rb_obj_is_kind_of(err, rb_eSystemExit)) { return sysexit_status(err); } else if (rb_obj_is_kind_of(err, rb_eSignal)) { VALUE sig = rb_iv_get(err, "signo"); ruby_default_signal(NUM2INT(sig)); } else if (ex == 0) { ex = 1; } } #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1 switch (ex) { #if EXIT_SUCCESS != 0 case 0: return EXIT_SUCCESS; #endif #if EXIT_FAILURE != 1 case 1: return EXIT_FAILURE; #endif } #endif return ex; }