Ejemplo n.º 1
0
void
redirect(union node *redir, int flags)
{
	union node *n;
	struct redirtab *sv = NULL;
	int i;
	int fd;
	char memory[10];	/* file descriptors to write to memory */

	INTOFF;
	for (i = 10 ; --i >= 0 ; )
		memory[i] = 0;
	memory[1] = flags & REDIR_BACKQ;
	if (flags & REDIR_PUSH) {
		empty_redirs++;
		if (redir != NULL) {
			sv = ckmalloc(sizeof (struct redirtab));
			for (i = 0 ; i < 10 ; i++)
				sv->renamed[i] = EMPTY;
			sv->fd0_redirected = fd0_redirected;
			sv->empty_redirs = empty_redirs - 1;
			sv->next = redirlist;
			redirlist = sv;
			empty_redirs = 0;
		}
	}
	for (n = redir ; n ; n = n->nfile.next) {
		fd = n->nfile.fd;
		if (fd == 0)
			fd0_redirected = 1;
		if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
		    n->ndup.dupfd == fd)
			continue; /* redirect from/to same file descriptor */

		if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
			INTOFF;
			if ((i = fcntl(fd, F_DUPFD_CLOEXEC, 10)) == -1) {
				switch (errno) {
				case EBADF:
					i = CLOSED;
					break;
				default:
					INTON;
					error("%d: %s", fd, strerror(errno));
					break;
				}
			}
			sv->renamed[fd] = i;
			INTON;
		}
		openredirect(n, memory);
		INTON;
		INTOFF;
	}
	if (memory[1])
		out1 = &memout;
	if (memory[2])
		out2 = &memout;
	INTON;
}
Ejemplo n.º 2
0
void
redirect(union node *redir, int flags)
{
	union node *n;
	struct redirtab *sv = NULL;
	int i;
	int fd;
	char memory[10];	/* file descriptors to write to memory */

	for (i = 10 ; --i >= 0 ; )
		memory[i] = 0;
	memory[1] = flags & REDIR_BACKQ;
	if (flags & REDIR_PUSH) {
		/* We don't have to worry about REDIR_VFORK here, as
		 * flags & REDIR_PUSH is never true if REDIR_VFORK is set.
		 */
		sv = ckmalloc(sizeof (struct redirtab));
		for (i = 0 ; i < 10 ; i++)
			sv->renamed[i] = EMPTY;
		sv->next = redirlist;
		redirlist = sv;
	}
	for (n = redir ; n ; n = n->nfile.next) {
		fd = n->nfile.fd;
		if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
		    n->ndup.dupfd == fd)
			continue; /* redirect from/to same file descriptor */

		if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
			INTOFF;
			if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
				switch (errno) {
				case EBADF:
					i = CLOSED;
					break;
				default:
					INTON;
					error("%d: %s", fd, strerror(errno));
					/* NOTREACHED */
				}
			} else
				(void)fcntl(i, F_SETFD, FD_CLOEXEC);
			sv->renamed[fd] = i;
			INTON;
		} else {
			close(fd);
		}
                if (fd == 0)
                        fd0_redirected++;
		openredirect(n, memory, flags);
	}
	if (memory[1])
		out1 = &memout;
	if (memory[2])
		out2 = &memout;
}
Ejemplo n.º 3
0
void
redirect(union node *redir, int flags)
{
	union node *n;
	struct redirtab *sv = NULL;
	int i;
	int fd;
	char memory[10];	/* file descriptors to write to memory */

	for (i = 10 ; --i >= 0 ; )
		memory[i] = 0;
	memory[1] = flags & REDIR_BACKQ;
	if (flags & REDIR_PUSH) {
		/* We don't have to worry about REDIR_VFORK here, as
		 * flags & REDIR_PUSH is never true if REDIR_VFORK is set.
		 */
		sv = ckmalloc(sizeof (struct redirtab));
		sv->renamed = NULL;
		sv->next = redirlist;
		redirlist = sv;
	}
	for (n = redir ; n ; n = n->nfile.next) {
		fd = n->nfile.fd;
		if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
		    n->ndup.dupfd == fd) {
			/* redirect from/to same file descriptor */
			/* make sure it stays open */
			if (fcntl(fd, F_SETFD, 0) < 0)
				error("fd %d: %s", fd, strerror(errno));
			continue;
		}

		if ((flags & REDIR_PUSH) && !is_renamed(sv->renamed, fd)) {
			INTOFF;
			if (big_sh_fd < 10)
				find_big_fd();
			if ((i = fcntl(fd, F_DUPFD, big_sh_fd)) == -1) {
				switch (errno) {
				case EBADF:
					i = CLOSED;
					break;
				case EMFILE:
				case EINVAL:
					find_big_fd();
					i = fcntl(fd, F_DUPFD, big_sh_fd);
					if (i >= 0)
						break;
					/* FALLTHRU */
				default:
					i = errno;
					INTON;    /* XXX not needed here ? */
					error("%d: %s", fd, strerror(i));
					/* NOTREACHED */
				}
			}
			if (i >= 0)
				(void)fcntl(i, F_SETFD, FD_CLOEXEC);
			fd_rename(sv, fd, i);
			INTON;
		}
		if (fd == 0)
			fd0_redirected++;
		openredirect(n, memory, flags);
	}
	if (memory[1])
		out1 = &memout;
	if (memory[2])
		out2 = &memout;
}
Ejemplo n.º 4
0
void
redirect(union node *redir, int flags)
{
	union node *n;
	struct redirtab *sv;
	int i;
	int fd;
	int newfd;
	int *p;
#if notyet
	char memory[10];	/* file descriptors to write to memory */

	for (i = 10 ; --i >= 0 ; )
		memory[i] = 0;
	memory[1] = flags & REDIR_BACKQ;
#endif
	nullredirs++;
	if (!redir) {
		return;
	}
	sv = NULL;
	INTOFF;
	if (flags & REDIR_PUSH) {
		struct redirtab *q;
		q = ckmalloc(sizeof (struct redirtab));
		q->next = redirlist;
		redirlist = q;
		q->nullredirs = nullredirs - 1;
		for (i = 0 ; i < 10 ; i++)
			q->renamed[i] = EMPTY;
		nullredirs = 0;
		sv = q;
	}
	n = redir;
	do {
		fd = n->nfile.fd;
		if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
		    n->ndup.dupfd == fd)
			continue; /* redirect from/to same file descriptor */

		newfd = openredirect(n);
		if (fd == newfd)
			continue;
		if (sv && *(p = &sv->renamed[fd]) == EMPTY) {
			int i = fcntl(fd, F_DUPFD, 10);
			if (i == -1) {
				i = errno;
				if (i != EBADF) {
					const char *m = strerror(i);
					close(newfd);
					sh_error("%d: %s", fd, m);
					/* NOTREACHED */
				}
			} else {
				*p = i;
				close(fd);
			}
		} else {
			close(fd);
		}
#ifdef notyet
		dupredirect(n, newfd, memory);
#else
		dupredirect(n, newfd);
#endif
	} while ((n = n->nfile.next));
	INTON;
#ifdef notyet
	if (memory[1])
		out1 = &memout;
	if (memory[2])
		out2 = &memout;
#endif
	if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0)
		preverrout.fd = sv->renamed[2];
}