Esempio n. 1
0
STATIC int
openredirect(union node *redir)
{
	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|O_TRUNC, 0666)) < 0)
			goto ecreate;
		break;
	case NTO:
		/* Take care of noclobber mode. */
		if (Cflag) {
			fname = redir->nfile.expfname;
			if ((f = noclobberopen(fname)) < 0)
				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;
	default:
#ifdef DEBUG
		abort();
#endif
		/* Fall through to eliminate warning. */
	case NTOFD:
	case NFROMFD:
		f = -1;
		break;
	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));
}
Esempio n. 2
0
static void
openredirect(union node *redir, char memory[10])
{
	struct stat sb;
	int fd = redir->nfile.fd;
	const char *fname;
	int f;
	int e;

	memory[fd] = 0;
	switch (redir->nfile.type) {
	case NFROM:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_RDONLY)) < 0)
			error("cannot open %s: %s", fname, strerror(errno));
		break;
	case NFROMTO:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_RDWR|O_CREAT, 0666)) < 0)
			error("cannot create %s: %s", fname, strerror(errno));
		break;
	case NTO:
		if (Cflag) {
			fname = redir->nfile.expfname;
			if (stat(fname, &sb) == -1) {
				if ((f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
					error("cannot create %s: %s", fname, strerror(errno));
			} else if (!S_ISREG(sb.st_mode)) {
				if ((f = open(fname, O_WRONLY, 0666)) < 0)
					error("cannot create %s: %s", fname, strerror(errno));
				if (fstat(f, &sb) != -1 && S_ISREG(sb.st_mode)) {
					close(f);
					error("cannot create %s: %s", fname,
					    strerror(EEXIST));
				}
			} else
				error("cannot create %s: %s", fname,
				    strerror(EEXIST));
			break;
		}
		/* FALLTHROUGH */
	case NCLOBBER:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
			error("cannot create %s: %s", fname, strerror(errno));
		break;
	case NAPPEND:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
			error("cannot create %s: %s", fname, strerror(errno));
		break;
	case NTOFD:
	case NFROMFD:
		if (redir->ndup.dupfd >= 0) {	/* if not ">&-" */
			if (memory[redir->ndup.dupfd])
				memory[fd] = 1;
			else {
				if (dup2(redir->ndup.dupfd, fd) < 0)
					error("%d: %s", redir->ndup.dupfd,
							strerror(errno));
			}
		} else {
			close(fd);
		}
		return;
	case NHERE:
	case NXHERE:
		f = openhere(redir);
		break;
	default:
		abort();
	}
	if (f != fd) {
		if (dup2(f, fd) == -1) {
			e = errno;
			close(f);
			error("%d: %s", fd, strerror(e));
		}
		close(f);
	}
}
Esempio n. 3
0
static void
openredirect(union node *redir, char memory[10])
{
	struct stat sb;
	int fd = redir->nfile.fd;
	char *fname;
	int f;
	int e;

	/*
	 * We suppress interrupts so that we won't leave open file
	 * descriptors around.  Because the signal handler remains
	 * installed and we do not use system call restart, interrupts
	 * will still abort blocking opens such as fifos (they will fail
	 * with EINTR). There is, however, a race condition if an interrupt
	 * arrives after INTOFF and before open blocks.
	 */
	INTOFF;
	memory[fd] = 0;
	switch (redir->nfile.type) {
	case NFROM:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_RDONLY)) < 0)
			error("cannot open %s: %s", fname, strerror(errno));
