/* Connects to a Vlog server socket. 'path' may be: * * - A string that starts with a PID. If a non-null, non-absolute name * was passed to Vlog_server_socket::listen(), then it must follow the * PID in 'path'. * * - An absolute path (starting with '/') to a Vlog server socket or a * pidfile. If it is a pidfile, the pidfile will be read and translated * into a Vlog server socket file name. * * - A relative path, which is translated into a pidfile name and then * treated as above. * * Returns 0 if successful, otherwise a positive errno value. If successful, * sets '*clientp' to the new vlog_client, otherwise to NULL. */ int vlog_client_connect(const char *path, struct vlog_client **clientp) { static int counter; struct vlog_client *client; struct stat s; int error; client = xmalloc(sizeof *client); if (path[0] == '/') { client->connect_path = xstrdup(path); } else if (isdigit((unsigned char) path[0])) { client->connect_path = xasprintf("/tmp/vlogs.%s", path); } else { client->connect_path = make_pidfile_name(path); } client->bind_path = NULL; if (stat(client->connect_path, &s)) { error = errno; VLOG_WARN("could not stat \"%s\": %s", client->connect_path, strerror(error)); goto error; } else if (S_ISREG(s.st_mode)) { pid_t pid = read_pidfile(client->connect_path); if (pid < 0) { error = -pid; VLOG_WARN("could not read pidfile \"%s\": %s", client->connect_path, strerror(error)); goto error; } free(client->connect_path); client->connect_path = xasprintf("/tmp/vlogs.%ld", (long int) pid); } client->bind_path = xasprintf("/tmp/vlog.%ld.%d", (long int) getpid(), counter++); client->fd = make_unix_socket(SOCK_DGRAM, false, false, client->bind_path, client->connect_path); if (client->fd < 0) { error = -client->fd; goto error; } *clientp = client; return 0; error: free(client->connect_path); free(client->bind_path); free(client); *clientp = NULL; return error; }
/** Returns true if there is already another Vidalia process running. */ bool is_vidalia_running(const QString &pidfile) { /* Read the pidfile and find out if that process still exists */ qint64 pid = read_pidfile(pidfile); if (pid > 0) { #if defined(Q_OS_WIN32) if (QSysInfo::WindowsVersion == QSysInfo::WV_NT) { /* We currently can't get a list of running processes on Windows NT, so * be pessimistic and assume the existence of a nonzero pidfile means * Vidalia is running. */ return true; } else return (is_process_running(pid)); #else return (is_process_running(pid)); #endif } return false; }
/* Kill the currently running slurmdbd */ static void _kill_old_slurmdbd(void) { int fd; pid_t oldpid; if (slurmdbd_conf->pid_file == NULL) { error("No PidFile configured"); return; } oldpid = read_pidfile(slurmdbd_conf->pid_file, &fd); if (oldpid != (pid_t) 0) { info("Killing old slurmdbd[%ld]", (long) oldpid); kill(oldpid, SIGTERM); /* * Wait for previous daemon to terminate */ if (fd_get_readw_lock(fd) < 0) fatal("Unable to wait for readw lock: %m"); (void) close(fd); /* Ignore errors */ } }
int32_t main(int argc, char *argv[]) { int32_t opt; uint32_t n; char *cfgfile = NULL; struct stat sb; struct bitcoind *b, *sigfrom; struct psj *psj; struct sigaction act; struct config *cfg; cfg = malloc(sizeof(*cfg)); if (cfg == NULL) { APPLOG(LOG_CRIT, "cfg malloc failed"); exit(255); } while ((opt = getopt(argc, argv, "hs:c:")) != -1) { switch(opt) { case 'c': cfgfile = optarg; break; case 's': cfg->force_pid = atoi(optarg); break; default: case 'h': usage(); } } APPLOG(LOG_NOTICE, "psj_sigmon v0.5 starting up"); /* config file parsing */ if (parse_cfg(cfgfile ? cfgfile : "config.cfg", cfg)) { APPLOG(LOG_CRIT, "parse_cfg error"); exit(255); } if (cfg->bitcoind_used == 0) { APPLOG(LOG_CRIT, "no bitcoind defined, exiting"); exit(EXIT_SUCCESS); } if (cfg->psj_used == 0) { APPLOG(LOG_CRIT, "no psj defined, exiting"); exit(EXIT_SUCCESS); } if (cfg->pidfile) { if (write_pidfile(cfg->pidfile) != 0) { APPLOG(LOG_CRIT, "write_pidfile failed"); exit(255); } } if (cfg->daemon) { APPLOG(LOG_NOTICE, "daemonising, you will hear no more from me"); if (daemon(false, false) == -1) { APPLOG(LOG_CRIT, "except daemonising failed.. dying"); exit(255); } cfg->daemon_done = true; } /* install signal handlers */ act.sa_flags = SA_SIGINFO; act.sa_sigaction = &sig_handler; sigaction(SIGUSR1, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); while(1) { select(0, NULL, NULL, NULL, NULL); APPLOG(LOG_INFO, "got signal %d, from pid %d", sig, pid); /* handle INT and TERM */ if (sig == SIGINT || sig == SIGTERM) /* break out of loop and exit gracefully */ break; /* ignore non-USR1 */ if (sig != SIGUSR1) continue; if (cfg->force_pid) { pid = cfg->force_pid; APPLOG(LOG_DEBUG, "forcing sending-pid to %d", pid); } sigfrom = NULL; for(n = 0 ; n < cfg->bitcoind_used ; n++) { /* check if pid == this bitcoind's pid */ b = cfg->bitcoind_list[n]; if (stat(b->pidfile, &sb) == -1) { APPLOG(LOG_WARNING, "%s on stat of %s", strerror(errno), b->pidfile); continue; } if (sb.st_mtime > b->pidfile_mtime) { /* refresh what we think the pid is of this * bitcoind */ b->pid = read_pidfile(b->pidfile); b->pidfile_mtime = sb.st_mtime; APPLOG(LOG_DEBUG, "%s changed: new pid is %u", b->pidfile, b->pid); } if (b->pid == pid) { APPLOG(LOG_DEBUG, "signal matches %s (%s)", b->pidfile, b->name); sigfrom = b; break; } } if (sigfrom == NULL) { APPLOG(LOG_WARNING, "signal not from a recognised pid"); continue; } /* tell each psj about b->name */ for(n = 0 ; n < cfg->psj_used ; n++) { psj = cfg->psj_list[n]; APPLOG(LOG_INFO, "notifying %s of signal", psj->hostport); poke_psj(cfg,psj, b); } } APPLOG(LOG_INFO, "shutting down, removing pidfile"); unlink(cfg->pidfile); /* we're lazy, the kernel will clean up our memory, sorry valgrind :p */ return EXIT_SUCCESS; }
int main(int argc, char **argv) { struct ctrlproxyd_config *config; GOptionContext *pc; const char *config_file = DEFAULT_CONFIG_FILE; gboolean version = FALSE; gboolean foreground = FALSE; gboolean isdaemon = TRUE; pid_t pid; GOptionEntry options[] = { {"config-file", 'c', 0, G_OPTION_ARG_STRING, &config_file, "Configuration file", "CONFIGFILE"}, {"foreground", 'F', 0, G_OPTION_ARG_NONE, &foreground, ("Stay in the foreground") }, {"inetd", 'I', 0, G_OPTION_ARG_NONE, &inetd, ("Run in inetd mode")}, {"version", 'v', 0, G_OPTION_ARG_NONE, &version, ("Show version information")}, { NULL } }; GError *error = NULL; daemon_listener = g_new0(struct irc_listener, 1); signal(SIGINT, signal_quit); signal(SIGTERM, signal_quit); #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); #endif #ifdef SIGHUP signal(SIGHUP, SIG_IGN); #endif #ifdef SIGSEGV signal(SIGSEGV, signal_crash); #endif main_loop = g_main_loop_new(NULL, FALSE); pc = g_option_context_new(""); g_option_context_add_main_entries(pc, options, NULL); if (!g_option_context_parse(pc, &argc, &argv, &error)) { fprintf(stderr, "%s\n", error->message); g_error_free(error); return 1; } g_option_context_free(pc); if (version) { printf("ctrlproxy %s\n", VERSION); printf("(c) 2002-2009 Jelmer Vernooij et al. <*****@*****.**>\n"); return 0; } global_daemon_config = config = read_config_file(config_file); if (config == NULL) { return 1; } pid = read_pidfile(PIDFILE); if (pid != -1) { fprintf(stderr, "ctrlproxyd already running at pid %d!\n", pid); return 1; } isdaemon = (!foreground && !inetd); if (gethostname(my_hostname, NI_MAXHOST) != 0) { fprintf(stderr, "Can't figure out hostname of local host!\n"); return 1; } if (isdaemon) { #if defined(HAVE_DAEMON) || defined(HAVE_FORK) #ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); #endif #ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); #endif #ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); #endif if (daemon(1, 0) < 0) { fprintf(stderr, "Unable to daemonize\n"); return -1; } #else fprintf(stderr, "Daemon mode not compiled in\n"); return -1; #endif } openlog("ctrlproxyd", 0, LOG_DAEMON); daemon_listener->iconv = (GIConv)-1; if (foreground) daemon_listener->log_fn = listener_stderr; else daemon_listener->log_fn = listener_syslog; daemon_listener->ops = &daemon_ops; daemon_listener->ssl = config->ssl; daemon_listener->ssl_credentials = config->ssl_credentials; if (inetd) { GIOChannel *io = g_io_channel_unix_new(0); listener_new_pending_client(daemon_listener, io); } else { write_pidfile(PIDFILE); if (!listener_start_tcp(daemon_listener, config->address, config->port)) return 1; } foreach_daemon_user(config, daemon_listener, daemon_user_start_if_exists); g_main_loop_run(main_loop); daemon_clients_exit(); return 0; }
/* * Start a process and return its status information. The status information * is also stored in the global processes linked list so that it can be * stopped automatically on program exit. * * The boolean argument says whether to start the process under fakeroot. If * true, PATH_FAKEROOT must be defined, generally by Autoconf. If it's not * found, call skip_all. * * This is a helper function for process_start and process_start_fakeroot. */ static struct process * process_start_internal(const char *const argv[], const char *pidfile, bool fakeroot) { size_t i; int log_fd; const char *name; struct timeval tv; struct process *process; const char **fakeroot_argv = NULL; const char *path_fakeroot = PATH_FAKEROOT; /* Check prerequisites. */ if (fakeroot && path_fakeroot[0] == '\0') skip_all("fakeroot not found"); /* Create the process struct and log file. */ process = bcalloc(1, sizeof(struct process)); process->pidfile = bstrdup(pidfile); process->tmpdir = test_tmpdir(); name = strrchr(argv[0], '/'); if (name != NULL) name++; else name = argv[0]; basprintf(&process->logfile, "%s/%s.log.XXXXXX", process->tmpdir, name); log_fd = mkstemp(process->logfile); if (log_fd < 0) sysbail("cannot create log file for %s", argv[0]); /* If using fakeroot, rewrite argv accordingly. */ if (fakeroot) { for (i = 0; argv[i] != NULL; i++) ; fakeroot_argv = bcalloc(2 + i + 1, sizeof(const char *)); fakeroot_argv[0] = path_fakeroot; fakeroot_argv[1] = "--"; for (i = 0; argv[i] != NULL; i++) fakeroot_argv[i + 2] = argv[i]; fakeroot_argv[i + 2] = NULL; argv = fakeroot_argv; } /* * Fork off the child process, redirect its standard output and standard * error to the log file, and then exec the program. */ process->pid = fork(); if (process->pid < 0) sysbail("fork failed"); else if (process->pid == 0) { if (dup2(log_fd, STDOUT_FILENO) < 0) sysbail("cannot redirect standard output"); if (dup2(log_fd, STDERR_FILENO) < 0) sysbail("cannot redirect standard error"); close(log_fd); if (execv(argv[0], (char *const *) argv) < 0) sysbail("exec of %s failed", argv[0]); } close(log_fd); free(fakeroot_argv); /* * In the parent. Wait for the child to start by watching for the PID * file to appear in 100ms intervals. */ for (i = 0; i < PROCESS_WAIT * 10 && access(pidfile, F_OK) != 0; i++) { tv.tv_sec = 0; tv.tv_usec = 100000; select(0, NULL, NULL, NULL, &tv); } /* * If the PID file still hasn't appeared after ten seconds, attempt to * kill the process and then bail. */ if (access(pidfile, F_OK) != 0) { kill(process->pid, SIGTERM); alarm(5); waitpid(process->pid, NULL, 0); alarm(0); bail("cannot start %s", argv[0]); } /* * Read the PID back from the PID file. This usually isn't necessary for * non-forking daemons, but always doing this makes this function general, * and it's required when running under fakeroot. */ if (fakeroot) process->pid = read_pidfile(pidfile); process->is_child = !fakeroot; /* Register the log file as a source of diag messages. */ diag_file_add(process->logfile); /* * Add the process to our global list and set our cleanup handler if this * is the first process we started. */ if (processes == NULL) test_cleanup_register(process_stop_all); process->next = processes; processes = process; /* All done. */ return process; }