summary refs log tree commit diff
path: root/bin/dash/src/redir.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/dash/src/redir.c')
-rw-r--r--bin/dash/src/redir.c483
1 files changed, 0 insertions, 483 deletions
diff --git a/bin/dash/src/redir.c b/bin/dash/src/redir.c
deleted file mode 100644
index 895140c3..00000000
--- a/bin/dash/src/redir.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- *	The Regents of the University of California.  All rights reserved.
- * Copyright (c) 1997-2005
- *	Herbert Xu <herbert@gondor.apana.org.au>.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Kenneth Almquist.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/param.h>	/* PIPE_BUF */
-#include <signal.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-/*
- * Code for dealing with input/output redirection.
- */
-
-#include "main.h"
-#include "shell.h"
-#include "nodes.h"
-#include "jobs.h"
-#include "options.h"
-#include "expand.h"
-#include "redir.h"
-#include "output.h"
-#include "memalloc.h"
-#include "error.h"
-
-
-#define EMPTY -2		/* marks an unused slot in redirtab */
-#define CLOSED -1		/* fd opened for redir needs to be closed */
-
-#ifndef PIPE_BUF
-# define PIPESIZE 4096		/* amount of buffering in a pipe */
-#else
-# define PIPESIZE PIPE_BUF
-#endif
-
-
-MKINIT
-struct redirtab {
-	struct redirtab *next;
-	int renamed[10];
-};
-
-
-MKINIT struct redirtab *redirlist;
-
-/* Bit map of currently closed file descriptors. */
-static unsigned closed_redirs;
-
-STATIC int openredirect(union node *);
-#ifdef notyet
-STATIC void dupredirect(union node *, int, char[10]);
-#else
-STATIC void dupredirect(union node *, int);
-#endif
-STATIC int openhere(union node *);
-
-
-static unsigned update_closed_redirs(int fd, int nfd)
-{
-	unsigned val = closed_redirs;
-	unsigned bit = 1 << fd;
-
-	if (nfd >= 0)
-		closed_redirs &= ~bit;
-	else
-		closed_redirs |= bit;
-
-	return val & bit;
-}
-
-
-/*
- * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
- * old file descriptors are stashed away so that the redirection can be
- * undone by calling popredir.  If the REDIR_BACKQ flag is set, then the
- * standard output, and the standard error if it becomes a duplicate of
- * stdout, is saved in memory.
- */
-
-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
-	if (!redir)
-		return;
-	sv = NULL;
-	INTOFF;
-	if (likely(flags & REDIR_PUSH))
-		sv = redirlist;
-	n = redir;
-	do {
-		newfd = openredirect(n);
-		if (newfd < -1)
-			continue;
-
-		fd = n->nfile.fd;
-
-		if (sv) {
-			int closed;
-
-			p = &sv->renamed[fd];
-			i = *p;
-
-			closed = update_closed_redirs(fd, newfd);
-
-			if (likely(i == EMPTY)) {
-				i = CLOSED;
-				if (fd != newfd && !closed) {
-					i = savefd(fd, fd);
-					fd = -1;
-				}
-			}
-
-			*p = i;
-		}
-
-		if (fd == newfd)
-			continue;
-
-#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->renamed[2] >= 0)
-		preverrout.fd = sv->renamed[2];
-}
-
-
-STATIC int
-openredirect(union node *redir)
-{
-	struct stat64 sb;
-	char *fname;
-	int f;
-
-	switch (redir->nfile.type) {
-	case NFROM:
-		fname = redir->nfile.expfname;
-		if ((f = open64(fname, O_RDONLY)) < 0)
-			goto eopen;
-		break;
-	case NFROMTO:
-		fname = redir->nfile.expfname;
-		if ((f = open64(fname, O_RDWR|O_CREAT, 0666)) < 0)
-			goto ecreate;
-		break;
-	case NTO:
-		/* Take care of noclobber mode. */
-		if (Cflag) {
-			fname = redir->nfile.expfname;
-			if (stat64(fname, &sb) < 0) {
-				if ((f = open64(fname, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
-					goto ecreate;
-			} else if (!S_ISREG(sb.st_mode)) {
-				if ((f = open64(fname, O_WRONLY, 0666)) < 0)
-					goto ecreate;
-				if (!fstat64(f, &sb) && S_ISREG(sb.st_mode)) {
-					close(f);
-					errno = EEXIST;
-					goto ecreate;
-				}
-			} else {
-				errno = EEXIST;
-				goto ecreate;
-			}
-			break;
-		}
-		/* FALLTHROUGH */
-	case NCLOBBER:
-		fname = redir->nfile.expfname;
-		if ((f = open64(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
-			goto ecreate;
-		break;
-	case NAPPEND:
-		fname = redir->nfile.expfname;
-		if ((f = open64(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
-			goto ecreate;
-		break;
-	case NTOFD:
-	case NFROMFD:
-		f = redir->ndup.dupfd;
-		if (f == redir->nfile.fd)
-			f = -2;
-		break;
-	default:
-#ifdef DEBUG
-		abort();
-#endif
-		/* Fall through to eliminate warning. */
-	case NHERE:
-	case NXHERE:
-		f = openhere(redir);
-		break;
-	}
-
-	return f;
-ecreate:
-	sh_error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
-eopen:
-	sh_error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
-}
-
-
-STATIC void
-#ifdef notyet
-dupredirect(redir, f, memory)
-#else
-dupredirect(redir, f)
-#endif
-	union node *redir;
-	int f;
-#ifdef notyet
-	char memory[10];
-#endif
-	{
-	int fd = redir->nfile.fd;
-	int err = 0;
-
-#ifdef notyet
-	memory[fd] = 0;
-#endif
-	if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
-		/* if not ">&-" */
-		if (f >= 0) {
-#ifdef notyet
-			if (memory[f])
-				memory[fd] = 1;
-			else
-#endif
-				if (dup2(f, fd) < 0) {
-					err = errno;
-					goto err;
-				}
-			return;
-		}
-		f = fd;
-	} else if (dup2(f, fd) < 0)
-		err = errno;
-
-	close(f);
-	if (err < 0)
-		goto err;
-
-	return;
-
-err:
-	sh_error("%d: %s", f, strerror(err));
-}
-
-
-/*
- * Handle here documents.  Normally we fork off a process to write the
- * data to a pipe.  If the document is short, we can stuff the data in
- * the pipe without forking.
- */
-
-STATIC int
-openhere(union node *redir)
-{
-	char *p;
-	int pip[2];
-	size_t len = 0;
-
-	if (pipe(pip) < 0)
-		sh_error("Pipe call failed");
-
-	p = redir->nhere.doc->narg.text;
-	if (redir->type == NXHERE) {
-		expandarg(redir->nhere.doc, NULL, EXP_QUOTED);
-		p = stackblock();
-	}
-
-	len = strlen(p);
-	if (len <= PIPESIZE) {
-		xwrite(pip[1], p, len);
-		goto out;
-	}
-
-	if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
-		close(pip[0]);
-		signal(SIGINT, SIG_IGN);
-		signal(SIGQUIT, SIG_IGN);
-		signal(SIGHUP, SIG_IGN);
-#ifdef SIGTSTP
-		signal(SIGTSTP, SIG_IGN);
-#endif
-		signal(SIGPIPE, SIG_DFL);
-		xwrite(pip[1], p, len);
-		_exit(0);
-	}
-out:
-	close(pip[1]);
-	return pip[0];
-}
-
-
-
-/*
- * Undo the effects of the last redirection.
- */
-
-void
-popredir(int drop)
-{
-	struct redirtab *rp;
-	int i;
-
-	INTOFF;
-	rp = redirlist;
-	for (i = 0 ; i < 10 ; i++) {
-		int closed;
-
-		if (rp->renamed[i] == EMPTY)
-			continue;
-
-		closed = drop ? 1 : update_closed_redirs(i, rp->renamed[i]);
-
-		switch (rp->renamed[i]) {
-		case CLOSED:
-			if (!closed)
-				close(i);
-			break;
-		default:
-			if (!drop)
-				dup2(rp->renamed[i], i);
-			close(rp->renamed[i]);
-			break;
-		}
-	}
-	redirlist = rp->next;
-	ckfree(rp);
-	INTON;
-}
-
-/*
- * Undo all redirections.  Called on error or interrupt.
- */
-
-#ifdef mkinit
-
-INCLUDE "redir.h"
-
-EXITRESET {
-	/*
-	 * Discard all saved file descriptors.
-	 */
-	unwindredir(0);
-}
-
-FORKRESET {
-	redirlist = NULL;
-}
-
-#endif
-
-
-
-/*
- * Move a file descriptor to > 10.  Invokes sh_error on error unless
- * the original file dscriptor is not open.
- */
-
-int
-savefd(int from, int ofd)
-{
-	int newfd;
-	int err;
-
-	newfd = fcntl(from, F_DUPFD, 10);
-	err = newfd < 0 ? errno : 0;
-	if (err != EBADF) {
-		close(ofd);
-		if (err)
-			sh_error("%d: %s", from, strerror(err));
-		else
-			fcntl(newfd, F_SETFD, FD_CLOEXEC);
-	}
-
-	return newfd;
-}
-
-
-int
-redirectsafe(union node *redir, int flags)
-{
-	int err;
-	volatile int saveint;
-	struct jmploc *volatile savehandler = handler;
-	struct jmploc jmploc;
-
-	SAVEINT(saveint);
-	if (!(err = setjmp(jmploc.loc) * 2)) {
-		handler = &jmploc;
-		redirect(redir, flags);
-	}
-	handler = savehandler;
-	if (err && exception != EXERROR)
-		longjmp(handler->loc, 1);
-	RESTOREINT(saveint);
-	return err;
-}
-
-
-void unwindredir(struct redirtab *stop)
-{
-	while (redirlist != stop)
-		popredir(0);
-}
-
-
-struct redirtab *pushredir(union node *redir)
-{
-	struct redirtab *sv;
-	struct redirtab *q;
-	int i;
-
-	q = redirlist;
-	if (!redir)
-		goto out;
-
-	sv = ckmalloc(sizeof (struct redirtab));
-	sv->next = q;
-	redirlist = sv;
-	for (i = 0; i < 10; i++)
-		sv->renamed[i] = EMPTY;
-
-out:
-	return q;
-}