/** Call before exiting. */ void awesome_atexit(bool restart) { int screen_nbr, nscreens; if(globalconf.hooks.exit != LUA_REFNIL) luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.exit, 0, 0); lua_pushboolean(globalconf.L, restart); signal_object_emit(globalconf.L, &global_signals, "exit", 1); a_dbus_cleanup(); /* do this only for real screen */ const xcb_setup_t *setup = xcb_get_setup(globalconf.connection); nscreens = setup ? xcb_setup_roots_length(setup) : -1; for(screen_nbr = 0; screen_nbr < nscreens; screen_nbr++) systray_cleanup(0, screen_nbr); //FIXME: Clean physical screens /* Close Lua */ lua_close(globalconf.L); xcb_flush(globalconf.connection); /* Disconnect *after* closing lua */ xcb_disconnect(globalconf.connection); ev_default_destroy(); }
static void reactor_usecount_decr (flux_reactor_t *r) { if (r && --r->usecount == 0) { if (r->loop) { if (ev_is_default_loop (r->loop)) ev_default_destroy (); else ev_loop_destroy (r->loop); } free (r); } }
int main(int argc, char** argv) { enum uprobe_log_level loglevel = UPROBE_LOG_LEVEL; bool upipe_ts = false; int opt; // parse options while ((opt = getopt(argc, argv, "dt")) != -1) { switch (opt) { case 'd': loglevel--; break; case 't': upipe_ts = true; break; default: break; } } if (optind >= argc) { printf("Usage: %s [-d] [-t] filename\n", argv[0]); exit(-1); } const char *uri = argv[optind++]; // upipe env struct ev_loop *loop = ev_default_loop(0); struct upump_mgr *upump_mgr = upump_ev_mgr_alloc(loop, UPUMP_POOL, UPUMP_BLOCKER_POOL); assert(upump_mgr != NULL); struct upipe_glxplayer *glxplayer = upipe_glxplayer_alloc(loglevel); assert(glxplayer != NULL); upipe_glxplayer_play(glxplayer, upump_mgr, uri, upipe_ts); upump_mgr_release(upump_mgr); ev_loop(loop, 0); upipe_glxplayer_free(glxplayer); ev_default_destroy(); return 0; }
const char* slave_run_cb(void) { struct ev_loop *loop; ev_io io_listen; ev_signal sigint_listen; ev_signal sigterm_listen; pthread_mutex_init(&srv.pending_lk, 0); pthread_mutex_init(&srv.clients_lk, 0); if (!(loop = ev_default_loop(EVFLAG_AUTO))) return 1; syslog(LOG_INFO, "listening on %s:%hd", inet_ntoa(srv.addr.sin_addr), ntohs(srv.addr.sin_port)); ev_signal_init(&sigint_listen, &nol_s_ev_sigint, SIGINT); ev_signal_init(&sigterm_listen, &nol_s_ev_sigint, SIGTERM); ev_io_init(&io_listen, &nol_s_ev_conn_accept, srv.listen_sock, EV_READ); ev_io_init(&srv.master_io, &nol_s_ev_master, srv.master_sock, EV_READ); ev_async_init(&srv.client_status, &nol_s_ev_client_status); /* catch SIGINT so we can close connections and clean up properly */ ev_signal_start(loop, &sigint_listen); ev_signal_start(loop, &sigterm_listen); ev_io_start(loop, &io_listen); ev_io_start(loop, &srv.master_io); ev_async_start(loop, &srv.client_status); /** * This loop will listen for new connections and data from * the master. **/ ev_loop(loop, 0); close(srv.listen_sock); ev_default_destroy(); closelog(); pthread_mutex_destroy(&srv.pending_lk); pthread_mutex_destroy(&srv.clients_lk); nol_s_hook_invoke(HOOK_CLEANUP); return 0; }
void server_run(void) { struct ev_loop* mainloop = ev_default_loop(0); ev_io accept_watcher; ev_io_init(&accept_watcher, ev_io_on_request, sockinfo.fd, EV_READ); ev_io_start(mainloop, &accept_watcher); #if WANT_SIGINT_HANDLING ev_signal signal_watcher; ev_signal_init(&signal_watcher, ev_signal_on_sigint, SIGINT); ev_signal_start(mainloop, &signal_watcher); #endif /* This is the program main loop */ Py_BEGIN_ALLOW_THREADS ev_loop(mainloop, 0); ev_default_destroy(); Py_END_ALLOW_THREADS }
/** Call before exiting. */ void awesome_atexit(bool restart) { lua_pushboolean(globalconf.L, restart); signal_object_emit(globalconf.L, &global_signals, "exit", 1); a_dbus_cleanup(); systray_cleanup(); /* Close Lua */ lua_close(globalconf.L); xcb_flush(globalconf.connection); /* Disconnect *after* closing lua */ xcb_disconnect(globalconf.connection); ev_default_destroy(); }
int main(int argc, char **argv) { long flags; loop = ev_default_loop(0); mgr = upump_ev_mgr_alloc(loop, UPUMP_POOL, UPUMP_BLOCKER_POOL); assert(mgr != NULL); /* Create a pipe with non-blocking write */ assert(pipe(pipefd) != -1); flags = fcntl(pipefd[1], F_GETFL); assert(flags != -1); flags |= O_NONBLOCK; assert(fcntl(pipefd[1], F_SETFL, flags) != -1); /* Create watchers */ write_idler = upump_alloc_idler(mgr, write_idler_cb, NULL); assert(write_idler != NULL); write_watcher = upump_alloc_fd_write(mgr, write_watcher_cb, NULL, pipefd[1]); assert(write_watcher != NULL); read_timer = upump_alloc_timer(mgr, read_timer_cb, NULL, timeout, 0); assert(read_timer != NULL); read_watcher = upump_alloc_fd_read(mgr, read_watcher_cb, NULL, pipefd[0]); assert(read_watcher != NULL); /* Start tests */ upump_start(write_idler); ev_loop(loop, 0); assert(bytes_read); assert(bytes_read == bytes_written); /* Clean up */ upump_free(write_idler); upump_free(write_watcher); upump_free(read_timer); upump_free(read_watcher); upump_mgr_release(mgr); ev_default_destroy(); return 0; }
int emc_start_server(struct emc_server_context *ctx) { log_printf(DEBUG_LEVEL_INFO, "INFO EMC server ready"); while (ctx->continue_processing) ev_loop(loop, 0 /* or: EVLOOP_NONBLOCK */ ); log_printf(DEBUG_LEVEL_INFO, "INFO EMC server shutting down"); g_thread_pool_free(ctx->pool_tls_handshake, TRUE, TRUE); g_thread_pool_free(ctx->pool_reader, TRUE, TRUE); g_async_queue_unref(ctx->work_queue); g_mutex_free(ctx->tls_client_list_mutex); g_tree_destroy(ctx->nuauth_directory); ev_default_destroy(); emc_close_servers(ctx); return 0; }
int main(int argc, char **argv) { struct ev_loop *el; struct ev_periodic ep; struct sigaction act; int c; // Initialize stats errno_cnt_init(&socket_errors_cnt); errno_cnt_init(&fcntl_errors_cnt); errno_cnt_init(&setsockopt_errors_cnt); errno_cnt_init(&connect_errors_cnt); errno_cnt_init(&write_errors_cnt); // Options and defaults struct hostent *hent; float period = 1.0f / connRate; optreset = optind = 1; while ((c = getopt(argc, argv, "r:s:n:hv")) != -1) { switch (c) { case 'h': usage(stdout, argv[0]); return 0; case 'r': if ((connRate = strtoul(optarg, NULL, 10)) > 0) { period = 1.0f / MIN(connRate, MAX_TICK_FREQUENCY); } break; case 's': dataSize = strtoul(optarg, NULL, 10); break; case 'n': numConns = strtoul(optarg, NULL, 10); break; case 'v': dbg_level++; break; case '?': fprintf(stderr, "%s: unknown option %c\n", argv[0], optopt); return 1; } } if ((argc - optind) != 2) { usage(stderr, argv[0]); return 1; } if (!(hent = gethostbyname(argv[optind]))) { fprintf(stderr, "%s: could not resolve host name\n", argv[0]); return 1; } bzero(&addr, sizeof(addr)); memcpy(&addr.sin_addr, hent->h_addr, sizeof(addr.sin_addr)); addr.sin_port = htons(strtoul(argv[optind + 1], NULL, 10)); addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; bzero(&act, sizeof(act)); act.sa_handler = sigint_cb; if (sigaction(SIGINT, &act, NULL)) { perror("sigaction"); exit(1); } el = ev_default_loop(EVFLAG_AUTO); if (connRate > 0) { ev_periodic_init(&ep, periodic_watcher_cb, 0, period, NULL); ev_periodic_start(el, &ep); } else { while (numConns-- > 0) { spawn_connection(el); } } atexit(atexit_cb); ev_loop(el, 0); ev_default_destroy(); return 0; }
int main(int argc, char **argv) { int opt; int option_index = 0; char *socket_path = getenv("I3SOCK"); char *i3_default_sock_path = "/tmp/i3-ipc.sock"; /* Initialize the standard config to use 0 as default */ memset(&config, '\0', sizeof(config_t)); static struct option long_opt[] = { { "socket", required_argument, 0, 's' }, { "bar_id", required_argument, 0, 'b' }, { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0} }; while ((opt = getopt_long(argc, argv, "b:s:hv", long_opt, &option_index)) != -1) { switch (opt) { case 's': socket_path = expand_path(optarg); break; case 'v': printf("i3bar version " I3_VERSION " © 2010-2014 Axel Wagner and contributors\n"); exit(EXIT_SUCCESS); break; case 'b': config.bar_id = sstrdup(optarg); break; default: print_usage(argv[0]); exit(EXIT_SUCCESS); break; } } if (!config.bar_id) { /* TODO: maybe we want -f which will automatically ask i3 for the first * configured bar (and error out if there are too many)? */ ELOG("No bar_id passed. Please let i3 start i3bar or specify --bar_id\n"); exit(EXIT_FAILURE); } main_loop = ev_default_loop(0); char *atom_sock_path = init_xcb_early(); if (socket_path == NULL) { socket_path = atom_sock_path; } if (socket_path == NULL) { ELOG("No Socket Path Specified, default to %s\n", i3_default_sock_path); socket_path = expand_path(i3_default_sock_path); } init_outputs(); if (init_connection(socket_path)) { /* Request the bar configuration. When it arrives, we fill the config array. */ i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id); } /* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main-loop. * We only need those watchers on the stack, so putting them on the stack saves us * some calls to free() */ ev_signal *sig_term = smalloc(sizeof(ev_signal)); ev_signal *sig_int = smalloc(sizeof(ev_signal)); ev_signal *sig_hup = smalloc(sizeof(ev_signal)); ev_signal_init(sig_term, &sig_cb, SIGTERM); ev_signal_init(sig_int, &sig_cb, SIGINT); ev_signal_init(sig_hup, &sig_cb, SIGHUP); ev_signal_start(main_loop, sig_term); ev_signal_start(main_loop, sig_int); ev_signal_start(main_loop, sig_hup); /* From here on everything should run smooth for itself, just start listening for * events. We stop simply stop the event-loop, when we are finished */ ev_loop(main_loop, 0); kill_child(); FREE(l_statusline_buffer); FREE(r_statusline_buffer); clean_xcb(); ev_default_destroy(); free_workspaces(); return 0; }
int main(int argc, char **argv) { int opt; int option_index = 0; char *socket_path = getenv("I3SOCK"); char *command = NULL; char *fontname = NULL; char *i3_default_sock_path = "/tmp/i3-ipc.sock"; struct xcb_color_strings_t colors = { NULL, }; /* Definition of the standard-config */ config.hide_on_modifier = 0; config.dockpos = DOCKPOS_NONE; config.disable_ws = 0; static struct option long_opt[] = { { "socket", required_argument, 0, 's' }, { "command", required_argument, 0, 'c' }, { "hide", no_argument, 0, 'm' }, { "dock", optional_argument, 0, 'd' }, { "font", required_argument, 0, 'f' }, { "nows", no_argument, 0, 'w' }, { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'v' }, { "verbose", no_argument, 0, 'V' }, { "color-bar-fg", required_argument, 0, 'A' }, { "color-bar-bg", required_argument, 0, 'B' }, { "color-active-ws-fg", required_argument, 0, 'C' }, { "color-active-ws-bg", required_argument, 0, 'D' }, { "color-inactive-ws-fg", required_argument, 0, 'E' }, { "color-inactive-ws-bg", required_argument, 0, 'F' }, { "color-urgent-ws-bg", required_argument, 0, 'G' }, { "color-urgent-ws-fg", required_argument, 0, 'H' }, { "color-focus-ws-bg", required_argument, 0, 'I' }, { "color-focus-ws-fg", required_argument, 0, 'J' }, { NULL, 0, 0, 0} }; while ((opt = getopt_long(argc, argv, "s:c:d::mf:whvVA:B:C:D:E:F:G:H:I:J:", long_opt, &option_index)) != -1) { switch (opt) { case 's': socket_path = expand_path(optarg); break; case 'c': command = strdup(optarg); break; case 'm': config.hide_on_modifier = 1; break; case 'd': config.hide_on_modifier = 0; if (optarg == NULL) { config.dockpos = DOCKPOS_BOT; break; } if (!strcmp(optarg, "top")) { config.dockpos = DOCKPOS_TOP; } else if (!strcmp(optarg, "bottom")) { config.dockpos = DOCKPOS_BOT; } else { print_usage(argv[0]); exit(EXIT_FAILURE); } break; case 'f': fontname = strdup(optarg); break; case 'w': config.disable_ws = 1; break; case 'v': printf("i3bar version " I3_VERSION " © 2010-2011 Axel Wagner and contributors\n"); exit(EXIT_SUCCESS); break; case 'V': config.verbose = 1; break; case 'A': read_color(&colors.bar_fg); break; case 'B': read_color(&colors.bar_bg); break; case 'C': read_color(&colors.active_ws_fg); break; case 'D': read_color(&colors.active_ws_bg); break; case 'E': read_color(&colors.inactive_ws_fg); break; case 'F': read_color(&colors.inactive_ws_bg); break; case 'G': read_color(&colors.urgent_ws_bg); break; case 'H': read_color(&colors.urgent_ws_fg); break; case 'I': read_color(&colors.focus_ws_bg); break; case 'J': read_color(&colors.focus_ws_fg); break; default: print_usage(argv[0]); exit(EXIT_SUCCESS); break; } } if (fontname == NULL) { /* This is a very restrictive default. More sensefull would be something like * "-misc-*-*-*-*--*-*-*-*-*-*-*-*". But since that produces very ugly results * on my machine, let's stick with this until we have a configfile */ fontname = "-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1"; } if (config.dockpos != DOCKPOS_NONE) { if (config.hide_on_modifier) { ELOG("--dock and --hide are mutually exclusive!\n"); exit(EXIT_FAILURE); } } else { config.hide_on_modifier = 1; } main_loop = ev_default_loop(0); init_colors(&colors); char *atom_sock_path = init_xcb(fontname); if (socket_path == NULL) { socket_path = atom_sock_path; } if (socket_path == NULL) { ELOG("No Socket Path Specified, default to %s\n", i3_default_sock_path); socket_path = expand_path(i3_default_sock_path); } free_colors(&colors); init_outputs(); if (init_connection(socket_path)) { /* We subscribe to the i3-events we need */ subscribe_events(); /* We initiate the main-function by requesting infos about the outputs and * workspaces. Everything else (creating the bars, showing the right workspace- * buttons and more) is taken care of by the event-driveniness of the code */ i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL); if (!config.disable_ws) { i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL); } } /* The name of this function is actually misleading. Even if no -c is specified, * this function initiates the watchers to listen on stdin and react accordingly */ start_child(command); FREE(command); /* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main-loop. * We only need those watchers on the stack, so putting them on the stack saves us * some calls to free() */ ev_signal *sig_term = malloc(sizeof(ev_signal)); ev_signal *sig_int = malloc(sizeof(ev_signal)); ev_signal *sig_hup = malloc(sizeof(ev_signal)); if (sig_term == NULL || sig_int == NULL || sig_hup == NULL) { ELOG("malloc() failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); } ev_signal_init(sig_term, &sig_cb, SIGTERM); ev_signal_init(sig_int, &sig_cb, SIGINT); ev_signal_init(sig_hup, &sig_cb, SIGHUP); ev_signal_start(main_loop, sig_term); ev_signal_start(main_loop, sig_int); ev_signal_start(main_loop, sig_hup); /* From here on everything should run smooth for itself, just start listening for * events. We stop simply stop the event-loop, when we are finished */ ev_loop(main_loop, 0); kill_child(); FREE(statusline_buffer); clean_xcb(); ev_default_destroy(); free_workspaces(); return 0; }
int main(int argc, char *argv[]) { #if EV_MULTIPLICITY lem_loop = ev_default_loop(LEM_LOOPFLAGS); if (lem_loop == NULL) { #else if (!ev_default_loop(LEM_LOOPFLAGS)) { #endif lem_log_error("lem: error initializing event loop"); return EXIT_FAILURE; } if (setsignal(SIGPIPE, SIG_IGN, 0) #if !EV_CHILD_ENABLE || setsignal(SIGCHLD, SIG_DFL, SA_NOCLDSTOP | SA_NOCLDWAIT) #endif ) goto error; /* create main Lua state */ L = luaL_newstate(); if (L == NULL) { lem_log_error("lem: error initializing Lua state"); goto error; } luaL_openlibs(L); /* push thread table */ lua_newtable(L); /* initialize runqueue */ ev_idle_init(&rq.w, runqueue_pop); ev_idle_start(LEM_ &rq.w); rq.queue = lem_xmalloc(LEM_INITIAL_QUEUESIZE * sizeof(struct lem_runqueue_slot)); rq.first = rq.last = 0; rq.mask = LEM_INITIAL_QUEUESIZE - 1; /* initialize threadpool */ if (pool_init()) { lem_log_error("lem: error initializing threadpool"); goto error; } /* load file */ if (queue_file(argc, argv, 1)) goto error; /* start the mainloop */ ev_loop(LEM_ 0); lem_debug("event loop exited"); /* if there is an error message left on L print it */ if (lua_type(L, -1) == LUA_TSTRING) lem_log_error("lem: %s", lua_tostring(L, -1)); /* shutdown Lua */ lua_close(L); /* free runqueue */ free(rq.queue); /* destroy loop */ #if EV_MULTIPLICITY ev_loop_destroy(lem_loop); #else ev_default_destroy(); #endif lem_debug("Bye %s", exit_status == EXIT_SUCCESS ? "o/" : ":("); return exit_status; error: if (L) lua_close(L); if (rq.queue) free(rq.queue); #if EV_MULTIPLICITY ev_loop_destroy(lem_loop); #else ev_default_destroy(); #endif return EXIT_FAILURE; }
int main(int argc, char *argv[]) { struct sigaction sa; struct rlimit limit; int i, c, rc; int opt_foreground = 0, opt_allow_links = 0; enum startup_state opt_startup = startup_enable; extern char *optarg; extern int optind; struct ev_loop *loop; struct ev_io netlink_watcher; struct ev_signal sigterm_watcher; struct ev_signal sighup_watcher; struct ev_signal sigusr1_watcher; struct ev_signal sigusr2_watcher; struct ev_signal sigchld_watcher; /* Get params && set mode */ while ((c = getopt(argc, argv, "flns:")) != -1) { switch (c) { case 'f': opt_foreground = 1; break; case 'l': opt_allow_links=1; break; case 'n': do_fork = 0; break; case 's': for (i=0; i<startup_INVALID; i++) { if (strncmp(optarg, startup_states[i], strlen(optarg)) == 0) { opt_startup = i; break; } } if (i == startup_INVALID) { fprintf(stderr, "unknown startup mode '%s'\n", optarg); usage(); } break; default: usage(); } } /* check for trailing command line following options */ if (optind < argc) { usage(); } if (opt_allow_links) set_allow_links(1); if (opt_foreground) { config.daemonize = D_FOREGROUND; set_aumessage_mode(MSG_STDERR, DBG_YES); } else { config.daemonize = D_BACKGROUND; set_aumessage_mode(MSG_SYSLOG, DBG_NO); (void) umask( umask( 077 ) | 022 ); } #ifndef DEBUG /* Make sure we are root */ if (getuid() != 0) { fprintf(stderr, "You must be root to run this program.\n"); return 4; } #endif /* Register sighandlers */ sa.sa_flags = 0 ; sigemptyset( &sa.sa_mask ) ; /* Ignore all signals by default */ sa.sa_handler = SIG_IGN; for (i=1; i<NSIG; i++) sigaction( i, &sa, NULL ); atexit(clean_exit); /* Raise the rlimits in case we're being started from a shell * with restrictions. Not a fatal error. */ limit.rlim_cur = RLIM_INFINITY; limit.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_FSIZE, &limit); setrlimit(RLIMIT_CPU, &limit); /* Load the Configuration File */ if (load_config(&config, TEST_AUDITD)) return 6; if (config.priority_boost != 0) { errno = 0; rc = nice((int)-config.priority_boost); if (rc == -1 && errno) { audit_msg(LOG_ERR, "Cannot change priority (%s)", strerror(errno)); return 1; } } /* Daemonize or stay in foreground for debugging */ if (config.daemonize == D_BACKGROUND) { if (become_daemon() != 0) { audit_msg(LOG_ERR, "Cannot daemonize (%s)", strerror(errno)); tell_parent(FAILURE); return 1; } openlog("auditd", LOG_PID, LOG_DAEMON); } /* Init netlink */ if ((fd = audit_open()) < 0) { audit_msg(LOG_ERR, "Cannot open netlink audit socket"); tell_parent(FAILURE); return 1; } /* Init the event handler thread */ write_pid_file(); if (init_event(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } if (init_dispatcher(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } /* Get machine name ready for use */ if (resolve_node(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } /* Write message to log that we are alive */ { struct utsname ubuf; char start[DEFAULT_BUF_SZ]; const char *fmt = audit_lookup_format((int)config.log_format); if (fmt == NULL) fmt = "UNKNOWN"; if (uname(&ubuf) != 0) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } if (getsubj(subj)) snprintf(start, sizeof(start), "auditd start, ver=%s format=%s " "kernel=%.56s auid=%u pid=%d subj=%s res=success", VERSION, fmt, ubuf.release, audit_getloginuid(), getpid(), subj); else snprintf(start, sizeof(start), "auditd start, ver=%s format=%s " "kernel=%.56s auid=%u pid=%d res=success", VERSION, fmt, ubuf.release, audit_getloginuid(), getpid()); if (send_audit_event(AUDIT_DAEMON_START, start)) { audit_msg(LOG_ERR, "Cannot send start message"); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } } /* Tell kernel not to kill us */ avoid_oom_killer(); /* let config manager init */ init_config_manager(); if (opt_startup != startup_nochange && (audit_is_enabled(fd) < 2) && audit_set_enabled(fd, (int)opt_startup) < 0) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); audit_msg(LOG_ERR, "Unable to set initial audit startup state to '%s', exiting", startup_states[opt_startup]); close_down(); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } /* Tell the kernel we are alive */ if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); audit_msg(LOG_ERR, "Unable to set audit pid, exiting"); close_down(); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } /* Depending on value of opt_startup (-s) set initial audit state */ loop = ev_default_loop (EVFLAG_NOENV); ev_io_init (&netlink_watcher, netlink_handler, fd, EV_READ); ev_io_start (loop, &netlink_watcher); ev_signal_init (&sigterm_watcher, term_handler, SIGTERM); ev_signal_start (loop, &sigterm_watcher); ev_signal_init (&sighup_watcher, hup_handler, SIGHUP); ev_signal_start (loop, &sighup_watcher); ev_signal_init (&sigusr1_watcher, user1_handler, SIGUSR1); ev_signal_start (loop, &sigusr1_watcher); ev_signal_init (&sigusr2_watcher, user2_handler, SIGUSR2); ev_signal_start (loop, &sigusr2_watcher); ev_signal_init (&sigchld_watcher, child_handler, SIGCHLD); ev_signal_start (loop, &sigchld_watcher); if (auditd_tcp_listen_init (loop, &config)) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); tell_parent(FAILURE); } else { /* Now tell parent that everything went OK */ tell_parent(SUCCESS); audit_msg(LOG_NOTICE, "Init complete, auditd %s listening for events (startup state %s)", VERSION, startup_states[opt_startup]); } /* Parent should be gone by now... */ if (do_fork) close(init_pipe[1]); // Init complete, start event loop if (!stop) ev_loop (loop, 0); auditd_tcp_listen_uninit (loop, &config); // Tear down IO watchers Part 1 ev_signal_stop (loop, &sighup_watcher); ev_signal_stop (loop, &sigusr1_watcher); ev_signal_stop (loop, &sigusr2_watcher); ev_signal_stop (loop, &sigterm_watcher); /* Write message to log that we are going down */ rc = audit_request_signal_info(fd); if (rc > 0) { struct audit_reply trep; rc = get_reply(fd, &trep, rc); if (rc > 0) { char txt[MAX_AUDIT_MESSAGE_LENGTH]; snprintf(txt, sizeof(txt), "auditd normal halt, sending auid=%u " "pid=%d subj=%s res=success", trep.signal_info->uid, trep.signal_info->pid, trep.signal_info->ctx); send_audit_event(AUDIT_DAEMON_END, txt); } } if (rc <= 0) send_audit_event(AUDIT_DAEMON_END, "auditd normal halt, sending auid=? " "pid=? subj=? res=success"); free(rep); // Tear down IO watchers Part 2 ev_io_stop (loop, &netlink_watcher); // Give DAEMON_END event a little time to be sent in case // of remote logging usleep(10000); // 10 milliseconds shutdown_dispatcher(); // Tear down IO watchers Part 3 ev_signal_stop (loop, &sigchld_watcher); close_down(); free_config(&config); ev_default_destroy(); return 0; }