/* 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;
}
示例#2
0
文件: main.cpp 项目: Bodyfarm/vidalia
/** 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;
}
示例#3
0
文件: slurmdbd.c 项目: lindenb/slurm
/* 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;
}
示例#5
0
文件: main.c 项目: jelmer/ctrlproxy
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;
}
示例#6
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;
}