/* Registers 'hook' to be called when a process termination signal is raised. * If 'run_at_exit' is true, 'hook' is also called during normal process * termination, e.g. when exit() is called or when main() returns. */ void fatal_signal_add_hook(void (*func)(void *aux), void *aux, bool run_at_exit) { fatal_signal_block(); assert(n_hooks < MAX_HOOKS); hooks[n_hooks].func = func; hooks[n_hooks].aux = aux; hooks[n_hooks].run_at_exit = run_at_exit; n_hooks++; fatal_signal_unblock(); }
/* Unregisters 'file' from being unlinked when the program terminates via * exit() or a fatal signal. */ void fatal_signal_remove_file_to_unlink(const char *file) { size_t i; fatal_signal_block(); for (i = 0; i < n_files; i++) { if (!strcmp(files[i], file)) { free(files[i]); files[i] = files[--n_files]; break; } } fatal_signal_unblock(); }
/* Registers 'file' to be unlinked when the program terminates via exit() or a * fatal signal. */ void fatal_signal_add_file_to_unlink(const char *file) { static bool added_hook = false; if (!added_hook) { added_hook = true; fatal_signal_add_hook(unlink_files, NULL, true); fatal_signal_add_hook(destroy_pipeline, NULL, true); } fatal_signal_block(); if (n_files >= max_files) { files = x2nrealloc(files, &max_files, sizeof *files); } files[n_files++] = xstrdup(file); fatal_signal_unblock(); }
int main(int argc, char *argv[]) { struct dhclient *cli; int error; set_program_name(argv[0]); register_fault_handlers(); vlog_init(); parse_options(argc, argv); argc -= optind; argv += optind; if (argc != 1) { ofp_fatal(0, "exactly one non-option argument required; " "use --help for help"); } error = dhclient_create(argv[0], modify_dhcp_request, NULL, NULL, &cli); if (error) { ofp_fatal(error, "dhclient_create failed"); } dhclient_init(cli, request_ip.s_addr); fatal_signal_add_hook(release, cli, true); for (;;) { fatal_signal_block(); dhclient_run(cli); if (dhclient_changed(cli)) { dhclient_configure_netdev(cli); if (update_resolv_conf) { dhclient_update_resolv_conf(cli); } } dhclient_wait(cli); fatal_signal_unblock(); poll_block(); } }