コード例 #1
0
ファイル: pseudo_wrappers.c プロジェクト: incandescant/pseudo
int wrap_clone_child(void *args) {
	struct clone_args *clargs = args;

	int (*fn)(void *) = clargs->fn;
	int flags = clargs->flags;
	void *arg = clargs->arg;

	/* We always free in the client */
	free(clargs);

	if (!(flags & CLONE_VM)) {
		pseudo_setupenv();
		if (!pseudo_has_unload(NULL)) {
			pseudo_reinit_libpseudo();
		} else {
			pseudo_dropenv();
		}
	}

	return fn(arg);
}
コード例 #2
0
ファイル: pseudo_client.c プロジェクト: cgwalters/pseudo
/* spawn server */
static int
client_spawn_server(void) {
	int status;
	FILE *fp;
	char * pseudo_pidfile;

	if ((server_pid = fork()) != 0) {
		if (server_pid == -1) {
			pseudo_diag("couldn't fork server: %s\n", strerror(errno));
			return 1;
		}
		pseudo_debug(4, "spawned server, pid %d\n", server_pid);
		/* wait for the child process to terminate, indicating server
		 * is ready
		 */
		waitpid(server_pid, &status, 0);
		server_pid = -2;
		pseudo_pidfile = pseudo_localstatedir_path(PSEUDO_PIDFILE);
		fp = fopen(pseudo_pidfile, "r");
		if (fp) {
			if (fscanf(fp, "%d", &server_pid) != 1) {
				pseudo_debug(1, "Opened server PID file, but didn't get a pid.\n");
			}
			fclose(fp);
		} else {
			pseudo_debug(1, "no pid file (%s): %s\n",
				pseudo_pidfile, strerror(errno));
		}
		pseudo_debug(2, "read new pid file: %d\n", server_pid);
		free(pseudo_pidfile);
		/* at this point, we should have a new server_pid */
		return 0;
	} else {
		char *base_args[] = { NULL, NULL, NULL };
		char **argv;
		char *option_string = pseudo_get_value("PSEUDO_OPTS");
		int args;
		int fd;

		pseudo_new_pid();
		base_args[0] = pseudo_bindir_path("pseudo");
		base_args[1] = "-d";
		if (option_string) {
			char *s;
			int arg;

			/* count arguments in PSEUDO_OPTS, starting at 2
			 * for pseudo/-d/NULL, plus one for the option string.
			 * The number of additional arguments may be less
			 * than the number of spaces, but can't be more.
			 */
			args = 4;
			for (s = option_string; *s; ++s)
				if (*s == ' ')
					++args;

			argv = malloc(args * sizeof(char *));
			argv[0] = base_args[0];
			argv[1] = base_args[1];
			arg = 2;
			while ((s = strsep(&option_string, " ")) != NULL) {
				if (*s) {
					argv[arg++] = strdup(s);
				}
			}
			argv[arg] = 0;
		} else {
			argv = base_args;
		}

		/* close any higher-numbered fds which might be open,
		 * such as sockets.  We don't have to worry about 0 and 1;
		 * the server closes them already, and more importantly,
		 * they can't have been opened or closed without us already
		 * having spawned a server... The issue is just socket()
		 * calls which could result in fds being left open, and those
		 * can't overwrite fds 0-2 unless we closed them...
		 * 
		 * No, really.  It works.
		 */
		for (fd = 3; fd < 1024; ++fd) {
			if (fd != pseudo_util_debug_fd)
				close(fd);
		}
		/* and now, execute the server */

		pseudo_set_value("PSEUDO_RELOADED", "YES");
		pseudo_setupenv();
		pseudo_dropenv(); /* drop PRELINK_LIBRARIES */

		pseudo_debug(4, "calling execv on %s\n", argv[0]);

		execv(argv[0], argv);
		pseudo_diag("critical failure: exec of pseudo daemon failed: %s\n", strerror(errno));
		exit(1);
	}
}