static void fatal_signal_init(void) { static bool inited = false; if (!inited) { size_t i; inited = true; xpipe(signal_fds); set_nonblocking(signal_fds[0]); set_nonblocking(signal_fds[1]); sigemptyset(&fatal_signal_set); for (i = 0; i < ARRAY_SIZE(fatal_signals); i++) { int sig_nr = fatal_signals[i]; struct sigaction old_sa; sigaddset(&fatal_signal_set, sig_nr); xsigaction(sig_nr, NULL, &old_sa); if (old_sa.sa_handler == SIG_DFL && signal(sig_nr, fatal_signal_handler) == SIG_ERR) { VLOG_FATAL("signal failed (%s)", strerror(errno)); } } atexit(atexit_handler); } }
/* Initializes the fatal signal handling module. Calling this function is * optional, because calling any other function in the module will also * initialize it. However, in a multithreaded program, the module must be * initialized while the process is still single-threaded. */ void fatal_signal_init(void) { static bool inited = false; if (!inited) { size_t i; assert_single_threaded(); inited = true; ovs_mutex_init_recursive(&mutex); xpipe_nonblocking(signal_fds); for (i = 0; i < ARRAY_SIZE(fatal_signals); i++) { int sig_nr = fatal_signals[i]; struct sigaction old_sa; xsigaction(sig_nr, NULL, &old_sa); if (old_sa.sa_handler == SIG_DFL && signal(sig_nr, fatal_signal_handler) == SIG_ERR) { VLOG_FATAL("signal failed (%s)", ovs_strerror(errno)); } } atexit(atexit_handler); } }
int main(int argc, char **argv) { struct sigaction sa; #ifndef __gnu_hurd__ int fd; #endif get_options(argc, argv); sa.sa_flags = 0; sa.sa_handler = handle_signal; (void)sigemptyset(&sa.sa_mask); xsigaction(SIGINT, &sa, NULL); xsigaction(SIGTERM, &sa, NULL); xsigaction(SIGALRM, &sa, NULL); (void)alarm(TIMEOUT); if (access(CLIENT_CONF_FILE, F_OK) == -1) write_file(CLIENT_CONF_FILE, DEFAULT_CLIENT_CONF); if (access(SERVER_CONF_FILE, F_OK) == -1) write_file(SERVER_CONF_FILE, DEFAULT_SERVER_CONF); create_fifo(); xatexit(remove_fifo); /* * Make sure there's a FIFO reader when the server starts up, in order * to avoid having to wait ten seconds until the server notices that we * opened the FIFO for reading (in the cat_fifo() function). GNU Hurd * doesn't like this trick, though. */ #ifndef __gnu_hurd__ fd = open(COMMAND_FILE, O_RDONLY | O_NONBLOCK); #endif run_command(join(SERVER_COMMAND_LINE, getenv("NSCA_SERVER_FLAGS"))); xatexit(kill_server); run_command(join(CLIENT_COMMAND_LINE, getenv("NSCA_CLIENT_FLAGS"))); cat_fifo(expected_num_lines); #ifndef __gnu_hurd__ (void)close(fd); #endif return EXIT_SUCCESS; }
/* Initializes the fatal signal handling module. Calling this function is * optional, because calling any other function in the module will also * initialize it. However, in a multithreaded program, the module must be * initialized while the process is still single-threaded. */ void fatal_signal_init(void) { static bool inited = false; if (!inited) { size_t i; assert_single_threaded(); inited = true; ovs_mutex_init_recursive(&mutex); #ifndef _WIN32 xpipe_nonblocking(signal_fds); #else wevent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!wevent) { char *msg_buf = ovs_lasterror_to_string(); VLOG_FATAL("Failed to create a event (%s).", msg_buf); } /* Register a function to handle Ctrl+C. */ SetConsoleCtrlHandler(ConsoleHandlerRoutine, true); #endif for (i = 0; i < ARRAY_SIZE(fatal_signals); i++) { int sig_nr = fatal_signals[i]; #ifndef _WIN32 struct sigaction old_sa; xsigaction(sig_nr, NULL, &old_sa); if (old_sa.sa_handler == SIG_DFL && signal(sig_nr, fatal_signal_handler) == SIG_ERR) { VLOG_FATAL("signal failed (%s)", ovs_strerror(errno)); } #else if (signal(sig_nr, fatal_signal_handler) == SIG_ERR) { VLOG_FATAL("signal failed (%s)", ovs_strerror(errno)); } #endif } atexit(fatal_signal_atexit_handler); } }
/* Sets up a handler for 'signr' and returns a structure that represents it. * * Only one handler for a given signal may be registered. */ struct signal * signal_register(int signr) { struct sigaction sa; struct signal *s; ovs_assert(signr >= 1 && signr < N_SIGNALS); /* Create a pipe. */ s = &signals[signr]; ovs_assert(!s->fds[0] && !s->fds[1]); xpipe_nonblocking(s->fds); /* Install signal handler. */ memset(&sa, 0, sizeof sa); sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; xsigaction(signr, &sa, NULL); return s; }
/** * This function should initialise the server, * and it not invoked after a re-exec. * * @return Non-zero on error */ int initialise_server(void) { struct vt_mode mode; char* display_env; int primary_socket_fd; int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" "Length: 38\n" "\n" "Command: get-vt\n" "Command: configure-vt\n"; const char* const secondary_message = "Command: intercept\n" "Message ID: 0\n" "Priority: -4611686018427387904\n" /* −2⁶² */ "Length: 22\n" "\n" "Command: switching-vt\n"; primary_socket_fd = socket_fd; fail_if (connect_to_display()); secondary_socket_fd = socket_fd; socket_fd = primary_socket_fd; display_env = getenv("MDS_DISPLAY"); display_env = display_env ? strchr(display_env, ':') : NULL; if ((display_env == NULL) || (strlen(display_env) < 2)) goto no_display; memset(vtfile_path, 0, sizeof(vtfile_path)); xsnprintf(vtfile_path, "%s/%s.vt", MDS_RUNTIME_ROOT_DIRECTORY, display_env + 1); stage = 1; if (is_respawn == 0) { display_vt = select_vt(); fail_if (display_vt < 0); display_tty_fd = vt_open(display_vt, &old_vt_stat); fail_if (write_vt_file() < 0); fail_if (vt_set_active(display_vt) < 0); } else { fail_if (read_vt_file() < 0); vt_is_active = (display_vt == vt_get_active()); fail_if (vt_is_active < 0); } fail_if (full_send(secondary_socket_fd, secondary_message, strlen(secondary_message))); fail_if (full_send(socket_fd, message, strlen(message))); fail_if (server_initialised() < 0); fail_if (mds_message_initialise(&received)); stage = 2; fail_if (xsigaction(SIGRTMIN + 2, received_switch_vt) < 0); fail_if (xsigaction(SIGRTMIN + 3, received_switch_vt) < 0); vt_construct_mode(1, SIGRTMIN + 2, SIGRTMIN + 3, &mode); fail_if (vt_get_set_mode(display_tty_fd, 1, &mode) < 0); if (vt_set_exclusive(display_tty_fd, 1) < 0) xperror(*argv); return 0; no_display: eprint("no display has been set, how did this happen."); return 1; fail: xperror(*argv); if (stage >= 1) unlink(vtfile_path); if (display_tty_fd >= 0) vt_close(display_tty_fd, &old_vt_stat); if (stage >= 2) mds_message_destroy(&received); return 1; }