예제 #1
0
ATF_TC_BODY(closefrom_buffer, tc)
{
	int buf[16], cur, half;
	size_t i;

	/*
	 * Open a buffer of descriptors, close the half of
	 * these and verify that the result is consistent.
	 */
	ATF_REQUIRE(closefrom(STDERR_FILENO + 1) == 0);

	cur = fcntl(0, F_MAXFD);
	ATF_REQUIRE(cur == STDERR_FILENO);

	for (i = 0; i < __arraycount(buf); i++) {
		buf[i] = open(path, O_RDWR | O_CREAT, 0600);
		ATF_REQUIRE(buf[i] >= 0);
	}

	cur = fcntl(0, F_MAXFD);
	ATF_REQUIRE(cur == __arraycount(buf) + STDERR_FILENO);

	half = STDERR_FILENO + __arraycount(buf) / 2;
	ATF_REQUIRE(closefrom(half) == 0);

	cur = fcntl(0, F_MAXFD);
	ATF_REQUIRE(cur == half - 1);

	for (i = 0; i < __arraycount(buf); i++)
		(void)close(buf[i]);
}
예제 #2
0
/*
 * Test that closefrom does the right thing in a threaded programs,
 * specifically that it doesn't kill the thread kernel signal pipe.
 */
int
main(int argc, char *argv[])
{
	pthread_t thread;
	void *status;
	int fd;
	int result;

	/* close files above stderr.   The kernel pipes shouldn't be touched */
	fd = STDERR_FILENO + 1;
	result = closefrom(fd);
	printf("closefrom(%d) == %d/%d\n", fd, result, errno);

	/* do it again: make sure that the result is -1/EBADF */
	result = closefrom(fd);
	printf("closefrom(%d) == %d/%d\n", fd, result, errno);
	ASSERT(result == -1 && errno == EBADF);

	/* start a thread to verify the thread kernel is working */
	CHECKr(pthread_create(&thread, NULL, dummy_thread, NULL));
	CHECKr(pthread_join(thread, &status));
	printf("dummy thread exited with status %p\n", status);

	SUCCEED;
	return 0;
}
int
main(void)
{
	int i, max, fds[NUM_OPENS];
	char buf[512];

	for (i = 0; i < NUM_OPENS; i++)
		if ((fds[i] = open("/dev/null", O_RDONLY)) == -1)
			exit(0);	/* can't test */
	max = i - 1;

	/* should close last fd only */
	closefrom(fds[max]);
	if (close(fds[max]) != -1)
		fail("failed to close highest fd");

	/* make sure we can still use remaining descriptors */
	for (i = 0; i < max; i++)
		if (read(fds[i], buf, sizeof(buf)) == -1)
			fail("closed descriptors it should not have");

	/* should close all fds */
	closefrom(fds[0]);
	for (i = 0; i < NUM_OPENS; i++)
		if (close(fds[i]) != -1)
			fail("failed to close from lowest fd");
}
예제 #4
0
/*
 * detach from tty
 */
