bool start() { #ifdef HAVE_LIBDAEMON pid_t pid; // Check that the daemon is not run twice a the same time if ((pid = daemon_pid_file_is_running()) >= 0) { daemon_log(LOG_ERR, "Daemon already running on (PID %u)", pid); throw Exception("Daemon already running on (PID %u)", pid); } pid = daemonize(); if ( pid < 0 ) { cleanup(); throw Exception("Failed to daemonize"); } else if (pid) { // parent return true; } else { // child return false; } #else throw Exception("Daemonizing support is not available.\n" "(libdaemon[-devel] was not available at compile time)\n"); #endif }
bool running() { #ifdef HAVE_LIBDAEMON return (daemon_pid_file_is_running() >= 0); #else throw Exception("Daemonizing support is not available.\n" "(libdaemon[-devel] was not available at compile time)\n"); #endif }
int main(int argc, char* argv[]) { daemon_pid_file_proc = pid_file_proc; if ((daemon_log_ident = strrchr(argv[0], '/'))) daemon_log_ident++; else daemon_log_ident = argv[0]; parse_args(argc, argv); if (geteuid() != 0) { daemon_log(LOG_ERR, "Sorry, you need to be root to run this binary."); return 2; } if (daemon_pid_file_is_running() >= 0) { daemon_log(LOG_ERR, "Sorry, there is already an instance of ifplugd for %s running.", interface); return 4; } if (daemonize) { pid_t pid; if (wait_on_fork) if (daemon_retval_init() < 0) { daemon_log(LOG_ERR, "Sorry, could not create pipe: %s", strerror(errno)); return 4; } if ((pid = daemon_fork()) < 0) return 3; if (pid) { int c = 0; // Parent process if (wait_on_fork) if ((c = daemon_retval_wait(60)) < 0) { daemon_log(LOG_WARNING, "Killing background process."); kill(pid, SIGTERM); } if (c > 3) daemon_log(LOG_ERR, "Daemon failed with error condition #%i. See syslog for details", c); return c; } } // Let's go work(); return 0; }
int main(int argc, char* argv[]) { daemon_pid_file_proc = pid_file_proc; if ((daemon_log_ident = strrchr(argv[0], '/'))) daemon_log_ident++; else daemon_log_ident = argv[0]; parse_args(argc, argv); /* if (geteuid() != 0) { daemon_log(LOG_ERR, "Sorry, you need to be root to run this binary."); return 2; } */ if (daemon_pid_file_is_running() >= 0) { daemon_log(LOG_ERR, "Sorry, there is already an instance of ifplugd running."); return 4; } if (daemonize) { pid_t pid; if ((pid = daemon_fork()) < 0) return 3; if (pid) { int c = 0; // Parent process if (c > 3) daemon_log(LOG_ERR, "Daemon failed with error condition #%i. See syslog for details", c); return c; } } // Let's go work(); daemon_log(LOG_ERR, "stop"); return 0; }
void kill() { #ifdef HAVE_LIBDAEMON pid_t pid; int ret; // Check that the daemon is not run twice a the same time if ((pid = daemon_pid_file_is_running()) < 0) { daemon_log(LOG_WARNING, "Fawkes daemon not running."); } // Kill daemon with SIGINT if ((ret = daemon_pid_file_kill_wait(SIGINT, 5)) < 0) { daemon_log(LOG_WARNING, "Failed to kill daemon"); } #else throw Exception("Daemonizing support is not available.\n" "(libdaemon[-devel] was not available at compile time)\n"); #endif }
int main(int argc, char *argv[]) { // create a configuration dtn::daemon::Configuration &conf = dtn::daemon::Configuration::getInstance(); // load parameter into the configuration conf.params(argc, argv); #ifdef HAVE_LIBDAEMON if (conf.getDaemon().daemonize()) { int ret = 0; pid_t pid; #ifdef HAVE_DAEMON_RESET_SIGS /* 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; } #endif /* Set identification string for the daemon for both syslog and PID file */ daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]); /* set the pid file path */ try { std::string p = conf.getDaemon().getPidFile().getPath(); __daemon_pidfile__ = new char[p.length() + 1]; ::strcpy(__daemon_pidfile__, p.c_str()); daemon_pid_file_proc = __daemon_pid_file_proc__; } catch (const dtn::daemon::Configuration::ParameterNotSetException&) { }; /* Check if we are called with -k parameter */ if (conf.getDaemon().kill_daemon()) { 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 */ /* 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, SIGUSR1, SIGUSR2, 0) < 0) { daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno)); daemon_retval_send(3); goto finish; } ret = __daemon_run(); finish: /* Do a cleanup */ daemon_log(LOG_INFO, "Exiting..."); daemon_retval_send(255); daemon_signal_done(); daemon_pid_file_remove(); } return ret; } else { #endif // run the daemon return __daemon_run(); #ifdef HAVE_LIBDAEMON } #endif }
int main(int argc, char *argv[]) { int r = 255; int wrote_pid_file = 0; avahi_set_log_function(log_function); init_rand_seed(); avahi_server_config_init(&config.server_config); config.command = DAEMON_RUN; config.daemonize = 0; config.config_file = NULL; #ifdef HAVE_DBUS config.enable_dbus = 1; config.fail_on_missing_dbus = 1; config.n_clients_max = 0; config.n_objects_per_client_max = 0; config.n_entries_per_entry_group_max = 0; #endif config.drop_root = 1; config.set_rlimits = 1; #ifdef ENABLE_CHROOT config.use_chroot = 1; #endif config.modify_proc_title = 1; config.disable_user_service_publishing = 0; config.publish_dns_servers = NULL; config.publish_resolv_conf = 0; config.use_syslog = 0; config.debug = 0; config.rlimit_as_set = 0; config.rlimit_core_set = 0; config.rlimit_data_set = 0; config.rlimit_fsize_set = 0; config.rlimit_nofile_set = 0; config.rlimit_stack_set = 0; #ifdef RLIMIT_NPROC config.rlimit_nproc_set = 0; #endif if ((argv0 = strrchr(argv[0], '/'))) argv0 = avahi_strdup(argv0 + 1); else argv0 = avahi_strdup(argv[0]); daemon_pid_file_ident = (const char *) argv0; daemon_log_ident = (char*) argv0; daemon_pid_file_proc = pid_file_proc; if (parse_command_line(&config, argc, argv) < 0) goto finish; if (config.modify_proc_title) avahi_init_proc_title(argc, argv); #ifdef ENABLE_CHROOT config.use_chroot = config.use_chroot && config.drop_root; #endif if (config.command == DAEMON_HELP) { help(stdout); r = 0; } else if (config.command == DAEMON_VERSION) { printf("%s "PACKAGE_VERSION"\n", argv0); r = 0; } else if (config.command == DAEMON_KILL) { if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) { avahi_log_warn("Failed to kill daemon: %s", strerror(errno)); goto finish; } r = 0; } else if (config.command == DAEMON_RELOAD) { if (daemon_pid_file_kill(SIGHUP) < 0) { avahi_log_warn("Failed to kill daemon: %s", strerror(errno)); goto finish; } r = 0; } else if (config.command == DAEMON_CHECK) r = (daemon_pid_file_is_running() >= 0) ? 0 : 1; else if (config.command == DAEMON_RUN) { pid_t pid; if (getuid() != 0 && config.drop_root) { avahi_log_error("This program is intended to be run as root."); goto finish; } if ((pid = daemon_pid_file_is_running()) >= 0) { avahi_log_error("Daemon already running on PID %u", pid); goto finish; } if (load_config_file(&config) < 0) goto finish; if (config.daemonize) { daemon_retval_init(); if ((pid = daemon_fork()) < 0) goto finish; else if (pid != 0) { int ret; /** Parent **/ if ((ret = daemon_retval_wait(20)) < 0) { avahi_log_error("Could not receive return value from daemon process."); goto finish; } r = ret; goto finish; } /* Child */ } if (config.use_syslog || config.daemonize) daemon_log_use = DAEMON_LOG_SYSLOG; if (sd_listen_fds(0) <= 0) if (daemon_close_all(-1) < 0) avahi_log_warn("Failed to close all remaining file descriptors: %s", strerror(errno)); daemon_reset_sigs(-1); daemon_unblock_sigs(-1); if (make_runtime_dir() < 0) goto finish; if (config.drop_root) { #ifdef ENABLE_CHROOT if (config.use_chroot) if (avahi_caps_reduce() < 0) goto finish; #endif if (drop_root() < 0) goto finish; #ifdef ENABLE_CHROOT if (config.use_chroot) if (avahi_caps_reduce2() < 0) goto finish; #endif } if (daemon_pid_file_create() < 0) { avahi_log_error("Failed to create PID file: %s", strerror(errno)); if (config.daemonize) daemon_retval_send(1); goto finish; } else wrote_pid_file = 1; if (config.set_rlimits) enforce_rlimits(); chdir("/"); #ifdef ENABLE_CHROOT if (config.drop_root && config.use_chroot) if (avahi_chroot_helper_start(argv0) < 0) { avahi_log_error("failed to start chroot() helper daemon."); goto finish; } #endif avahi_log_info("%s "PACKAGE_VERSION" starting up.", argv0); sd_notifyf(0, "STATUS=%s "PACKAGE_VERSION" starting up.", argv0); avahi_set_proc_title(argv0, "%s: starting up", argv0); if (run_server(&config) == 0) r = 0; avahi_log_info("%s "PACKAGE_VERSION" exiting.", argv0); sd_notifyf(0, "STATUS=%s "PACKAGE_VERSION" exiting.", argv0); } finish: if (config.daemonize) daemon_retval_done(); avahi_server_config_free(&config.server_config); avahi_free(config.config_file); avahi_strfreev(config.publish_dns_servers); avahi_strfreev(resolv_conf_name_servers); avahi_strfreev(resolv_conf_search_domains); if (wrote_pid_file) { #ifdef ENABLE_CHROOT avahi_chroot_helper_unlink(pid_file_proc()); #else daemon_pid_file_remove(); #endif } #ifdef ENABLE_CHROOT avahi_chroot_helper_shutdown(); #endif avahi_free(argv0); return r; }
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; } }
int main(int argc, char *argv[]) { int index; int c; std::string ptp_dev("tun0"); std::string app_name("tunnel"); std::string endpoint("dtn:none"); unsigned int lifetime = 60; bool daemonize = false; bool stop_daemon = false; std::string pidfile; bool throughput = false; #ifdef HAVE_LIBDAEMON while ((c = getopt (argc, argv, "td:s:l:hDkp:")) != -1) #else while ((c = getopt (argc, argv, "td:s:l:h")) != -1) #endif switch (c) { #ifdef HAVE_LIBDAEMON case 'D': daemonize = true; break; case 'k': daemonize = true; stop_daemon = true; break; case 'p': pidfile = optarg; break; #endif case 'd': ptp_dev = optarg; break; case 't': throughput = true; break; case 's': app_name = optarg; break; case 'l': lifetime = atoi(optarg); break; default: print_help(argv[0]); return 1; } int optindex = 0; for (index = optind; index < argc; ++index) { switch (optindex) { case 0: endpoint = std::string(argv[index]); break; } optindex++; } // print help if not enough parameters are set if (!stop_daemon && (optindex < 1)) { print_help(argv[0]); exit(0); } // catch process signals ibrcommon::SignalHandler sighandler(term); sighandler.handle(SIGINT); sighandler.handle(SIGTERM); sighandler.handle(SIGQUIT); //initialize sighandler after possible exit call sighandler.initialize(); // logging options //const unsigned char logopts = ibrcommon::Logger::LOG_DATETIME | ibrcommon::Logger::LOG_LEVEL; const unsigned char logopts = 0; // error filter const unsigned char logerr = ibrcommon::Logger::LOGGER_ERR | ibrcommon::Logger::LOGGER_CRIT; // logging filter, everything but debug, err and crit const unsigned char logstd = ibrcommon::Logger::LOGGER_ALL ^ (ibrcommon::Logger::LOGGER_DEBUG | logerr); // syslog filter, everything but DEBUG and NOTICE const unsigned char logsys = ibrcommon::Logger::LOGGER_ALL ^ (ibrcommon::Logger::LOGGER_DEBUG | ibrcommon::Logger::LOGGER_NOTICE); #ifdef HAVE_LIBDAEMON if (daemonize) { // enable syslog logging ibrcommon::Logger::enableSyslog(argv[0], LOG_PID, LOG_DAEMON, logsys); } else #endif { // add logging to the cout ibrcommon::Logger::addStream(std::cout, logstd, logopts); // add logging to the cerr ibrcommon::Logger::addStream(std::cerr, logerr, logopts); } #ifdef HAVE_LIBDAEMON if (daemonize) { #ifdef HAVE_DAEMON_RESET_SIGS /* Reset signal handlers */ if (daemon_reset_sigs(-1) < 0) { IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to reset all signal handlers: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL; return 1; } /* Unblock signals */ if (daemon_unblock_sigs(-1) < 0) { IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to unblock all signals: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL; return 1; } #endif pid_t pid; /* Set identification string for the daemon for both syslog and PID file */ daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]); /* set the pid file path */ if (pidfile.length() > 0) { __daemon_pidfile__ = new char[pidfile.length() + 1]; ::strcpy(__daemon_pidfile__, pidfile.c_str()); daemon_pid_file_proc = __daemon_pid_file_proc__; } /* Check if we are called with -k parameter */ if (stop_daemon) { 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) IBRCOMMON_LOGGER_TAG("Core", warning) << "Failed to kill daemon: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL; 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) { IBRCOMMON_LOGGER_TAG("Core", error) << "Daemon already running on PID file " << pid << IBRCOMMON_LOGGER_ENDL; return 1; } /* Prepare for return value passing from the initialization procedure of the daemon process */ if (daemon_retval_init() < 0) { IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to create pipe." << IBRCOMMON_LOGGER_ENDL; 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) { IBRCOMMON_LOGGER_TAG("Core", error) << "Could not recieve return value from daemon process: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL; return 255; } return ret; } else { /* The daemon */ /* Close FDs */ if (daemon_close_all(-1) < 0) { IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to close all file descriptors: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL; /* Send the error condition to the parent process */ daemon_retval_send(1); /* Do a cleanup */ daemon_retval_send(255); daemon_signal_done(); daemon_pid_file_remove(); return -1; } /* Create the PID file */ if (daemon_pid_file_create() < 0) { IBRCOMMON_LOGGER_TAG("Core", error) << "Could not create PID file ( " << strerror(errno) << ")." << IBRCOMMON_LOGGER_ENDL; daemon_retval_send(2); /* Do a cleanup */ daemon_retval_send(255); daemon_signal_done(); daemon_pid_file_remove(); return -1; } /* Send OK to parent process */ daemon_retval_send(0); } } #endif IBRCOMMON_LOGGER_TAG("Core", info) << "IBR-DTN IP <-> Bundle Tunnel" << IBRCOMMON_LOGGER_ENDL; // create a connection to the dtn daemon ibrcommon::vaddress addr("localhost", 4550); ibrcommon::socketstream conn(new ibrcommon::tcpsocket(addr)); try { // set-up tun2bundle gateway TUN2BundleGateway gateway(app_name, conn, ptp_dev); _gateway = &gateway; IBRCOMMON_LOGGER_TAG("Core", info) << "Local: " << app_name << IBRCOMMON_LOGGER_ENDL; IBRCOMMON_LOGGER_TAG("Core", info) << "Peer: " << endpoint << IBRCOMMON_LOGGER_ENDL; IBRCOMMON_LOGGER_TAG("Core", info) << "Device: " << gateway.getDeviceName() << IBRCOMMON_LOGGER_ENDL; IBRCOMMON_LOGGER_TAG("Core", notice) << IBRCOMMON_LOGGER_ENDL; IBRCOMMON_LOGGER_TAG("Core", notice) << "Now you need to set-up the ip tunnel. You can use commands like this:" << IBRCOMMON_LOGGER_ENDL; IBRCOMMON_LOGGER_TAG("Core", notice) << "# sudo ip link set " << gateway.getDeviceName() << " up mtu 65535" << IBRCOMMON_LOGGER_ENDL; IBRCOMMON_LOGGER_TAG("Core", notice) << "# sudo ip addr add 10.0.0.1/24 dev " << gateway.getDeviceName() << IBRCOMMON_LOGGER_ENDL; IBRCOMMON_LOGGER_TAG("Core", notice) << IBRCOMMON_LOGGER_ENDL; timer_t timerid; struct sigevent sev; if (!daemonize && throughput) { // enable throughput timer signal(SIGRTMIN, timer_display_throughput); sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGRTMIN; sev.sigev_value.sival_ptr = &timerid; // create a timer timer_create(CLOCK_MONOTONIC, &sev, &timerid); // arm the timer struct itimerspec its; size_t freq_nanosecs = 200000000; its.it_value.tv_sec = freq_nanosecs / 1000000000;; its.it_value.tv_nsec = freq_nanosecs % 1000000000; its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; if (timer_settime(timerid, 0, &its, NULL) == -1) { IBRCOMMON_LOGGER_TAG("Core", error) << "Timer set failed." << IBRCOMMON_LOGGER_ENDL; } } // destination dtn::data::EID eid(endpoint); while (m_running) { gateway.process(eid, lifetime); } gateway.shutdown(); } catch (const ibrcommon::Exception &ex) { if (m_running) { IBRCOMMON_LOGGER_TAG("Core", error) << ex.what() << IBRCOMMON_LOGGER_ENDL; return -1; } } #ifdef HAVE_LIBDAEMON if (daemonize) { /* Do a cleanup */ IBRCOMMON_LOGGER_TAG("Core", info) << "Stopped " << app_name << IBRCOMMON_LOGGER_ENDL; daemon_retval_send(255); daemon_signal_done(); daemon_pid_file_remove(); } else #endif { std::cout << std::endl; } return 0; }
void parse_args(int argc, char *argv[]) { static struct option long_options[] = { {"no-auto", no_argument, 0, 'a'}, {"no-daemon", no_argument, 0, 'n'}, {"no-syslog", no_argument, 0, 's'}, {"no-beep", no_argument, 0, 'b'}, {"ignore-fail", no_argument, 0, 'f'}, {"ignore-fail-positive", no_argument, 0, 'F'}, {"ignore-retval", no_argument, 0, 'I'}, {"iface", required_argument, 0, 'i'}, {"run", required_argument, 0, 'r'}, {"poll-time", required_argument, 0, 't'}, {"delay-up", required_argument, 0, 'u'}, {"delay-down", required_argument, 0, 'd'}, {"api-mode", required_argument, 0, 'm'}, {"wait-on-fork", no_argument, 0, 'w'}, {"wait-on-kill", no_argument, 0, 'W'}, {"no-startup", no_argument, 0, 'p'}, {"no-shutdown", no_argument, 0, 'q'}, {"help", no_argument, 0, 'h'}, {"kill", no_argument, 0, 'k'}, {"check-running", no_argument, 0, 'c'}, {"version", no_argument, 0, 'v'}, {"extra-arg", required_argument, 0, 'x'}, {"suspend", no_argument, 0, 'S'}, {"resume", no_argument, 0, 'R'}, {"info", no_argument, 0, 'z'}, {"initial-down", no_argument, 0, 'l'}, {"monitor", no_argument, 0, 'M'}, {0, 0, 0, 0} }; int option_index = 0; int help = 0, _kill = 0, _check = 0, _version = 0, _suspend = 0, _resume = 0, _info = 0; for (;;) { int c; if ((c = getopt_long(argc, argv, "asni:r:t:u:d:hkbfFvm:pqwx:cISRzlMW", long_options, &option_index)) < 0) break; switch (c) { case 'a' : interface_auto_up = !interface_auto_up; break; case 's' : use_syslog = !use_syslog; break; case 'n' : daemonize = !daemonize; break; case 'i' : if (interface) free(interface); interface = strdup(optarg); break; case 'r': run = strdup(optarg); break; case 'I': ignore_retval = !ignore_retval; break; case 't': polltime = atoi(optarg); if (polltime < 0) polltime = 0; break; case 'u': delay_up = atoi(optarg); break; case 'd': delay_down = atoi(optarg); break; case 'h': help = 1; break; case 'k': _kill = 1; break; case 'c': _check = 1; break; case 'v': _version = 1; break; case 'b': use_beep = !use_beep; break; case 'f': failure_status = IFSTATUS_DOWN; break; case 'F': failure_status = IFSTATUS_UP; break; case 'm': switch (tolower(optarg[0])) { case 'e': api_mode = API_ETHTOOL; break; case 'm': api_mode = API_MII; break; case 'p': api_mode = API_PRIVATE; break; case 'w': api_mode = API_WLAN; break; case 'a': api_mode = API_AUTO; break; case 'i': api_mode = API_IFF; break; default: daemon_log(LOG_ERR, "Unknown API mode: %s", optarg); exit(2); } break; case 'p': no_startup_script = !no_startup_script; break; case 'q': no_shutdown_script = !no_shutdown_script; break; case 'l': initial_down = !initial_down; break; case 'w': wait_on_fork = !wait_on_fork; break; case 'W': wait_on_kill = !wait_on_kill; break; case 'x': extra_arg = strdup(optarg); break; case 'S': _suspend = 1; break; case 'R': _resume = 1; break; case 'z': _info = 1; break; case 'M': use_ifmonitor = !use_ifmonitor; break; default: daemon_log(LOG_ERR, "Unknown parameter."); exit(1); } } if (!interface) interface = strdup("eth0"); if (!use_syslog) daemon_log_use = DAEMON_LOG_STDERR; if (help) { usage(argv[0]); exit(0); } if (_kill || _resume || _suspend || _info) { int rv; if (_kill && wait_on_kill) rv = daemon_pid_file_kill_wait(SIGINT, 5); else rv = daemon_pid_file_kill(_kill ? SIGINT : (_resume ? SIGUSR2 : (_info ? SIGHUP : SIGUSR1))); if (rv < 0) { daemon_log(LOG_ERR, "Failed to kill daemon. (%s)", strerror(errno)); exit(6); } exit(0); } if (_version) { #ifdef SVN_REVISION printf("ifplugd "VERSION" (SVN: "SVN_REVISION")\n"); #else printf("ifplugd "VERSION"\n"); #endif exit(0); } if (_check) { pid_t pid = daemon_pid_file_is_running(); if (pid == (pid_t) -1 || pid == 0) { printf("ifplugd not running.\n"); exit(255); } else { printf("ifplugd process for device %s running as pid %u.\n", interface, pid); exit(0); } } }
int main(int argc, char **argv) { int pid, ret; struct sigaction new_action, old_action; GOptionContext *ctx; GError *parse_err = NULL; daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]); daemon_pid_file_proc = conf_pid_file_proc; if (conf_init() < 0) return EXIT_FAILURE; ctx = g_option_context_new(""); g_option_context_add_main_entries(ctx, options, PACKAGE); g_option_context_set_summary(ctx, PACKAGE"-"VERSION GITHEAD" - mpd cron daemon"); if (!g_option_context_parse(ctx, &argc, &argv, &parse_err)) { g_printerr("option parsing failed: %s\n", parse_err->message); g_option_context_free(ctx); g_error_free(parse_err); return EXIT_FAILURE; } g_option_context_free(ctx); if (optv) { about(); cleanup(); return EXIT_SUCCESS; } #ifdef DAEMON_SET_VERBOSITY_AVAILABLE if (conf.no_daemon) daemon_set_verbosity(LOG_DEBUG); #endif /* DAEMON_SET_VERBOSITY_AVAILABLE */ /* Version to environment variable */ g_setenv("MPDCRON_PACKAGE", PACKAGE, 1); g_setenv("MPDCRON_VERSION", VERSION, 1); g_setenv("MPDCRON_GITHEAD", GITHEAD, 1); /* Command line options to environment variables */ if (conf.no_daemon) g_unsetenv("MCOPT_DAEMONIZE"); else g_setenv("MCOPT_DAEMONIZE", "1", 1); /* Important! Parse configuration file before killing the daemon * because the configuration file has a pidfile and killwait option. */ cfd = g_key_file_new(); if (keyfile_load(&cfd) < 0) { cleanup(); return EXIT_FAILURE; } if (optk) { if (daemon_pid_file_kill_wait(SIGINT, conf.killwait) < 0) { g_warning("Failed to kill daemon: %s", strerror(errno)); cleanup(); return EXIT_FAILURE; } daemon_pid_file_remove(); cleanup(); return EXIT_SUCCESS; } /* Logging */ g_log_set_default_handler(log_handler, GINT_TO_POINTER(conf.no_daemon ? 5 : conf.loglevel)); /* Signal handling */ new_action.sa_handler = sig_cleanup; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; #define HANDLE_SIGNAL(sig) \ do { \ sigaction((sig), NULL, &old_action); \ if (old_action.sa_handler != SIG_IGN) \ sigaction((sig), &new_action, NULL); \ } while (0) HANDLE_SIGNAL(SIGABRT); HANDLE_SIGNAL(SIGSEGV); HANDLE_SIGNAL(SIGINT); HANDLE_SIGNAL(SIGTERM); #undef HANDLE_SIGNAL if (conf.no_daemon) { /* Create the main loop */ loop = g_main_loop_new(NULL, FALSE); #ifdef HAVE_GMODULE /* Load modules which may add initial events */ keyfile_load_modules(&cfd); #endif /* HAVE_GMODULE */ g_key_file_free(cfd); cfd = NULL; /* Add default initial events */ loop_connect(); /* Run the main loop */ g_main_loop_run(loop); cleanup(); return EXIT_SUCCESS; } /* Daemonize */ if ((pid = daemon_pid_file_is_running()) > 0) { g_critical("Daemon already running on PID %u", pid); return EXIT_FAILURE; } daemon_retval_init(); pid = daemon_fork(); if (pid < 0) { g_critical("Failed to fork: %s", strerror(errno)); daemon_retval_done(); return EXIT_FAILURE; } else if (pid != 0) { /* Parent */ cleanup(); if ((ret = daemon_retval_wait(2)) < 0) { g_critical("Could not receive return value from daemon process: %s", strerror(errno)); return 255; } if (ret != 0) g_critical("Daemon returned %i as return value", ret); else g_critical("Daemon returned %i as return value", ret); return ret; } else { /* Daemon */ if (daemon_close_all(-1) < 0) { g_critical("Failed to close all file descriptors: %s", strerror(errno)); daemon_retval_send(1); return EXIT_FAILURE; } if (daemon_pid_file_create() < 0) { g_critical("Failed to create PID file: %s", strerror(errno)); daemon_retval_send(2); return EXIT_FAILURE; } /* Send OK to parent process */ daemon_retval_send(0); /* Create the main loop */ loop = g_main_loop_new(NULL, FALSE); #ifdef HAVE_GMODULE /* Load modules which may add initial events */ keyfile_load_modules(&cfd); #endif /* HAVE_GMODULE */ g_key_file_free(cfd); cfd = NULL; /* Add default initial events */ loop_connect(); /* Run the main loop */ g_main_loop_run(loop); cleanup(); return EXIT_SUCCESS; } return EXIT_SUCCESS; }
/** * Read the config file, determine if we should daemonize or not, * and set up libevent dispatches. */ int main(int argc, char *argv[]) { int cmdline_debug_level = 0; int foreground = 0; int option; pid_t pid; int kill=0; int ret; /* set some sane config defaults */ memset((void*)&config, 0, sizeof(gopher_conf_t)); config.port = 70; config.base_dir = "."; config.socket_backlog = 5; config.config_file = DEFAULT_CONFIGFILE; while((option = getopt(argc, argv, "d:c:fp:s:k")) != -1) { switch(option) { case 'd': cmdline_debug_level = atoi(optarg); if(cmdline_debug_level < 1 || cmdline_debug_level > 5) { ERROR("Debug level must be 1-5 (default %d)", DEFAULT_DEBUGLEVEL); usage_quit(argv[0]); } break; case 'c': config.config_file = optarg; break; case 'f': foreground = 1; break; case 'p': config.port = atoi(optarg); break; case 's': config.base_dir = optarg; case 'k': kill = 1; break; default: usage_quit(argv[0]); } } debug_level(cmdline_debug_level ? cmdline_debug_level : DEFAULT_DEBUGLEVEL); /* kill before config, so we don't have to specify a config file */ daemon_pid_file_ident = daemon_ident_from_argv0(argv[0]); /* kill? */ if(kill) { if((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0) { ERROR("Failed to kill daemon: %s", strerror(errno)); } exit(ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS); } if((pid = daemon_pid_file_is_running()) >= 0) { ERROR("Daemon already running as pid %u", pid); exit(EXIT_FAILURE); } /* TODO: read the config file and verify sufficient config */ debug_level(cmdline_debug_level); /* daemonize, or check for background daemon */ if(!foreground) { debug_output(DBG_OUTPUT_SYSLOG, "evgopherd"); if(daemon_retval_init() < 0) { ERROR("Could not set up daemon pipe"); exit(EXIT_FAILURE); } if((pid = daemon_fork()) < 0) { daemon_retval_done(); ERROR("Forking error: %s", strerror(errno)); exit(EXIT_FAILURE); } else if (pid) { /* parent */ if((ret = daemon_retval_wait(5)) < 0) { ERROR("Could not receive startup retval from daemon process: %s", strerror(errno)); exit(EXIT_FAILURE); } if(ret > 0) ERROR("Daemon declined to start. Error: %d\n", ret); exit(ret == 0 ? EXIT_SUCCESS :EXIT_FAILURE); } } if(daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGPIPE, 0) < 0) { ERROR("Could not set up signal handlers: %s", strerror(errno)); goto finish; } if(!foreground) { if(daemon_pid_file_create() < 0) { ERROR("Could not create pidfile: %s", strerror(errno)); if(!foreground) daemon_retval_send(2); goto finish; } /* should close handles here */ daemon_retval_send(0); /* started up to the point that we can rely on syslog */ } WARN("Daemon started"); /* need to fork off a watchdog process */ while(!g_quitflag) { /* fork and wait */ pid_t pid = fork(); if(pid == -1) { ERROR("Error forking child process. Aborting"); g_quitflag = 1; } else if(pid == 0) { /* child */ do_child_process(); } else { /* parent */ int status; waitpid(pid, &status, 0); if(WIFEXITED(status) && WEXITSTATUS(status)) { /* exited with error */ ERROR("Error initializing child process. Aborting"); g_quitflag=1; } else if(!WIFEXITED(status)) { ERROR("Child process (%d) crashed. Restarting.", pid); } else { /* graceful exit... we've obviously terminated */ g_quitflag = 1; } } } WARN("Daemon exiting gracefully"); finish: daemon_signal_done(); daemon_pid_file_remove(); return EXIT_SUCCESS; }