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)); }
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); } }
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; }
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)); }
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)); }