static void
detachfromtty(void)
{
	nscd_rc_t	rc;
	char		*me = "detachfromtty";

	if (_logfd > 0) {
		int i;
		for (i = 0; i < _logfd; i++)
			(void) close(i);
		closefrom(_logfd + 1);
	} else
		closefrom(0);

	(void) chdir("/");

	switch (fork1()) {
	case (pid_t)-1:

		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "unable to fork: pid = %d, %s\n",
		    getpid(), strerror(errno));

		exit(1);
		break;
	case 0:
		/* start the forker nscd if so configured */
		_nscd_start_forker(saved_execname, saved_argc, saved_argv);
		break;
	default:
		exit(0);
	}

	(void) setsid();
	(void) open("/dev/null", O_RDWR, 0);
	(void) dup(0);
	if (_logfd != 2)
		(void) dup(0);

	/*
	 * start monitoring the states of the name service clients
	 */
	rc = _nscd_init_smf_monitor();
	if (rc != NSCD_SUCCESS) {
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
	(me, "unable to start the SMF monitor (rc = %d)\n", rc);

		exit(-1);
	}
}
예제 #5
0
파일: main.c 프로젝트: darksoul42/bitrig
__dead void
ctl_openconsole(const char *name)
{
	closefrom(STDERR_FILENO + 1);
	execl(VMCTL_CU, VMCTL_CU, "-l", name, "-s", "9600", NULL);
	err(1, "failed to open the console");
}
예제 #6
0
ATF_TC_BODY(closefrom_one, tc)
{
	pid_t pid;
	int sta;

	pid = fork();
	ATF_REQUIRE(pid >= 0);

	if (pid == 0) {

		if (closefrom(1) != 0)
			_exit(10);

		_exit(fcntl(0, F_MAXFD));
	}


	(void)wait(&sta);

	/*
	 * STDIN_FILENO sould still be open; WEXITSTATUS(1) == 0.
	 */
	if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != 0)
		atf_tc_fail("not all descriptors were closed");
}
예제 #7
0
파일: tmux.c 프로젝트: MarvinZhuang/tmate
__dead void
shell_exec(const char *shell, const char *shellcmd)
{
	const char	*shellname, *ptr;
	char		*argv0;

	ptr = strrchr(shell, '/');
	if (ptr != NULL && *(ptr + 1) != '\0')
		shellname = ptr + 1;
	else
		shellname = shell;
	if (login_shell)
		xasprintf(&argv0, "-%s", shellname);
	else
		xasprintf(&argv0, "%s", shellname);
	setenv("SHELL", shell, 1);

	setblocking(STDIN_FILENO, 1);
	setblocking(STDOUT_FILENO, 1);
	setblocking(STDERR_FILENO, 1);
	closefrom(STDERR_FILENO + 1);

	execl(shell, argv0, "-c", shellcmd, (char *) NULL);
	fatal("execl failed");
}
예제 #8
0
파일: tmux.c 프로젝트: ddollar/tmux
__dead void
shell_exec(const char *shell, const char *shellcmd)
{
	const char	*shellname, *ptr;
	char		*argv0;
	int		 mode;

	ptr = strrchr(shell, '/');
	if (ptr != NULL && *(ptr + 1) != '\0')
		shellname = ptr + 1;
	else
		shellname = shell;
	if (login_shell)
		xasprintf(&argv0, "-%s", shellname);
	else
		xasprintf(&argv0, "%s", shellname);
	setenv("SHELL", shell, 1);

	if ((mode = fcntl(STDIN_FILENO, F_GETFL)) != -1)
		fcntl(STDIN_FILENO, F_SETFL, mode & ~O_NONBLOCK);
	if ((mode = fcntl(STDOUT_FILENO, F_GETFL)) != -1)
		fcntl(STDOUT_FILENO, F_SETFL, mode & ~O_NONBLOCK);
	if ((mode = fcntl(STDERR_FILENO, F_GETFL)) != -1)
		fcntl(STDERR_FILENO, F_SETFL, mode & ~O_NONBLOCK);
	closefrom(STDERR_FILENO + 1);

	execl(shell, argv0, "-c", shellcmd, (char *) NULL);
	fatal("execl failed");
}
예제 #9
0
static int
daemonize_self(void)
{
	pid_t pid;
	int fd;

	(void) close(STDIN_FILENO);

	if ((fd = open(DEV_NULL, O_RDONLY)) == -1) {
		(void) printf("Could not open /dev/null: %s\n",
		    strerror(errno));
	} else if (fd != STDIN_FILENO) {
		(void) dup2(fd, STDIN_FILENO);
		(void) close(fd);
	}
	(void) dup2(STDERR_FILENO, STDOUT_FILENO);
	closefrom(3);

	if ((pid = fork1()) < 0) {
		(void) printf("fork() failed: %s\n", strerror(errno));
		return (1);
	}

	if (pid != 0)
		exit(0);

	(void) setsid();
	(void) chdir("/");

	return (0);
}
예제 #10
0
static int
has_fs(char *prog, char *slice)
{
	pid_t	pid;
	int	loc;
	mode_t	mode = S_IRUSR | S_IWUSR;

	switch ((pid = fork1())) {
	case 0:
	    /* child process */

	    closefrom(1);
	    (void) open("/dev/null", O_WRONLY, mode);
	    (void) open("/dev/null", O_WRONLY, mode);
	    (void) execl(prog, "fstyp", slice, NULL);
	    _exit(1);
	    break;

	case -1:
	    return (0);

	default:
	    /* parent process */
	    break;
	}

	(void) waitpid(pid, &loc, 0);

	if (WIFEXITED(loc) && WEXITSTATUS(loc) == 0) {
	    return (1);
	}

	return (0);
}
예제 #11
0
파일: ntp_worker.c 프로젝트: ntpsec/ntpsec
/*
 * close_all_beyond()
 *
 * Close all file descriptors after the given keep_fd, which is the
 * highest fd to keep open.  See
 *
 * http://stackoverflow.com/questions/899038/getting-the-highest-allocated-file-descriptor
 */