movefd:
		if (f != fd) {
			if (dup2(f, fd) == -1) {
				e = errno;
				close(f);
				error("%d: %s", fd, strerror(e));
			}
			close(f);
		}
		break;
	case NFROMTO:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_RDWR|O_CREAT, 0666)) < 0)
			error("cannot create %s: %s", fname, strerror(errno));
		goto movefd;
	case NTO:
		if (Cflag) {
			fname = redir->nfile.expfname;
			if (stat(fname, &sb) == -1) {
				if ((f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
					error("cannot create %s: %s", fname, strerror(errno));
			} else if (!S_ISREG(sb.st_mode)) {
				if ((f = open(fname, O_WRONLY, 0666)) < 0)
					error("cannot create %s: %s", fname, strerror(errno));
				if (fstat(f, &sb) != -1 && S_ISREG(sb.st_mode)) {
					close(f);
					error("cannot create %s: %s", fname,
					    strerror(EEXIST));
				}
			} else
				error("cannot create %s: %s", fname,
				    strerror(EEXIST));
			goto movefd;
		}
		/* FALLTHROUGH */
	case NCLOBBER:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
			error("cannot create %s: %s", fname, strerror(errno));
		goto movefd;
	case NAPPEND:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
			error("cannot create %s: %s", fname, strerror(errno));
		goto movefd;
	case NTOFD:
	case NFROMFD:
		if (redir->ndup.dupfd >= 0) {	/* if not ">&-" */
			if (memory[redir->ndup.dupfd])
				memory[fd] = 1;
			else {
				if (dup2(redir->ndup.dupfd, fd) < 0)
					error("%d: %s", redir->ndup.dupfd,
							strerror(errno));
			}
		} else {
			close(fd);
		}
		break;
	case NHERE:
	case NXHERE:
		f = openhere(redir);
		goto movefd;
	default:
		abort();
	}
	INTON;
}
Esempio n. 4
0
STATIC void
openredirect(union node *redir, char memory[10], int flags)
{
	struct stat sb;
	int fd = redir->nfile.fd;
	char *fname;
	int f;
	int eflags, cloexec;

	/*
	 * We suppress interrupts so that we won't leave open file
	 * descriptors around.  This may not be such a good idea because
	 * an open of a device or a fifo can block indefinitely.
	 */
	INTOFF;
	if (fd < 10)
		memory[fd] = 0;
	switch (redir->nfile.type) {
	case NFROM:
		fname = redir->nfile.expfname;
		if (flags & REDIR_VFORK)
			eflags = O_NONBLOCK;
		else
			eflags = 0;
		if ((f = open(fname, O_RDONLY|eflags)) < 0)
			goto eopen;
		if (eflags)
			(void)fcntl(f, F_SETFL, fcntl(f, F_GETFL, 0) & ~eflags);
		break;
	case NFROMTO:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
			goto ecreate;
		break;
	case NTO:
		if (Cflag) {
			fname = redir->nfile.expfname;
			if ((f = open(fname, O_WRONLY)) == -1) {
				if ((f = open(fname, O_WRONLY|O_CREAT|O_EXCL,
				    0666)) < 0)
					goto ecreate;
			} else if (fstat(f, &sb) == -1) {
				int serrno = errno;
				close(f);
				errno = serrno;
				goto ecreate;
			} else if (S_ISREG(sb.st_mode)) {
				close(f);
				errno = EEXIST;
				goto ecreate;
			}
			break;
		}
		/* FALLTHROUGH */
	case NCLOBBER:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
			goto ecreate;
		break;
	case NAPPEND:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
			goto ecreate;
		break;
	case NTOFD:
	case NFROMFD:
		if (redir->ndup.dupfd >= 0) {	/* if not ">&-" */
			if (fd < 10 && redir->ndup.dupfd < 10 &&
			    memory[redir->ndup.dupfd])
				memory[fd] = 1;
			else if (copyfd(redir->ndup.dupfd, fd,
			    (flags & REDIR_KEEP) == 0) < 0)
				error("Redirect (from %d to %d) failed: %s",
				    redir->ndup.dupfd, fd, strerror(errno));
		} else
			(void) close(fd);
		INTON;
		return;
	case NHERE:
	case NXHERE:
		f = openhere(redir);
		break;
	default:
		abort();
	}

	cloexec = fd > 2 && (flags & REDIR_KEEP) == 0;
	if (f != fd) {
		if (copyfd(f, fd, cloexec) < 0) {
			int e = errno;

			close(f);
			error("redirect reassignment (fd %d) failed: %s", fd,
			    strerror(e));
		}
		close(f);
	} else if (cloexec)
		(void)fcntl(f, F_SETFD, FD_CLOEXEC);

	INTON;
	return;
ecreate:
	exerrno = 1;
	error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
eopen:
	exerrno = 1;
	error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
}
Esempio n. 5
0
STATIC void
openredirect(union node *redir, char memory[10], int flags)
{
	int fd = redir->nfile.fd;
	char *fname;
	int f;
	int oflags = O_WRONLY|O_CREAT|O_TRUNC, eflags;

	/*
	 * We suppress interrupts so that we won't leave open file
	 * descriptors around.  This may not be such a good idea because
	 * an open of a device or a fifo can block indefinitely.
	 */
	INTOFF;
	memory[fd] = 0;
	switch (redir->nfile.type) {
	case NFROM:
		fname = redir->nfile.expfname;
		if (flags & REDIR_VFORK)
			eflags = O_NONBLOCK;
		else
			eflags = 0;
		if ((f = open(fname, O_RDONLY|eflags)) < 0)
			goto eopen;
		if (eflags)
			(void)fcntl(f, F_SETFL, fcntl(f, F_GETFL, 0) & ~eflags);
		break;
	case NFROMTO:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
			goto ecreate;
		break;
	case NTO:
		if (Cflag)
			oflags |= O_EXCL;
		/* FALLTHROUGH */
	case NCLOBBER:
		fname = redir->nfile.expfname;
		if ((f = open(fname, oflags, 0666)) < 0)
			goto ecreate;
		break;
	case NAPPEND:
		fname = redir->nfile.expfname;
		if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
			goto ecreate;
		break;
	case NTOFD:
	case NFROMFD:
		if (redir->ndup.dupfd >= 0) {	/* if not ">&-" */
			if (memory[redir->ndup.dupfd])
				memory[fd] = 1;
			else
				copyfd(redir->ndup.dupfd, fd, 1);
		}
		INTON;
		return;
	case NHERE:
	case NXHERE:
		f = openhere(redir);
		break;
	default:
		abort();
	}

	if (f != fd) {
		copyfd(f, fd, 1);
		close(f);
	}
	INTON;
	return;
ecreate:
	exerrno = 1;
	error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
eopen:
	exerrno = 1;
	error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
}