BSD 4_4 release
[unix-history] / usr / src / bin / csh / sem.c
index e87d6b4..584d3fb 100644 (file)
@@ -1,22 +1,62 @@
 /*-
 /*-
- * Copyright (c) 1980, 1991 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1980, 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. 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.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)sem.c      5.14 (Berkeley) %G%";
+static char sccsid[] = "@(#)sem.c      8.1 (Berkeley) 5/31/93";
 #endif /* not lint */
 
 #endif /* not lint */
 
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#if __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
 #include "csh.h"
 #include "csh.h"
-#include "dir.h"
 #include "proc.h"
 #include "extern.h"
 
 #include "proc.h"
 #include "extern.h"
 
-static void    vffree __P((int));
-static void    doio __P((struct command *t, int *, int *));
-static void    chkclob __P((Char *));
+static void     vffree __P((int));
+static Char    *splicepipe __P((struct command *t, Char *));
+static void     doio __P((struct command *t, int *, int *));
+static void     chkclob __P((char *));
 
 void
 execute(t, wanttty, pipein, pipeout)
 
 void
 execute(t, wanttty, pipein, pipeout)
@@ -28,12 +68,16 @@ execute(t, wanttty, pipein, pipeout)
     int     pid = 0;
     int     pv[2];
 
     int     pid = 0;
     int     pv[2];
 
-    static sigmask_t csigmask;
+    static sigset_t csigmask;
 
 
-    static sigmask_t ocsigmask;
+    static sigset_t ocsigmask;
     static int onosigchld = 0;
     static int nosigchld = 0;
 
     static int onosigchld = 0;
     static int nosigchld = 0;
 
+    UNREGISTER(forked);
+    UNREGISTER(bifunc);
+    UNREGISTER(wanttty);
+
     if (t == 0)
        return;
 
     if (t == 0)
        return;
 
@@ -63,8 +107,6 @@ execute(t, wanttty, pipein, pipeout)
            if (noexec)
                (void) close(0);
        }
            if (noexec)
                (void) close(0);
        }
-       if (noexec)
-           break;
 
        set(STRstatus, Strsave(STR0));
 
 
        set(STRstatus, Strsave(STR0));
 
@@ -111,15 +153,29 @@ execute(t, wanttty, pipein, pipeout)
            else
                break;
 
            else
                break;
 
-       /* is t a command */
+       /* is it a command */
        if (t->t_dtyp == NODE_COMMAND) {
            /*
             * Check if we have a builtin function and remember which one.
             */
            bifunc = isbfunc(t);
        if (t->t_dtyp == NODE_COMMAND) {
            /*
             * Check if we have a builtin function and remember which one.
             */
            bifunc = isbfunc(t);
+           if (noexec) {
+               /*
+                * Continue for builtins that are part of the scripting language
+                */
+               if (bifunc->bfunct != dobreak   && bifunc->bfunct != docontin &&
+                   bifunc->bfunct != doelse    && bifunc->bfunct != doend    &&
+                   bifunc->bfunct != doforeach && bifunc->bfunct != dogoto   &&
+                   bifunc->bfunct != doif      && bifunc->bfunct != dorepeat &&
+                   bifunc->bfunct != doswbrk   && bifunc->bfunct != doswitch &&
+                   bifunc->bfunct != dowhile   && bifunc->bfunct != dozip)
+                   break;
+           }
        }
        else {                  /* not a command */
        }
        else {                  /* not a command */
-           bifunc = (struct biltins *) 0;
+           bifunc = NULL;
+           if (noexec)
+               break;
        }
 
        /*
        }
 
        /*
@@ -136,13 +192,13 @@ execute(t, wanttty, pipein, pipeout)
                       bifunc->bfunct == dopushd ||
                       bifunc->bfunct == dopopd))
            t->t_dflg &= ~(F_NICE);
                       bifunc->bfunct == dopushd ||
                       bifunc->bfunct == dopopd))
            t->t_dflg &= ~(F_NICE);
-       if (((t->t_dflg & F_TIME) || (t->t_dflg & F_NOFORK) == 0 &&
+       if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 &&
             (!bifunc || t->t_dflg &
             (!bifunc || t->t_dflg &
-             (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP))) ||
+             (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP)))) ||
        /*
         * We have to fork for eval too.
         */
        /*
         * We have to fork for eval too.
         */
-           (bifunc && (t->t_dflg & F_PIPEIN) != 0 &&
+           (bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 &&
             bifunc->bfunct == doeval))
            if (t->t_dtyp == NODE_PAREN ||
                t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) {
             bifunc->bfunct == doeval))
            if (t->t_dtyp == NODE_PAREN ||
                t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) {
@@ -161,11 +217,14 @@ execute(t, wanttty, pipein, pipeout)
                    (void) sigsetmask(csigmask);
                    nosigchld = 0;
                }
                    (void) sigsetmask(csigmask);
                    nosigchld = 0;
                }