void
close_all_beyond(
	int keep_fd
	)
{
# ifdef HAVE_CLOSEFROM
	closefrom(keep_fd + 1);
# elif defined(F_CLOSEM)
	/*
	 * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
	 * by Eric Agar (saves us from doing 32767 system
	 * calls)
	 */
	if (fcntl(keep_fd + 1, F_CLOSEM, 0) == -1)
		msyslog(LOG_ERR, "F_CLOSEM(%d): %m", keep_fd + 1);
# else	/* !HAVE_CLOSEFROM && !F_CLOSEM follows */
	int fd;
	int max_fd;

	/* includes POSIX case */
	max_fd = GETDTABLESIZE();
	for (fd = keep_fd + 1; fd < max_fd; fd++)
		close(fd);
# endif	/* !HAVE_CLOSEFROM && !F_CLOSEM */
}
예제 #12
0
파일: mproc.c 프로젝트: OpenSMTPD/OpenSMTPD
int
mproc_fork(struct mproc *p, const char *path, char *argv[])
{
	int sp[2];

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0)
		return (-1);

	io_set_nonblocking(sp[0]);
	io_set_nonblocking(sp[1]);

	if ((p->pid = fork()) == -1)
		goto err;

	if (p->pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		execv(path, argv);
		err(1, "execv: %s", path);
	}

	/* parent process */
	close(sp[0]);
	mproc_init(p, sp[1]);
	return (0);

