Beispiel #1
0
// Return the 'struct Fd' for a file descriptor number.
// Returns NULL on failure, a pointer on success.
// If 'must_exist' is true, then the file descriptor must currently be open
// or NULL is returned.
// Returns 0 on success, < 0 error code on failure.
//
int
fd_lookup(int fdnum, struct Fd **fd_store, bool must_exist)
{
	struct Fd *fd = (struct Fd *) (FDTABLE + fdnum * PGSIZE);

	if (fdnum < 0 || fdnum >= NFD || (must_exist && !fd_isopen(fd))) {
		*fd_store = 0;
		return -E_INVAL;
	} else {
		*fd_store = fd;
		return 0;
	}
}
Beispiel #2
0
// Finds the smallest index from 0 to NFD-1 that doesn't have
// its fd page mapped.
// Sets *fd_store to the corresponding fd page virtual address.
//
// Does NOT actually allocate an fd page.
// It is up to the caller to allocate the page somehow.
// This means that if someone calls fd_find_unused twice in a row
// without allocating the first page we return, we'll return the same
// page the second time.
//
// Returns 0 on success, < 0 on error.  Errors are:
//	-E_MAX_FD: no more file descriptors
// On error, *fd_store is set to 0.
int
fd_find_unused(struct Fd **fd_store)
{
	int i;
	struct Fd *fd;

	for (i = 0; i < NFD; i++) {
		(void) fd_lookup(i, &fd, false);
		if (!fd_isopen(fd)) {
			*fd_store = fd;
			return 0;
		}
	}
	*fd_store = 0;
	return -E_MAX_OPEN;
}
Beispiel #3
0
/*
 * NAME
 *	fd2 - redirect from/to file descriptor 2
 *
 * SYNOPSIS
 *	fd2 [-e] [-f file] [--] command [arg ...]
 *
 * DESCRIPTION
 *	See the fd2(1) manual page for full details.
 */
int
main(int argc, char **argv)
{
	bool eopt;
	int efd, fd, nfd, ofd, opt;
	char *file;

	setmyerrexit(&ut_errexit);
	setmyname(argv[0]);
	setmypid(getpid());

	/*
	 * Set-ID execution is not supported.
	 */
	if (geteuid() != getuid() || getegid() != getgid())
		err(FC_ERR, FMT2S, getmyname(), ERR_SETID);

	/*
	 * File descriptors 0, 1, and 2 must be open.
	 */
	for (fd = 0; fd < 3; fd++)
		if (!fd_isopen(fd))
			err(FC_ERR, "%s: %u: %s\n",
			    getmyname(), (unsigned)fd, strerror(errno));

	ofd = FD1, efd = FD2;
	eopt = false, file = NULL;
	while ((opt = getopt(argc, argv, ":ef:")) != -1)
		switch (opt) {
		case 'e':
			eopt = true;
			break;
		case 'f':
			file = optarg;
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;
	if (argc < 1)
		usage();

	if (file != NULL) {
		if ((nfd = open(file, O_WRONLY|O_APPEND|O_CREAT, 0666)) == -1)
			err(FC_ERR, FMT3S, getmyname(), file, ERR_CREATE);
		if (dup2(nfd, efd) == -1)
			err(FC_ERR, FMT2S, getmyname(), strerror(errno));
		if (eopt && dup2(efd, ofd) == -1)
			err(FC_ERR, FMT2S, getmyname(), strerror(errno));
		(void)close(nfd);
	} else {
		if (eopt)
			ofd = FD2, efd = FD1;
		if (dup2(ofd, efd) == -1)
			err(FC_ERR, FMT2S, getmyname(), strerror(errno));
	}

	/*
	 * Try to execute the specified command.
	 */
	(void)err_pexec(argv[0], argv);
	/*NOTREACHED*/
	return FC_ERR;
}