+               else if (pid != 0 && (t->t_dflg & F_AMPERSAND))
+                   backpid = pid;
+
            }
            else {
                int     ochild, osetintr, ohaderr, odidfds;
            }
            else {
                int     ochild, osetintr, ohaderr, odidfds;
-               int     oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp;
-               sigmask_t omask;
+               int     oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp;
+               sigset_t omask;
 
                /*
                 * Prepare for the vfork by saving everything that the child
 
                /*
                 * Prepare for the vfork by saving everything that the child
@@ -186,7 +245,7 @@ execute(t, wanttty, pipein, pipeout)
                odidfds = didfds;
                oSHIN = SHIN;
                oSHOUT = SHOUT;
                odidfds = didfds;
                oSHIN = SHIN;
                oSHOUT = SHOUT;
-               oSHDIAG = SHDIAG;
+               oSHERR = SHERR;
                oOLDSTD = OLDSTD;
                otpgrp = tpgrp;
                ocsigmask = csigmask;
                oOLDSTD = OLDSTD;
                otpgrp = tpgrp;
                ocsigmask = csigmask;
@@ -208,7 +267,7 @@ execute(t, wanttty, pipein, pipeout)
                    didfds = odidfds;
                    SHIN = oSHIN;
                    SHOUT = oSHOUT;
                    didfds = odidfds;
                    SHIN = oSHIN;
                    SHOUT = oSHOUT;
-                   SHDIAG = oSHDIAG;
+                   SHERR = oSHERR;
                    OLDSTD = oOLDSTD;
                    tpgrp = otpgrp;
                    csigmask = ocsigmask;
                    OLDSTD = oOLDSTD;
                    tpgrp = otpgrp;
                    csigmask = ocsigmask;
@@ -240,7 +299,7 @@ execute(t, wanttty, pipein, pipeout)
                        ignint =
                            (tpgrp == -1 &&
                             (t->t_dflg & F_NOINTERRUPT))
                        ignint =
                            (tpgrp == -1 &&
                             (t->t_dflg & F_NOINTERRUPT))
-                           || gointr && eq(gointr, STRminus);
+                           || (gointr && eq(gointr, STRminus));
                    pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
                    child++;
                    if (setintr) {
                    pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
                    child++;
                    if (setintr) {
@@ -313,7 +372,7 @@ execute(t, wanttty, pipein, pipeout)
            break;
        }
        if (t->t_dtyp != NODE_PAREN) {
            break;
        }
        if (t->t_dtyp != NODE_PAREN) {
-           doexec(t);
+           doexec(NULL, t);
            /* NOTREACHED */
        }
        /*
            /* NOTREACHED */
        }
        /*
@@ -321,7 +380,7 @@ execute(t, wanttty, pipein, pipeout)
         */
        OLDSTD = dcopy(0, FOLDSTD);
        SHOUT = dcopy(1, FSHOUT);
         */
        OLDSTD = dcopy(0, FOLDSTD);
        SHOUT = dcopy(1, FSHOUT);
-       SHDIAG = dcopy(2, FSHDIAG);
+       SHERR = dcopy(2, FSHERR);
        (void) close(SHIN);
        SHIN = -1;
        didfds = 0;
        (void) close(SHIN);
        SHIN = -1;
        didfds = 0;
