diff options
Diffstat (limited to 'source/ap/ash/patches/ash-redir.patch')
-rw-r--r-- | source/ap/ash/patches/ash-redir.patch | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/source/ap/ash/patches/ash-redir.patch b/source/ap/ash/patches/ash-redir.patch new file mode 100644 index 00000000..40cdbe9a --- /dev/null +++ b/source/ap/ash/patches/ash-redir.patch @@ -0,0 +1,463 @@ +diff -ur netbsd-sh/eval.c netbsd-sh-/eval.c +--- netbsd-sh/eval.c Tue May 23 12:03:18 2000 ++++ netbsd-sh-/eval.c Mon Apr 23 23:33:34 2001 +@@ -442,6 +442,7 @@ + case NFROM: + case NTO: + case NAPPEND: ++ case NTOOV: + expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); + redir->nfile.expfname = fn.list->text; + break; +diff -ur netbsd-sh/exec.c netbsd-sh-/exec.c +--- netbsd-sh/exec.c Fri Jan 12 17:50:35 2001 ++++ netbsd-sh-/exec.c Mon Apr 23 23:33:34 2001 +@@ -125,6 +125,10 @@ + char *cmdname; + int e; + ++ if (fd2 >= 0 && fd2 != 2) { ++ close(fd2); ++ } ++ + if (strchr(argv[0], '/') != NULL) { + tryexec(argv[0], argv, envp); + e = errno; +diff -ur netbsd-sh/jobs.c netbsd-sh-/jobs.c +--- netbsd-sh/jobs.c Mon Apr 23 23:34:53 2001 ++++ netbsd-sh-/jobs.c Mon Apr 23 23:34:30 2001 +@@ -129,9 +129,9 @@ + if (on) { + do { /* while we are in the background */ + #ifdef OLD_TTY_DRIVER +- if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) { ++ if (ioctl(fd2, TIOCGPGRP, (char *)&initialpgrp) < 0) { + #else +- initialpgrp = tcgetpgrp(2); ++ initialpgrp = tcgetpgrp(fd2); + if (initialpgrp < 0) { + #endif + out2str("sh: can't access tty; job control turned off\n"); +@@ -146,7 +146,7 @@ + } + } while (0); + #ifdef OLD_TTY_DRIVER +- if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { ++ if (ioctl(fd2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { + out2str("sh: need new tty driver to run job control; job control turned off\n"); + mflag = 0; + return; +@@ -157,16 +157,16 @@ + setsignal(SIGTTIN); + setpgid(0, rootpid); + #ifdef OLD_TTY_DRIVER +- ioctl(2, TIOCSPGRP, (char *)&rootpid); ++ ioctl(fd2, TIOCSPGRP, (char *)&rootpid); + #else +- tcsetpgrp(2, rootpid); ++ tcsetpgrp(fd2, rootpid); + #endif + } else { /* turning job control off */ + setpgid(0, initialpgrp); + #ifdef OLD_TTY_DRIVER +- ioctl(2, TIOCSPGRP, (char *)&initialpgrp); ++ ioctl(fd2, TIOCSPGRP, (char *)&initialpgrp); + #else +- tcsetpgrp(2, initialpgrp); ++ tcsetpgrp(fd2, initialpgrp); + #endif + setsignal(SIGTSTP); + setsignal(SIGTTOU); +@@ -206,9 +206,9 @@ + error("job not created under job control"); + pgrp = jp->ps[0].pid; + #ifdef OLD_TTY_DRIVER +- ioctl(2, TIOCSPGRP, (char *)&pgrp); ++ ioctl(fd2, TIOCSPGRP, (char *)&pgrp); + #else +- tcsetpgrp(2, pgrp); ++ tcsetpgrp(fd2, pgrp); + #endif + restartjob(jp); + INTOFF; +@@ -612,10 +612,10 @@ + if (mode == FORK_FG) { + /*** this causes superfluous TIOCSPGRPS ***/ + #ifdef OLD_TTY_DRIVER +- if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0) ++ if (ioctl(fd2, TIOCSPGRP, (char *)&pgrp) < 0) + error("TIOCSPGRP failed, errno=%d", errno); + #else +- if (tcsetpgrp(2, pgrp) < 0) ++ if (tcsetpgrp(fd2, pgrp) < 0) + error("tcsetpgrp failed, errno=%d", errno); + #endif + } +@@ -734,10 +734,10 @@ + #if JOBS + if (jp->jobctl) { + #ifdef OLD_TTY_DRIVER +- if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0) ++ if (ioctl(fd2, TIOCSPGRP, (char *)&mypgrp) < 0) + error("TIOCSPGRP failed, errno=%d\n", errno); + #else +- if (tcsetpgrp(2, mypgrp) < 0) ++ if (tcsetpgrp(fd2, mypgrp) < 0) + error("tcsetpgrp failed, errno=%d\n", errno); + #endif + } +@@ -1092,6 +1092,8 @@ + p = ">>"; i = 1; goto redir; + case NTOFD: + p = ">&"; i = 1; goto redir; ++ case NTOOV: ++ p = ">|"; i = 1; goto redir; + case NFROM: + p = "<"; i = 0; goto redir; + case NFROMFD: +Only in netbsd-sh-: jobs.c.orig +diff -ur netbsd-sh/nodetypes netbsd-sh-/nodetypes +--- netbsd-sh/nodetypes Fri Feb 5 13:04:52 1999 ++++ netbsd-sh-/nodetypes Mon Apr 23 23:33:34 2001 +@@ -119,6 +119,7 @@ + NFROM nfile # fd< fname + NFROMTO nfile # fd<> fname + NAPPEND nfile # fd>> fname ++NTOOV nfile # fd>| fname + type int + next nodeptr # next redirection in list + fd int # file descriptor being redirected +diff -ur netbsd-sh/parser.c netbsd-sh-/parser.c +--- netbsd-sh/parser.c Fri Jan 12 17:50:39 2001 ++++ netbsd-sh-/parser.c Mon Apr 23 23:33:34 2001 +@@ -1125,6 +1125,8 @@ + np->type = NAPPEND; + else if (c == '&') + np->type = NTOFD; ++ else if (c == '|') ++ np->type = NTOOV; + else { + np->type = NTO; + pungetc(); +diff -ur netbsd-sh/redir.c netbsd-sh-/redir.c +--- netbsd-sh/redir.c Tue May 23 12:03:19 2000 ++++ netbsd-sh-/redir.c Mon Apr 23 23:33:34 2001 +@@ -45,6 +45,7 @@ + #endif + #endif /* not lint */ + ++#include <sys/stat.h> + #include <sys/types.h> + #include <sys/param.h> /* PIPE_BUF */ + #include <signal.h> +@@ -66,6 +67,7 @@ + #include "output.h" + #include "memalloc.h" + #include "error.h" ++#include "options.h" + + + #define EMPTY -2 /* marks an unused slot in redirtab */ +@@ -92,8 +94,15 @@ + */ + int fd0_redirected = 0; + +-STATIC void openredirect __P((union node *, char[10 ])); ++/* ++ * We also keep track of where fd2 goes. ++ */ ++int fd2 = 2; ++ ++STATIC int openredirect __P((union node *)); ++STATIC void dupredirect __P((union node *, int, char[10 ])); + STATIC int openhere __P((union node *)); ++STATIC int noclobberopen __P((const char *)); + + + /* +@@ -113,6 +122,7 @@ + struct redirtab *sv = NULL; + int i; + int fd; ++ int newfd; + int try; + char memory[10]; /* file descriptors to write to memory */ + +@@ -133,36 +143,47 @@ + n->ndup.dupfd == fd) + continue; /* redirect from/to same file descriptor */ + +- if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) { +- INTOFF; +-again: +- if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { ++ INTOFF; ++ newfd = openredirect(n); ++ if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) || ++ (fd == fd2)) { ++ if (newfd == fd) { ++ try++; ++ } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { + switch (errno) { + case EBADF: + if (!try) { +- openredirect(n, memory); ++ dupredirect(n, newfd, memory); + try++; +- goto again; ++ break; + } + /* FALLTHROUGH*/ + default: ++ if (newfd >= 0) { ++ close(newfd); ++ } + INTON; + error("%d: %s", fd, strerror(errno)); + /* NOTREACHED */ + } + } + if (!try) { +- sv->renamed[fd] = i; + close(fd); ++ if (flags & REDIR_PUSH) { ++ sv->renamed[fd] = i; ++ } ++ if (fd == fd2) { ++ fd2 = i; ++ } + } +- INTON; +- } else { ++ } else if (fd != newfd) { + close(fd); + } + if (fd == 0) + fd0_redirected++; + if (!try) +- openredirect(n, memory); ++ dupredirect(n, newfd, memory); ++ INTON; + } + if (memory[1]) + out1 = &memout; +@@ -171,22 +192,13 @@ + } + + +-STATIC void +-openredirect(redir, memory) ++STATIC int ++openredirect(redir) + union node *redir; +- char memory[10]; + { +- int fd = redir->nfile.fd; + char *fname; + int f; + +- /* +- * 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; +@@ -199,6 +211,14 @@ + goto ecreate; + break; + case NTO: ++ /* Take care of noclobber mode. */ ++ if (Cflag) { ++ fname = redir->nfile.expfname; ++ if ((f = noclobberopen(fname)) < 0) ++ goto ecreate; ++ break; ++ } ++ case NTOOV: + fname = redir->nfile.expfname; + #ifdef O_CREAT + if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) +@@ -222,32 +242,48 @@ + break; + case NTOFD: + case NFROMFD: ++ f = -1; ++ break; ++ case NHERE: ++ case NXHERE: ++ f = openhere(redir); ++ break; ++ default: ++ abort(); ++ } ++ ++ return f; ++ecreate: ++ error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); ++eopen: ++ error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); ++} ++ ++ ++STATIC void ++dupredirect(redir, f, memory) ++ union node *redir; ++ int f; ++ char memory[10]; ++ { ++ int fd = redir->nfile.fd; ++ ++ memory[fd] = 0; ++ if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { + if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ + if (memory[redir->ndup.dupfd]) + memory[fd] = 1; + else + copyfd(redir->ndup.dupfd, fd); + } +- INTON; + return; +- case NHERE: +- case NXHERE: +- f = openhere(redir); +- break; +- default: +- abort(); + } + + if (f != fd) { + copyfd(f, fd); + close(f); + } +- INTON; + return; +-ecreate: +- error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); +-eopen: +- error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); + } + + +@@ -304,6 +340,7 @@ + struct redirtab *rp = redirlist; + int i; + ++ INTOFF; + for (i = 0 ; i < 10 ; i++) { + if (rp->renamed[i] != EMPTY) { + if (i == 0) +@@ -313,9 +350,11 @@ + copyfd(rp->renamed[i], i); + close(rp->renamed[i]); + } ++ if (rp->renamed[i] == fd2) { ++ fd2 = i; ++ } + } + } +- INTOFF; + redirlist = rp->next; + ckfree(rp); + INTON; +@@ -359,6 +398,9 @@ + for (i = 0 ; i < 10 ; i++) { + if (rp->renamed[i] >= 0) { + close(rp->renamed[i]); ++ if (rp->renamed[i] == fd2) { ++ fd2 = -1; ++ } + } + rp->renamed[i] = EMPTY; + } +@@ -388,4 +430,63 @@ + error("%d: %s", from, strerror(errno)); + } + return newfd; ++} ++ ++/* ++ * Open a file in noclobber mode. ++ * The code was copied from bash. ++ */ ++int ++noclobberopen(fname) ++ const char *fname; ++{ ++ int r, fd; ++ struct stat finfo, finfo2; ++ ++ /* ++ * If the file exists and is a regular file, return an error ++ * immediately. ++ */ ++ r = stat(fname, &finfo); ++ if (r == 0 && S_ISREG(finfo.st_mode)) { ++ errno = EEXIST; ++ return -1; ++ } ++ ++ /* ++ * If the file was not present (r != 0), make sure we open it ++ * exclusively so that if it is created before we open it, our open ++ * will fail. Make sure that we do not truncate an existing file. ++ * Note that we don't turn on O_EXCL unless the stat failed -- if the ++ * file was not a regular file, we leave O_EXCL off. ++ */ ++ if (r != 0) ++ return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666); ++ fd = open(fname, O_WRONLY|O_CREAT, 0666); ++ ++ /* If the open failed, return the file descriptor right away. */ ++ if (fd < 0) ++ return fd; ++ ++ /* ++ * OK, the open succeeded, but the file may have been changed from a ++ * non-regular file to a regular file between the stat and the open. ++ * We are assuming that the O_EXCL open handles the case where FILENAME ++ * did not exist and is symlinked to an existing file between the stat ++ * and open. ++ */ ++ ++ /* ++ * If we can open it and fstat the file descriptor, and neither check ++ * revealed that it was a regular file, and the file has not been ++ * replaced, return the file descriptor. ++ */ ++ if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) && ++ finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino) ++ return fd; ++ ++ /* The file has been replaced. badness. */ ++ close(fd); ++ errno = EEXIST; ++ return -1; + } +Only in netbsd-sh-: redir.c.orig +diff -ur netbsd-sh/redir.h netbsd-sh-/redir.h +--- netbsd-sh/redir.h Tue May 23 12:03:19 2000 ++++ netbsd-sh-/redir.h Mon Apr 23 23:33:34 2001 +@@ -42,6 +42,8 @@ + #define REDIR_PUSH 01 /* save previous values of file descriptors */ + #define REDIR_BACKQ 02 /* save the command output in memory */ + ++extern int fd2; ++ + union node; + void redirect __P((union node *, int)); + void popredir __P((void)); +diff -ur netbsd-sh/show.c netbsd-sh-/show.c +--- netbsd-sh/show.c Sat Oct 9 13:02:09 1999 ++++ netbsd-sh-/show.c Mon Apr 23 23:33:34 2001 +@@ -155,6 +155,7 @@ + case NTO: s = ">"; dftfd = 1; break; + case NAPPEND: s = ">>"; dftfd = 1; break; + case NTOFD: s = ">&"; dftfd = 1; break; ++ case NTOOV: s = ">|"; dftfd = 1; break; + case NFROM: s = "<"; dftfd = 0; break; + case NFROMFD: s = "<&"; dftfd = 0; break; + case NFROMTO: s = "<>"; dftfd = 0; break; |