/** * read a signal from the libdaemon signal queue (event dispatch routine). * * @param fd fd signalled (via libevent) * @param event event (read/write, etc... from libevent) * @param arg opaqe pointer (from libevent), underlying event struct */ static void on_signal(int fd, short event, void *arg) { // struct event *ev = arg; int sig; while((sig = daemon_signal_next()) > 0) { switch(sig) { case SIGINT: case SIGQUIT: case SIGTERM: INFO("Got signal -- terminating"); g_quitflag = 1; break; case SIGHUP: INFO("Got HUP"); break; case SIGPIPE: INFO("Got SIGPIPE"); break; } } if(sig < 0) { ERROR("daemon_signal_next() failed: %s. Aborting", strerror(errno)); g_quitflag = 1; } }
static void infinoted_signal_sig_func(InfNativeSocket* fd, InfIoEvent event, gpointer user_data) { InfinotedSignal* sig; int occured; GError* error; sig = (InfinotedSignal*)user_data; if(event & INF_IO_ERROR) { inf_io_remove_watch(INF_IO(sig->run->io), sig->watch); daemon_signal_done(); sig->run = NULL; sig->signal_fd = 0; sig->watch = NULL; infinoted_log_error( sig->run->startup->log, _("Error on signal handler connection; signal " "handlers have been removed from now on") ); } else if(event & INF_IO_INCOMING) { occured = daemon_signal_next(); if(occured == SIGINT || occured == SIGTERM || occured == SIGQUIT) { printf("\n"); inf_standalone_io_loop_quit(sig->run->io); } else if(occured == SIGHUP) { error = NULL; if(!infinoted_config_reload(sig->run, &error)) { infinoted_log_error( sig->run->startup->log, _("Configuration reload failed: %s"), error->message ); g_error_free(error); } else { infinoted_log_info( sig->run->startup->log, _("Configuration reloaded") ); } } } }
static void signal_callback(AvahiWatch *watch, AVAHI_GCC_UNUSED int fd, AVAHI_GCC_UNUSED AvahiWatchEvent event, AVAHI_GCC_UNUSED void *userdata) { int sig; const AvahiPoll *poll_api; assert(watch); assert(simple_poll_api); poll_api = avahi_simple_poll_get(simple_poll_api); if ((sig = daemon_signal_next()) <= 0) { avahi_log_error("daemon_signal_next() failed"); poll_api->watch_free(watch); return; } switch (sig) { case SIGINT: case SIGQUIT: case SIGTERM: avahi_log_info( "Got %s, quitting.", sig == SIGINT ? "SIGINT" : (sig == SIGQUIT ? "SIGQUIT" : "SIGTERM")); avahi_simple_poll_quit(simple_poll_api); break; case SIGHUP: avahi_log_info("Got SIGHUP, reloading."); reload_config(); break; case SIGUSR1: avahi_log_info("Got SIGUSR1, dumping record data."); avahi_server_dump(avahi_server, dump, NULL); break; default: avahi_log_warn("Got spurious signal, ignoring."); break; } }
int main(int argc, char *argv[]) { pid_t pid; /* Reset signal handlers */ if (daemon_reset_sigs(-1) < 0) { daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s", strerror(errno)); return 1; } /* Unblock signals */ if (daemon_unblock_sigs(-1) < 0) { daemon_log(LOG_ERR, "Failed to unblock all signals: %s", strerror(errno)); } /* Set indetification string for the daemon for both syslog and PID file */ daemon_log_ident = daemon_ident_from_argv0(argv[0]); daemon_pid_file_ident = daemon_log_ident; //(LOG_ERR, "The log ident is %s\n",daemon_log_ident); daemon_pid_file_proc = get_pid_file_proc; sprintf (image_pid_file, "/var/run/%s.pid", daemon_pid_file_ident); /* Check if we are called with -k parameter */ if (argc >= 2 && !strcmp(argv[1], "-k")) { int ret; /* Kill daemon with SIGTERM */ /* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */ if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0) daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno)); return ret < 0 ? 1 : 0; } /* Check that the daemon is not rung twice a the same time */ if ((pid = daemon_pid_file_is_running()) >= 0) { daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid); return 1; } /* Prepare for return value passing from the initialization procedure of the daemon process */ if (daemon_retval_init() < 0) { daemon_log(LOG_ERR, "Failed to create pipe."); return 1; } /* Do the fork */ if ((pid = daemon_fork()) < 0) { /* Exit on error */ daemon_retval_done(); return 1; } else if (pid) { /* The parent */ int ret; /* Wait for 20 seconds for the return value passed from the daemon process */ if ((ret = daemon_retval_wait(20)) < 0) { daemon_log(LOG_ERR, "Count not receive return value from daemon" "process: %s", strerror(errno)); } //daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, // "Daemon returned %i as return value.", ret); return ret; } else { /* The daemon */ int fd, quit = 0; fd_set fds; pthread_t sock_thread; pthread_t nl_thread; /* Close FDs */ if (daemon_close_all(-1) < 0) { daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno)); /* Send the error condition to the parent process */ daemon_retval_send(1); goto finish; } /* Create the PID file */ if (daemon_pid_file_create() < 0) { daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno)); daemon_retval_send(2); goto finish; } /* Initialize signal handling */ if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) { daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno)); daemon_retval_send(3); goto finish; } /* Init task */ init_image_config(argc, argv); init_netlink(); /* Send OK to parent process */ daemon_retval_send(0); daemon_log(LOG_INFO, "Sucessfully started"); /* Main task*/ pthread_create(&nl_thread, NULL, (void *)netlink_loop, (void *)NULL); #if 0 pthread_create(&sock_thread, NULL, (void *)socket_loop, (void *)NULL); #endif pthread_create(&sock_thread, NULL, (void *)mq_loop, (void *)NULL); /* Prepare for select() on the signal fd */ FD_ZERO(&fds); fd = daemon_signal_fd(); FD_SET(fd, &fds); while (!quit) { fd_set fds2 = fds; /* Wait for an incoming signal */ if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) { /* If we've been interrupted by an incoming signal, continue */ if (errno == EINTR) continue; daemon_log(LOG_ERR, "select(): %s", strerror(errno)); break; } /* Check if a signal has been recieved */ if (FD_ISSET(fd, &fds2)) { int sig; /* Get signal */ if ((sig = daemon_signal_next()) <= 0) { daemon_log(LOG_ERR, "daemon_signal_next() failed: %s", strerror(errno)); break; } /* Dispatch signal */ switch (sig) { case SIGINT: case SIGQUIT: case SIGTERM: daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or" "SIGTERM."); if (nl_image_config.nl_connected == 1) { nl_image_config.nl_connected = 0; if (nl_send_image_session_cmd( IMAGE_SESSION_CMD_DISCONNECT) < 0) { printf("Failed to remove connection with" "kernel!\n"); } } quit = 1; break; case SIGHUP: daemon_log(LOG_INFO, "Got a HUP"); daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL); break; } } } /* Do a cleanup */ finish: delete_pid_file(IMAGE_SERVER_PROC); daemon_log(LOG_INFO, "Exiting..."); daemon_retval_send(255); daemon_signal_done(); daemon_pid_file_remove(); return 0; } }
/** Punto de entrada de la aplicacion de navegacion. * @return Estado de la aplicacion al terminar. */ int main(int argc, char *argv[]) { pid_t pid; /* Reset signal handlers */ if (daemon_reset_sigs(-1) < 0) { daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s", strerror(errno)); return 1; } /* Unblock signals */ if (daemon_unblock_sigs(-1) < 0) { daemon_log(LOG_ERR, "Failed to unblock all signals: %s", strerror(errno)); return 1; } /* Set indetification string for the daemon for both syslog and PID file */ daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]); /* Check if we are called with -k parameter */ if (argc >= 2 && !strcmp(argv[1], "-k")) { int ret; /* Kill daemon with SIGTERM */ /* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */ if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0) daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno)); return ret < 0 ? 1 : 0; } /* Check that the daemon is not rung twice a the same time */ if ((pid = daemon_pid_file_is_running()) >= 0) { daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid); return 1; } /* Prepare for return value passing from the initialization procedure of the daemon process */ if (daemon_retval_init() < 0) { daemon_log(LOG_ERR, "Failed to create pipe."); return 1; } /* Do the fork */ if ((pid = daemon_fork()) < 0) { /* Exit on error */ daemon_retval_done(); return 1; } else if (pid) { /* The parent */ int ret; /* Wait for 20 seconds for the return value passed from the daemon process */ if ((ret = daemon_retval_wait(20)) < 0) { daemon_log(LOG_ERR, "Could not recieve return value from daemon process: %s", strerror(errno)); return 255; } daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret); return ret; } else { /* The daemon */ int fd, quit = 0; fd_set fds; char * config_file; config_t cfg; config_setting_t *setting; /* Base de Datos de Tiempo Real */ struct rtdb rtdb; /* Controlador de estado de la MTi-G */ struct mti_g mti_g; struct time_tracker tracker; struct sharksoft sharksoft; /* Close FDs */ if (daemon_close_all(-1) < 0) { daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno)); /* Send the error condition to the parent process */ daemon_retval_send(1); goto finish; } /* Create the PID file */ if (daemon_pid_file_create() < 0) { daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno)); daemon_retval_send(2); goto finish; } /* Initialize signal handling */ if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) { daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno)); daemon_retval_send(3); goto finish; } /*... do some further init work here */ daemon_log(LOG_INFO, "Starting"); /* cargar la configuración de la aplicación */ config_init(&cfg); config_file = malloc(strlen(CONFIG_PATH) + strlen(CONFIG_FILE) + 1); assert(config_file != NULL); strcpy(config_file, CONFIG_PATH); strcpy(config_file + strlen(CONFIG_PATH), CONFIG_FILE); /* Read the file. If there is an error, report it and exit. */ if (!config_read_file(&cfg, CONFIG_FILE)) { daemon_log(LOG_ERR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); daemon_retval_send(4); goto finish; } daemon_log(LOG_INFO, "Config file readed"); /* Inicializar el controlador de estado de la MTi-G, enlazando * la RTDB como area de almacenamiento */ setting = config_lookup(&cfg, "mti_g"); mti_g_init(&mti_g, setting, &(rtdb.imu), &(rtdb.gps)); daemon_log(LOG_INFO, "MTi-G state controller inited"); setting = config_lookup(&cfg, "time_tracker"); time_tracker_init(&tracker, setting); daemon_log(LOG_INFO, "Time Tracker service inited"); setting = config_lookup(&cfg, "sharksoft"); sharksoft_init(&sharksoft, setting, &(rtdb.imu), &(rtdb.gps)); daemon_log(LOG_INFO, "Sharksoft data provider service inited"); /* Send OK to parent process */ daemon_retval_send(0); daemon_log(LOG_INFO, "Sucessfully started"); /* Prepare for select() on the signals */ FD_ZERO(&fds); fd = daemon_signal_fd(); FD_SET(fd, &fds); FD_SET(mti_g.fd, &fds); FD_SET(sharksoft.fd, &fds); while (!quit) { fd_set fds2 = fds; /* Wait for an incoming signal */ if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) { /* If we've been interrupted by an incoming signal, continue */ if (errno == EINTR) continue; daemon_log(LOG_ERR, "select(): %s", strerror(errno)); break; } /* Check if a signal has been recieved */ if (FD_ISSET(fd, &fds2)) { int sig; /* Get signal */ if ((sig = daemon_signal_next()) <= 0) { daemon_log(LOG_ERR, "daemon_signal_next() failed: %s", strerror(errno)); break; } /* Dispatch signal */ switch (sig) { case SIGINT: case SIGQUIT: case SIGTERM: daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM."); quit = 1; break; case SIGHUP: daemon_log(LOG_INFO, "Got a HUP"); daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL); break; } } /* Procesar señales desde la MTi-G */ if (FD_ISSET(mti_g.fd, &fds2)) { mti_g_handle_request(&mti_g); //sharksoft_handle_getdata(&sharksoft); //time_tracker_handle(&tracker); } /* Procesar señales desde el HMI Sharksoft */ if (FD_ISSET(sharksoft.fd, &fds2)) { //time_tracker_handle(&tracker); sharksoft_handle_request(&sharksoft); } } time_tracker_dispose(&tracker); config_destroy(&cfg); /* Do a cleanup */ finish: daemon_log(LOG_INFO, "Exiting..."); daemon_retval_send(255); daemon_signal_done(); daemon_pid_file_remove(); return 0; } }
void work(void) { fd_set fds; int sigfd; static char log_ident[256]; snprintf(log_ident, sizeof(log_ident), "ifplugd"); daemon_log_ident = log_ident; daemon_log(LOG_INFO, "ifplugd "VERSION" initializing, using NETLINK device monitoring"); if (daemon_pid_file_create() < 0) { daemon_log(LOG_ERR, "Could not create PID file %s.", daemon_pid_file_proc()); goto finish; } if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2, -1) < 0) { daemon_log(LOG_ERR, "Could not register signal handler: %s", strerror(errno)); goto finish; } if ((netlink = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) { daemon_log(LOG_ERR, "socket(): %s", strerror(errno)); goto finish; } rbus = rbus_init("unix!/tmp/ifplugd.9p"); rbus->rbus.childs = &root_children[0]; discover(netlink); if (nlapi_open(RTMGRP_LINK) < 0) goto finish; if (ifmonitor_init(ifmonitor_cb) < 0) goto finish; FD_ZERO(&fds); sigfd = daemon_signal_fd(); FD_SET(sigfd, &fds); FD_SET(nlapi_fd, &fds); for (;;) { struct interface_state *iface; fd_set qfds = fds; struct timeval tv; IxpConn *c; for(c = rbus->srv->conn; c; c = c->next) { if(c->read) { FD_SET(c->fd, &qfds); } } tv.tv_sec = polltime; tv.tv_usec = 0; if (select(FD_SETSIZE, &qfds, NULL, NULL, &tv) < 0) { if (errno == EINTR) continue; daemon_log(LOG_ERR, "select(): %s", strerror(errno)); goto finish; } //daemon_log(LOG_INFO, "select()"); for(c = rbus->srv->conn; c; c = c->next) { if(c->read && FD_ISSET(c->fd, &qfds)) { c->read(c); } } if (FD_ISSET(nlapi_fd, &qfds)) { if (nlapi_work(0) < 0) goto finish; } for(iface = interface; iface; iface=iface->next) { if(! is_iface_available(netlink, iface->name)) { drop_interface(iface); continue; } detect_beat(netlink, iface); status_change(iface); } if (FD_ISSET(sigfd, &qfds)) { int sig; if ((sig = daemon_signal_next()) < 0) { daemon_log(LOG_ERR, "daemon_signal_next(): %s", strerror(errno)); goto finish; } switch (sig) { case SIGINT: case SIGTERM: goto cleanup; case SIGQUIT: goto finish; case SIGCHLD: break; case SIGHUP: break; default: daemon_log(LOG_INFO, "Ignoring unknown signal %s", strsignal(sig)); break; } } } cleanup: finish: if (netlink >= 0) close(netlink); nlapi_close(); daemon_pid_file_remove(); daemon_signal_done(); daemon_log(LOG_INFO, "Exiting."); }
void work(void) { interface_status_t status; int fd = -1; fd_set fds; int sigfd; time_t t = 0; int send_retval = 1; int paused = 0; static char log_ident[256]; snprintf(log_ident, sizeof(log_ident), "ifplugd(%s)", interface); daemon_log_ident = log_ident; daemon_log(LOG_INFO, "ifplugd "VERSION" initializing%s.", use_ifmonitor ? ", using NETLINK device monitoring" : ""); if (daemon_pid_file_create() < 0) { daemon_log(LOG_ERR, "Could not create PID file %s.", daemon_pid_file_proc()); goto finish; } if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2, -1) < 0) { daemon_log(LOG_ERR, "Could not register signal handler: %s", strerror(errno)); goto finish; } switch (api_mode) { case API_ETHTOOL: detect_beat_func = interface_detect_beat_ethtool; break; case API_MII: detect_beat_func = interface_detect_beat_mii; break; case API_PRIVATE: detect_beat_func = interface_detect_beat_priv; break; case API_WLAN: detect_beat_func = interface_detect_beat_wlan; break; case API_IFF: detect_beat_func = interface_detect_beat_iff; break; default: detect_beat_func = detect_beat_auto; interface_do_message = 0; break; } if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { daemon_log(LOG_ERR, "socket(): %s", strerror(errno)); goto finish; } if (use_ifmonitor) { int b; if ((b = is_iface_available(fd, interface)) < 0) { daemon_log(LOG_ERR, "Failed to check interface availabilty!"); goto finish; } disabled = !b; if (nlapi_open(RTMGRP_LINK) < 0) goto finish; if (ifmonitor_init(ifmonitor_cb) < 0) goto finish; } else disabled = 0; if (!disabled) { if (welcome_iface(fd, interface) < 0) goto finish; } if ((status = detect_beat(fd, interface)) == IFSTATUS_ERR) goto finish; daemon_log(LOG_INFO, "Initialization complete, link beat %sdetected%s.", status == IFSTATUS_UP ? "" : "not ", use_ifmonitor ? (disabled ? ", interface disabled" : ", interface enabled") : ""); beep(status == IFSTATUS_UP ? 0 : 1); if ((!no_startup_script && status == IFSTATUS_UP) || initial_down) if (action(status) < 0) goto finish; if (send_retval && daemonize && wait_on_fork) { char c = status == IFSTATUS_UP ? 2 : (status == IFSTATUS_DOWN ? 3 : 1); daemon_retval_send(c); send_retval = 0; } FD_ZERO(&fds); sigfd = daemon_signal_fd(); FD_SET(sigfd, &fds); if (use_ifmonitor) FD_SET(nlapi_fd, &fds); for (;;) { interface_status_t s; fd_set qfds = fds; int d; struct timeval tv; tv.tv_sec = polltime; tv.tv_usec = 0; if (select(FD_SETSIZE, &qfds, NULL, NULL, &tv) < 0) { if (errno == EINTR) continue; daemon_log(LOG_ERR, "select(): %s", strerror(errno)); goto finish; } //daemon_log(LOG_INFO, "select()"); d = disabled; s = status; if (use_ifmonitor) { if (FD_ISSET(nlapi_fd, &qfds)) { if (nlapi_work(0) < 0) goto finish; } if (d && !disabled) { daemon_log(LOG_INFO, "Interface enabled"); welcome_iface(fd, interface); status = IFSTATUS_DOWN; } if (!d && disabled) { daemon_log(LOG_INFO, "Interface disabled"); status = IFSTATUS_DOWN; } } if (!paused && !disabled) { //daemon_log(LOG_INFO, "detect"); if ((status = detect_beat(fd, interface)) == IFSTATUS_ERR) { if (!use_ifmonitor) goto finish; status = IFSTATUS_DOWN; } } if (status != s) { daemon_log(LOG_INFO, "Link beat %s.", status == IFSTATUS_DOWN ? "lost" : "detected"); beep(status == IFSTATUS_UP ? 0 : 1); if (t) t = 0; else { t = time(NULL); if (status == IFSTATUS_UP) t += delay_up; if (status == IFSTATUS_DOWN) t += delay_down; } } if (FD_ISSET(sigfd, &qfds)) { int sig; if ((sig = daemon_signal_next()) < 0) { daemon_log(LOG_ERR, "daemon_signal_next(): %s", strerror(errno)); goto finish; } switch (sig) { case SIGINT: case SIGTERM: goto cleanup; case SIGQUIT: goto finish; case SIGCHLD: break; case SIGHUP: daemon_log(LOG_INFO, "SIGHUP: %s, link detected on %s: %s", paused ? "Suspended" : "Running", interface, status == IFSTATUS_DOWN ? "no" : "yes"); if (use_ifmonitor) daemon_log(LOG_INFO, "SIGHUP: Interface %s", disabled ? "disabled" : "enabled"); break; case SIGUSR1: daemon_log(LOG_INFO, "SIGUSR1: Daemon suspended (#%i)", ++paused); break; case SIGUSR2: if (paused > 0) { daemon_log(LOG_INFO, "SIGUSR2: Daemon resumed (#%i)", paused); paused --; } break; default: daemon_log(LOG_INFO, "Ignoring unknown signal %s", strsignal(sig)); break; } } if (t && t < time(NULL)) { t = 0; if (action(status) < 0) goto finish; } } cleanup: if (!no_shutdown_script && (status == IFSTATUS_UP || (status == IFSTATUS_DOWN && t))) { setenv(IFPLUGD_ENV_PREVIOUS, strstatus(status), 1); setenv(IFPLUGD_ENV_CURRENT, strstatus(-1), 1); action(IFSTATUS_DOWN); beep(1); } finish: if (fd >= 0) close(fd); if (use_ifmonitor) nlapi_close(); if (send_retval && daemonize && wait_on_fork) daemon_retval_send(255); daemon_pid_file_remove(); daemon_signal_done(); daemon_log(LOG_INFO, "Exiting."); }
int action(interface_status_t status) { pid_t pid; int _pipe[2]; unsigned n = 0; static char buf[256]; char *arg = (status == IFSTATUS_UP ? "up" : "down"); int sigfd, r; fd_set rfds; daemon_log(LOG_INFO, "Executing '%s %s %s'.", run, interface, arg); if (pipe(_pipe) < 0) { daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); return -1; } if ((pid = fork()) < 0) { daemon_log(LOG_ERR, "fork() failed: %s", strerror(errno)); return -1; } else if (pid == 0) { dup2(_pipe[1], 1); dup2(_pipe[1], 2); if (_pipe[0] > 2) close(_pipe[0]); if (_pipe[1] > 2) close(_pipe[1]); umask(0022); /* Set up a sane umask */ execl(run, run, interface, arg, extra_arg, (char *) NULL); _exit(EXIT_FAILURE); } close(_pipe[1]); FD_ZERO(&rfds); FD_SET(_pipe[0], &rfds); sigfd = daemon_signal_fd(); FD_SET(sigfd, &rfds); n = 0; for (;;) { fd_set wrfds = rfds; if (select(FD_SETSIZE, &wrfds, NULL, NULL, NULL) < 0) { if (errno == EINTR) continue; break; } if (FD_ISSET(_pipe[0], &wrfds)) { char c; if (read(_pipe[0], &c, 1) != 1) break; buf[n] = c; if (c == '\n' || n >= sizeof(buf) - 2) { if (c != '\n') n++; buf[n] = 0; if (buf[0]) daemon_log(LOG_WARNING, "client: %s", buf); n = 0; } else n++; } if (FD_ISSET(sigfd, &wrfds)) { int sig; if ((sig = daemon_signal_next()) < 0) { daemon_log(LOG_ERR, "daemon_signal_next(): %s", strerror(errno)); break; } if (sig != SIGCHLD) { daemon_log(LOG_WARNING, "Killing child."); kill(pid, SIGTERM); } } } if (n > 0) { buf[n] = 0; daemon_log(LOG_WARNING, "client: %s", buf); } waitpid(pid, &r, 0); close(_pipe[0]); if (!WIFEXITED(r) || WEXITSTATUS(r) != 0) { if (status == IFSTATUS_UP) beep(2); daemon_log(LOG_ERR, "Program execution failed, return value is %i.", WEXITSTATUS(r)); return ignore_retval ? 0 : -1; } else { if (status == IFSTATUS_UP) beep(0); daemon_log(LOG_INFO, "Program executed successfully."); return 0; } }