@@ -392,17 +451,71 @@ int i;
 {
     register Char **v;
 
 {
     register Char **v;
 
-    if (v = gargv) {
+    if ((v = gargv) != NULL) {
        gargv = 0;
        xfree((ptr_t) v);
     }
        gargv = 0;
        xfree((ptr_t) v);
     }
-    if (v = pargv) {
+    if ((v = pargv) != NULL) {
        pargv = 0;
        xfree((ptr_t) v);
     }
     _exit(i);
 }
 
        pargv = 0;
        xfree((ptr_t) v);
     }
     _exit(i);
 }
 
+/*
+ * Expand and glob the words after an i/o redirection.
+ * If more than one word is generated, then update the command vector.
+ *
+ * This is done differently in all the shells:
+ * 1. in the bourne shell and ksh globbing is not performed
+ * 2. Bash/csh say ambiguous
+ * 3. zsh does i/o to/from all the files
+ * 4. itcsh concatenates the words.
+ *
+ * I don't know what is best to do. I think that Ambiguous is better
+ * than restructuring the command vector, because the user can get
+ * unexpected results. In any case, the command vector restructuring 
+ * code is present and the user can choose it by setting noambiguous
+ */
+static Char *
+splicepipe(t, cp)
+    register struct command *t;
+    Char *cp;  /* word after < or > */
+{
+    Char *blk[2];
+
+    if (adrof(STRnoambiguous)) {
+       Char **pv;
+
+       blk[0] = Dfix1(cp); /* expand $ */
+       blk[1] = NULL;
+
+       gflag = 0, tglob(blk);
+       if (gflag) {
+           pv = globall(blk);
+           if (pv == NULL) {
+               setname(vis_str(blk[0]));
+               xfree((ptr_t) blk[0]);
+               stderror(ERR_NAME | ERR_NOMATCH);
+           }
+           gargv = NULL;
+           if (pv[1] != NULL) { /* we need to fix the command vector */
+               Char **av = blkspl(t->t_dcom, &pv[1]);
+               xfree((ptr_t) t->t_dcom);
+               t->t_dcom = av;
+           }
+           xfree((ptr_t) blk[0]);
+           blk[0] = pv[0];
+           xfree((ptr_t) pv);
+       }
+    }
+    else {
+       blk[0] = globone(blk[1] = Dfix1(cp), G_ERROR);
+       xfree((ptr_t) blk[1]);
+    }
+    return(blk[0]);
+}
+
 /*
  * Perform io redirection.
  * We may or maynot be forked here.
 /*
  * Perform io redirection.
  * We may or maynot be forked here.
@@ -419,18 +532,18 @@ doio(t, pipein, pipeout)
     if (didfds || (flags & F_REPEAT))
        return;
     if ((flags & F_READ) == 0) {/* F_READ already done */
     if (didfds || (flags & F_REPEAT))
        return;
     if ((flags & F_READ) == 0) {/* F_READ already done */
-       if (cp = t->t_dlef) {
-           char    tmp[MAXPATHLEN];
+       if (t->t_dlef) {
+           char    tmp[MAXPATHLEN+1];
 
            /*
             * so < /dev/std{in,out,err} work
             */
            (void) dcopy(SHIN, 0);
            (void) dcopy(SHOUT, 1);
 
            /*
             * so < /dev/std{in,out,err} work
             */
            (void) dcopy(SHIN, 0);
            (void) dcopy(SHOUT, 1);
-           (void) dcopy(SHDIAG, 2);
-           cp = globone(Dfix1(cp), G_IGNORE);
+           (void) dcopy(SHERR, 2);
+           cp = splicepipe(t, t->t_dlef);
            (void) strncpy(tmp, short2str(cp), MAXPATHLEN);
            (void) strncpy(tmp, short2str(cp), MAXPATHLEN);
-           tmp[MAXPATHLEN - 1] = '\0';
+           tmp[MAXPATHLEN] = '\0';
            xfree((ptr_t) cp);
            if ((fd = open(tmp, O_RDONLY)) < 0)
                stderror(ERR_SYSTEM, tmp, strerror(errno));
            xfree((ptr_t) cp);
            if ((fd = open(tmp, O_RDONLY)) < 0)
                stderror(ERR_SYSTEM, tmp, strerror(errno));
@@ -449,36 +562,36 @@ doio(t, pipein, pipeout)
        else {
            (void) close(0);
            (void) dup(OLDSTD);
        else {
            (void) close(0);
            (void) dup(OLDSTD);
-           (void) ioctl(0, FIONCLEX, (char *) 0);
+           (void) ioctl(0, FIONCLEX, NULL);
        }
     }
        }
     }
-    if (cp = t->t_drit) {
-       Char    tmp[MAXPATHLEN];
+    if (t->t_drit) {
+       char    tmp[MAXPATHLEN+1];
 
 
-       cp = globone(Dfix1(cp), G_IGNORE);
-       (void) Strncpy(tmp, cp, MAXPATHLEN);
-       tmp[MAXPATHLEN - 1] = '\0';
+       cp = splicepipe(t, t->t_drit);
+       (void) strncpy(tmp, short2str(cp), MAXPATHLEN);
+       tmp[MAXPATHLEN] = '\0';
        xfree((ptr_t) cp);
        /*
         * so > /dev/std{out,err} work
         */
        (void) dcopy(SHOUT, 1);
        xfree((ptr_t) cp);
        /*
         * so > /dev/std{out,err} work
         */
        (void) dcopy(SHOUT, 1);
-       (void) dcopy(SHDIAG, 2);
+       (void) dcopy(SHERR, 2);
        if ((flags & F_APPEND) &&
 #ifdef O_APPEND
        if ((flags & F_APPEND) &&
 #ifdef O_APPEND
-           (fd = open(short2str(tmp), O_WRONLY | O_APPEND)) >= 0);
+           (fd = open(tmp, O_WRONLY | O_APPEND)) >= 0);
 #else
 #else
-           (fd = open(short2str(tmp), O_WRONLY)) >= 0)
+           (fd = open(tmp, O_WRONLY)) >= 0)
            (void) lseek(1, (off_t) 0, L_XTND);
 #endif
        else {
            if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) {
                if (flags & F_APPEND)
            (void) lseek(1, (off_t) 0, L_XTND);
 #endif
        else {
            if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) {
                if (flags & F_APPEND)
-                   stderror(ERR_SYSTEM, short2str(tmp), strerror(errno));
+                   stderror(ERR_SYSTEM, tmp, strerror(errno));
                chkclob(tmp);
            }
                chkclob(tmp);
            }
-           if ((fd = creat(short2str(tmp), 0666)) < 0)
-               stderror(ERR_SYSTEM, short2str(tmp), strerror(errno));
+           if ((fd = creat(tmp, 0666)) < 0)
+               stderror(ERR_SYSTEM, tmp, strerror(errno));
        }
        (void) dmove(fd, 1);
     }
        }
        (void) dmove(fd, 1);
     }