err:
	log_warn("warn: Failed to start process %s, instance of %s", argv[0], path);
	close(sp[0]);
	close(sp[1]);
	return (-1);
}
예제 #13
0
// A wsh client will need lots of fds
gint wsh_client_init_fds(GError **err) {
	g_assert(err != NULL);
	g_assert(*err == NULL);

	WSH_CLIENT_ERROR = g_quark_from_static_string("wsh_client_error");

	struct rlimit rlp;

	if (getrlimit(RLIMIT_NOFILE, &rlp)) {
		*err = g_error_new(WSH_CLIENT_ERROR, WSH_CLIENT_RLIMIT_ERR,
		                   "getrlimit: %s", strerror(errno));
		return 1;
	}

	// Raise rlimits to max allowed for user
	rlp.rlim_cur = rlp.rlim_max - 1;
	if (setrlimit(RLIMIT_NOFILE, &rlp)) {
		*err = g_error_new(WSH_CLIENT_ERROR, WSH_CLIENT_RLIMIT_ERR,
		                   "setrlimit: %s", strerror(errno));
		return 2;
	}

	(void) closefrom(STDERR_FILENO + 1);

	return 0;
}
예제 #14
0
파일: h_reconcli.c 프로젝트: 2asoft/freebsd
static void *
closer(void *arg)
{

	pthread_mutex_lock(&closermtx);
	while (!quit) {
		while (!riseandwhine)
			pthread_cond_wait(&closercv, &closermtx);
		riseandwhine = 0;
		pthread_mutex_unlock(&closermtx);

		/* try to catch a random slot */
		usleep(random() % 100000);

		/*
		 * wide-angle disintegration beam, but takes care
		 * of the client rumpkernel communication socket.
		 */
		closefrom(3);

		pthread_mutex_lock(&closermtx);
	}
	pthread_mutex_unlock(&closermtx);

	return NULL;
}
예제 #15
0
파일: aw.c 프로젝트: pcd1193182/openzfs
static int
pipeline(char **ppargv, char **asargv)
{
	int pipedes[4];
	int active = 0;
	int rval = 0;
	pid_t pid_pp, pid_f, pid_as;

	if (pipe(pipedes) == -1 || pipe(pipedes + 2) == -1) {
		perror("pipe");
		return (4);
	}

	if ((pid_pp = invoke(ppargv, -1, pipedes[0])) > 0)
		active++;

	if (verbose)
		(void) fprintf(stderr, "| ");

	if ((pid_f = filter(pipedes[1], pipedes[2])) > 0)
		active++;

	if (verbose)
		(void) fprintf(stderr, "| ");

	if ((pid_as = invoke(asargv, pipedes[3], -1)) > 0)
		active++;

	if (verbose) {
		(void) fprintf(stderr, "\n");
		(void) fflush(stderr);
	}

	closefrom(3);

	if (active != 3)
		return (5);

	while (active != 0) {
		pid_t pid;
		int stat;

		if ((pid = wait(&stat)) == -1) {
			rval++;
			break;
		}

		if (!WIFEXITED(stat))
			continue;

		if (pid == pid_pp || pid == pid_f || pid == pid_as) {
			active--;
			if (WEXITSTATUS(stat) != 0)
				rval++;
		}
	}

	return (rval);
}
예제 #16
0
파일: capsicum.c 프로젝트: dpl0/soc2013
struct sandbox *
startChild(void *data)
{
	int procd, pid, sv[2];
	struct sandbox *newsandbox;

	if ((newsandbox = malloc(sizeof (struct sandbox))) == NULL)
		err(1, "Couldn't allocate memory for sandbox");

	sv[0] = sv[1] = 0;
	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) < 0 )
		err(1, "zcaplib: socketpair()");

	pid = pdfork(&procd, 0);
	if (pid == 0 ) {
		cap_rights_t stdin_cap;
		cap_rights_t stdout_cap;
		cap_rights_t stderr_cap;
		cap_rights_t socket_cap;

		cap_rights_init(&stdin_cap, CAP_READ);
		cap_rights_init(&stderr_cap, CAP_WRITE, CAP_FSTAT);
		cap_rights_init(&stdout_cap, CAP_WRITE);

		if (dup2(sv[0], 3) != 3)
			err(1, "Couldn't duplicate fd");
		closefrom(4);

		cap_rights_init(&socket_cap, CAP_WRITE, CAP_READ, CAP_POLL_EVENT);

		if (cap_rights_limit(STDIN_FILENO, &stdin_cap) < 0)
			err(1, "Couldn't limit stdin");
		if (cap_rights_limit(STDOUT_FILENO, &stdout_cap) < 0)
			err(1, "Couldn't limit stdout");
		if (cap_rights_limit(STDERR_FILENO, &stderr_cap) < 0)
			err(1, "Couldn't limit stderr");
		if (cap_rights_limit(3, &socket_cap) < 0)
			err(1, "Couldn't limit sandbox socket");

		/* execl() zlibworker */
		if ( execl("/usr/libexec/zlibworker", "zlibworker", NULL) < 0)
			err(1, "Couldn't find zlibworker.");

		exit(0);
	} else if (pid == -1) {
		err(1, "Couldn't fork");
	} else {
		signal(SIGCHLD, suicide);
		atexit(killChild);
		newsandbox->dataptr = data;
		newsandbox->pd = procd;
		newsandbox->socket = sv[1];
		debug("DEBUG: We have started a new sandbox.\n");
		debug("\tdata: %p pd: %d, socket: %d\n", data, newsandbox->pd, newsandbox->socket);
	}
	return (newsandbox);
}
예제 #17
0
static int
queue_proc_init(struct passwd *pw, int server)
{
	int		sp[2];
	uint32_t	version;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: queue-proc: socketpair");
		return (0);
	}

	if ((pid = fork()) == -1) {
		log_warn("warn: queue-proc: fork");
		goto err;
	}

	if (pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		execl(execpath, "queue_ramproc", NULL);
		err(1, "execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&ibuf, sp[1]);

	version = PROC_QUEUE_API_VERSION;
	imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1,
	    &version, sizeof(version));

	queue_api_on_message_create(queue_proc_message_create);
	queue_api_on_message_commit(queue_proc_message_commit);
	queue_api_on_message_delete(queue_proc_message_delete);
	queue_api_on_message_fd_r(queue_proc_message_fd_r);
	queue_api_on_message_corrupt(queue_proc_message_corrupt);
	queue_api_on_envelope_create(queue_proc_envelope_create);
	queue_api_on_envelope_delete(queue_proc_envelope_delete);
	queue_api_on_envelope_update(queue_proc_envelope_update);
	queue_api_on_envelope_load(queue_proc_envelope_load);
	queue_api_on_envelope_walk(queue_proc_envelope_walk);

	queue_proc_call();
	queue_proc_end();

	return (1);

err:
	close(sp[0]);
	close(sp[1]);
	return (0);
}
예제 #18
0
static int
xorg_backtrace_pstack(void)
{
    pid_t kidpid;
    int pipefd[2];

    if (pipe(pipefd) != 0) {
        return -1;
    }

    kidpid = fork1();

    if (kidpid == -1) {
        /* ERROR */
        return -1;
    }
    else if (kidpid == 0) {
        /* CHILD */
        char parent[16];

        seteuid(0);
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        dup2(pipefd[1], STDOUT_FILENO);
        closefrom(STDERR_FILENO);

        snprintf(parent, sizeof(parent), "%d", getppid());
        execle("/usr/bin/pstack", "pstack", parent, NULL);
        exit(1);
    }
    else {
        /* PARENT */
        char btline[256];
        int kidstat;
        int bytesread;
        int done = 0;

        close(pipefd[1]);

        while (!done) {
            bytesread = read(pipefd[0], btline, sizeof(btline) - 1);

            if (bytesread > 0) {
                btline[bytesread] = 0;
                ErrorFSigSafe("%s", btline);
            }
            else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN)))
                done = 1;
        }
        close(pipefd[0]);
        waitpid(kidpid, &kidstat, 0);
        if (kidstat != 0)
            return -1;
    }
    return 0;
}
예제 #19
0
파일: privsep.c 프로젝트: SylvestreG/bitrig
int
isc_priv_init(int lstderr)
{
	int i, socks[2], cmd;

	logmsg(LOG_NOTICE, "Starting privilege separation");

	log_stderr = lstderr;

	/* Create sockets */
	if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, socks) == -1)
		fatal("socketpair() failed");

	switch (child_pid = fork()) {
	case -1:
		fatal("failed to fork() for privsep");
	case 0:
		close(socks[0]);
		priv_fd = socks[1];
		return (0);
	default:
		break;
	}

	for (i = 1; i < _NSIG; i++)
		signal(i, SIG_DFL);

	signal(SIGALRM, sig_pass_to_chld);
	signal(SIGTERM, sig_pass_to_chld);
	signal(SIGHUP,  sig_pass_to_chld);
	signal(SIGINT,  sig_pass_to_chld);
	signal(SIGCHLD, sig_got_chld);

	/* Father - close unneeded sockets */
	for (i = STDERR_FILENO + 1; i < socks[0]; i++)
		close(i);
	closefrom(socks[0] + 1);

	setproctitle("[priv]");

	while (cur_state != STATE_QUIT) {
		if (may_read(socks[0], &cmd, sizeof(int)))
			break;
		switch (cmd) {
		case PRIV_BIND:
			parent_bind(socks[0]);
			break;
		default:
			logmsg(LOG_ERR, "[priv]: unknown command %d", cmd);
			_exit(1);
			/* NOTREACHED */
		}
	}

	_exit(0);
}
예제 #20
0
파일: utils.c 프로젝트: baitisj/pkg
pid_t
process_spawn_pipe(FILE *inout[2], const char *command)
{
	pid_t pid;
	int pipes[4];
	char *argv[4];

	/* Parent read/child write pipe */
	if (pipe(&pipes[0]) == -1)
		return (-1);

	/* Child read/parent write pipe */
	if (pipe(&pipes[2]) == -1) {
		close(pipes[0]);
		close(pipes[1]);
		return (-1);
	}

	argv[0] = __DECONST(char *, "sh");
	argv[1] = __DECONST(char *, "-c");
	argv[2] = __DECONST(char *, command);
	argv[3] = NULL;

	pid = fork();
	if (pid > 0) {
		/* Parent process */
		inout[0] = fdopen(pipes[0], "r");
		inout[1] = fdopen(pipes[3], "w");

		close(pipes[1]);
		close(pipes[2]);

		return (pid);

	} else if (pid == 0) {
		close(pipes[0]);
		close(pipes[3]);

		if (pipes[1] != STDOUT_FILENO) {
			dup2(pipes[1], STDOUT_FILENO);
			close(pipes[1]);
		}
		if (pipes[2] != STDIN_FILENO) {
			dup2(pipes[2], STDIN_FILENO);
			close(pipes[2]);
		}
		closefrom(STDERR_FILENO + 1);

		execve(_PATH_BSHELL, argv, environ);

		exit(127);
	}

	return (-1); /* ? */
}
예제 #21
0
파일: tst.fds.c 프로젝트: 0mp/freebsd
int
main(int argc, char *argv[])
{
	const char *file = "/dev/null";
	int i, n, fds[10];
	struct sigaction act;

	if (argc > 1) {
		(void) fprintf(stderr, "Usage: %s\n", argv[0]);
		return (EXIT_FAILURE);
	}

	act.sa_handler = interrupt;
	act.sa_flags = 0;

	(void) sigemptyset(&act.sa_mask);
	(void) sigaction(SIGUSR1, &act, NULL);

	closefrom(0);
	n = 0;

	/*
	 * With all of our file descriptors closed, wait here spinning in bogus
	 * ioctl() calls until DTrace hits us with a SIGUSR1 to start the test.
	 */
	if (sigsetjmp(env, 1) == 0) {
		for (;;)
			(void) ioctl(-1, 0, NULL);
	}

	/*
	 * To test the fds[] array, we open /dev/null (a file with reliable
	 * pathname and properties) using various flags and seek offsets.
	 */
	fds[n++] = open(file, O_RDONLY);
	fds[n++] = open(file, O_WRONLY);
	fds[n++] = open(file, O_RDWR);

	fds[n++] = open(file, O_RDWR | O_APPEND | O_CREAT |
	    O_NOCTTY | O_NONBLOCK | O_NDELAY | O_SYNC | O_TRUNC | 0666);

	fds[n++] = open(file, O_RDWR);
	(void) lseek(fds[n - 1], 123, SEEK_SET);

	/*
	 * Once we have all the file descriptors in the state we want to test,
	 * issue a bogus ioctl() on each fd with cmd 0 and arg NULL to whack
	 * our DTrace script into recording the content of the fds[] array.
	 */
	for (i = 0; i < n; i++)
		(void) ioctl(fds[i], 0, NULL);

	assert(n <= sizeof (fds) / sizeof (fds[0]));
	exit(0);
}
예제 #22
0
int
start_daemon(void)
{
	closefrom(0);
	(void) open("/dev/null", O_RDONLY);
	(void) open("/dev/null", O_WRONLY);
	(void) dup(1);
	(void) setsid();

	return (execl(_PATH_KCFD, _PATH_KCFD, (char *)0));
}
예제 #23
0
ATF_TC_BODY(closefrom_basic, tc)
{
	int fd, cur1, cur2;

	(void)closefrom(STDERR_FILENO + 1);

	fd = open(path, O_RDONLY | O_CREAT, 0400);
	ATF_REQUIRE(fd >= 0);

	cur1 = fcntl(0, F_MAXFD);

	ATF_REQUIRE(cur1 == STDERR_FILENO + 1);
	ATF_REQUIRE(closefrom(cur1) == 0);

	cur2 = fcntl(0, F_MAXFD);

	ATF_REQUIRE(cur1 - 1 == cur2);
	ATF_REQUIRE(close(fd) == -1);
	ATF_REQUIRE(unlink(path) == 0);
}
예제 #24
0
static void *
table_proc_open(struct table *table)
{
	int			 sp[2];
	struct table_proc_priv	*priv;
	char			*environ_new[2];
	struct table_open_params op;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: table-proc: socketpair");
		return (NULL);
	}
	priv = xcalloc(1, sizeof(*priv), "table_proc_open");

	if ((priv->pid = fork()) == -1) {
		log_warn("warn: table-proc: fork");
		goto err;
	}

	if (priv->pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		environ_new[0] = "PATH=" _PATH_DEFPATH;
		environ_new[1] = (char *)NULL;
		environ = environ_new;
		execle("/bin/sh", "/bin/sh", "-c", table->t_config, (char *)NULL,
		    environ_new);
		fatal("execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&priv->ibuf, sp[1]);

	memset(&op, 0, sizeof op);
	op.version = PROC_TABLE_API_VERSION;
	(void)strlcpy(op.name, table->t_name, sizeof op.name);
	imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op);

	table_proc_call(priv);
	table_proc_end();

	return (priv);
err:
	free(priv);
	close(sp[0]);
	close(sp[1]);
	return (NULL);
}
/*
 * Close all descriptors, startfd and higher except those listed
 * in pfds.
 */