@@ -489,7 +602,7 @@ doio(t, pipein, pipeout)
     else {
        (void) close(1);
        (void) dup(SHOUT);
     else {
        (void) close(1);
        (void) dup(SHOUT);
-       (void) ioctl(1, FIONCLEX, (char *) 0);
+       (void) ioctl(1, FIONCLEX, NULL);
     }
 
     (void) close(2);
     }
 
     (void) close(2);
@@ -497,8 +610,8 @@ doio(t, pipein, pipeout)
        (void) dup(1);
     }
     else {
        (void) dup(1);
     }
     else {
-       (void) dup(SHDIAG);
-       (void) ioctl(2, FIONCLEX, (char *) 0);
+       (void) dup(SHERR);
+       (void) ioctl(2, FIONCLEX, NULL);
     }
     didfds = 1;
 }
     }
     didfds = 1;
 }
@@ -520,14 +633,13 @@ oops:
 
 static void
 chkclob(cp)
 
 static void
 chkclob(cp)
-    register Char *cp;
+    register char *cp;
 {
     struct stat stb;
 {
     struct stat stb;
-    char   *ptr;
 
 
-    if (stat(ptr = short2str(cp), &stb) < 0)
+    if (stat(cp, &stb) < 0)
        return;
        return;
-    if ((stb.st_mode & S_IFMT) == S_IFCHR)
+    if (S_ISCHR(stb.st_mode))
        return;
        return;
-    stderror(ERR_EXISTS, ptr);
+    stderror(ERR_EXISTS, cp);
 }
 }