void
closefrom_except(int startfd, struct preserved_fd_list *pfds)
{
    int debug_fd, fd, lastfd = -1;
    struct preserved_fd *pfd, *pfd_next;
    fd_set *fdsp;
    debug_decl(closefrom_except, SUDO_DEBUG_UTIL)

    debug_fd = sudo_debug_fd_get();

    /* First, relocate preserved fds to be as contiguous as possible.  */
    TAILQ_FOREACH_REVERSE_SAFE(pfd, pfds, preserved_fd_list, entries, pfd_next) {
        if (pfd->highfd < startfd)
            continue;
        fd = dup(pfd->highfd);
        if (fd == -1) {
            sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
                              "dup %d", pfd->highfd);
            if (errno == EBADF) {
                TAILQ_REMOVE(pfds, pfd, entries);
                continue;
            }
            /* NOTE: still need to adjust lastfd below with unchanged lowfd. */
        } else if (fd < pfd->highfd) {
            pfd->lowfd = fd;
            fd = pfd->highfd;
            if (fd == debug_fd)
                debug_fd = sudo_debug_fd_set(pfd->lowfd);
            sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
                              "dup %d -> %d", pfd->highfd, pfd->lowfd);
        }
        if (fd != -1)
            (void) close(fd);

        if (pfd->lowfd > lastfd)
            lastfd = pfd->lowfd;	/* highest (relocated) preserved fd */
    }

    if (lastfd == -1) {
        /* No fds to preserve. */
        sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
                          "closefrom(%d)", startfd);
        closefrom(startfd);
        debug_return;
    }

    /* Create bitmap of preserved (relocated) fds.  */
    fdsp = ecalloc(howmany(lastfd + 1, NFDBITS), sizeof(fd_mask));
    TAILQ_FOREACH(pfd, pfds, entries) {
        FD_SET(pfd->lowfd, fdsp);
    }
예제 #26
0
/*
 * Invoked in the child's child to initialize the slave side of the pty and set
 * of file descriptors for forking the child.
 */
static int
ps_init_slavepty(int mfd)
{
	char *slavename;
	int sfd, setup;

	if ((slavename = ptsname(mfd)) == NULL) {
		perror("child's child: ptsname");
		return (-1);
	}

	(void) close(mfd);

	if ((sfd = open(slavename, O_RDWR)) < 0) {
		perror("child's child: open pty");
		return (-1);
	}

	if ((setup = ioctl(sfd, I_FIND, "ldterm")) < 0) {
		perror("child's child: ioctl(I_FIND, \"ldterm\")");
		return (-1);
	}

	if (setup == 0) {
		if (ioctl(sfd, I_PUSH, "ptem") < 0) {
			perror("child's child: ioctl(I_PUSH, \"ptem\")");
			return (-1);
		}

		if (ioctl(sfd, I_PUSH, "ldterm") < 0) {
			perror("child's child: ioctl(I_PUSH, \"ldterm\")");
			return (-1);
		}

		if (ioctl(sfd, I_PUSH, "ttcompat") < 0) {
			perror("child's child: ioctl(I_PUSH, \"ttcompat\")");
			return (-1);
		}
	}

	if (dup2(sfd, STDIN_FILENO) != STDIN_FILENO ||
	    dup2(sfd, STDOUT_FILENO) != STDOUT_FILENO ||
	    dup2(sfd, STDERR_FILENO) != STDERR_FILENO) {
		perror("child's child: dup2");
		return (-1);
	}

	closefrom(STDERR_FILENO + 1);
	return (0);
}
예제 #27
0
static int
scheduler_proc_init(void)
{
	int		sp[2], r;
	uint32_t	version;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: scheduler-proc: socketpair");
		goto err;
	}

	if ((pid = fork()) == -1) {
		log_warn("warn: scheduler-proc: fork");
		goto err;
	}

	if (pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		execl(execpath, "scheduler-proc", NULL);
		err(1, "execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&ibuf, sp[1]);

	version = PROC_SCHEDULER_API_VERSION;
	imsg_compose(&ibuf, PROC_SCHEDULER_INIT, 0, 0, -1,
	    &version, sizeof(version));

	scheduler_proc_call();
	scheduler_proc_read(&r, sizeof(r));
	scheduler_proc_end();

	return (r);

err:
	close(sp[0]);
	close(sp[1]);
	fatalx("scheduler-proc: exiting");

	return (0);
}
예제 #28
0
void
VSUB_closefrom(int fd)
{

	assert(fd >= 0);

#ifdef HAVE_CLOSEFROM
	closefrom(fd);
#else
	int i = sysconf(_SC_OPEN_MAX);
	assert(i > 0);
	for (; i > fd; i--)
		(void)close(i);
#endif
}
예제 #29
0
파일: fd.c 프로젝트: MrJoe/gtk-gnutella
static inline bool
try_close_from(const int first_fd)
{
#if defined(F_CLOSEM)
	return -1 != fcntl(first_fd, F_CLOSEM);
#elif defined(HAS_CLOSEFROM)
	/* Returns nothing on Solaris; NetBSD has F_CLOSEM and closefrom()
	 * equivalent to the above. Thus prefer F_CLOSEM due to potential
	 * error. */
	closefrom(first_fd);
	return TRUE;
#else
	(void) first_fd;
	return FALSE;
#endif	/* HAS_CLOSEFROM */
}
예제 #30
0
/*
 * call-seq:
 *    IO.closefrom(lowfd)
 *
 * Close all open file descriptors (associated with the current process) that
 * are greater than or equal to +lowfd+.
 *
 * This method uses your system's builtin closefrom() function, if supported.
 * Otherwise, it uses a manual, and (probably) less efficient approach.
 *
 *--
 * The manual approach was copied from the closefrom() man page on Solaris 9.
 */
static VALUE io_closefrom(VALUE klass, VALUE v_low_fd){
#if defined(HAVE_CLOSEFROM) && !defined(HAVE_RB_RESERVED_FD_P)
   /* we can't safely use closefrom() if the RubyVM reserves FDs */
   closefrom(NUM2INT(v_low_fd));
#else
   int i, lowfd;
   int maxfd = open_max();
   lowfd = NUM2INT(v_low_fd);

   for(i = lowfd; i < maxfd; i++) {
      if(!RB_RESERVED_FD_P(i))
         close(i);
   }
#endif
   return klass;
}