BSD 4_4 release
[unix-history] / usr / src / bin / csh / sem.c
index 315faf7..584d3fb 100644 (file)
@@ -1,12 +1,38 @@
 /*-
 /*-
- * 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.20 (Berkeley) %G%";
+static char sccsid[] = "@(#)sem.c      8.1 (Berkeley) 5/31/93";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -27,9 +53,10 @@ static char sccsid[] = "@(#)sem.c    5.20 (Berkeley) %G%";
 #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)
@@ -47,6 +74,10 @@ execute(t, wanttty, pipein, pipeout)
     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;
 
@@ -161,9 +192,9 @@ 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.
         */
@@ -186,6 +217,9 @@ 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;
@@ -265,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) {
@@ -417,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.
@@ -438,13 +526,13 @@ doio(t, pipein, pipeout)
     int    *pipein, *pipeout;
 {
     register int fd;
     int    *pipein, *pipeout;
 {
     register int fd;
-    register Char *cp, *dp;
+    register Char *cp;
     register int flags = t->t_dflg;
 
     if (didfds || (flags & F_REPEAT))
        return;
     if ((flags & F_READ) == 0) {/* F_READ already done */
     register int flags = t->t_dflg;
 
     if (didfds || (flags & F_REPEAT))
        return;
     if ((flags & F_READ) == 0) {/* F_READ already done */
-       if (cp = t->t_dlef) {
+       if (t->t_dlef) {
            char    tmp[MAXPATHLEN+1];
 
            /*
            char    tmp[MAXPATHLEN+1];
 
            /*
@@ -453,11 +541,10 @@ doio(t, pipein, pipeout)
            (void) dcopy(SHIN, 0);
            (void) dcopy(SHOUT, 1);
            (void) dcopy(SHERR, 2);
            (void) dcopy(SHIN, 0);
            (void) dcopy(SHOUT, 1);
            (void) dcopy(SHERR, 2);
-           cp = globone(dp = Dfix1(cp), G_IGNORE);
+           cp = splicepipe(t, t->t_dlef);
            (void) strncpy(tmp, short2str(cp), MAXPATHLEN);
            tmp[MAXPATHLEN] = '\0';
            xfree((ptr_t) cp);
            (void) strncpy(tmp, short2str(cp), MAXPATHLEN);
            tmp[MAXPATHLEN] = '\0';
            xfree((ptr_t) cp);
-           xfree((ptr_t) dp);
            if ((fd = open(tmp, O_RDONLY)) < 0)
                stderror(ERR_SYSTEM, tmp, strerror(errno));
            (void) dmove(fd, 0);
            if ((fd = open(tmp, O_RDONLY)) < 0)
                stderror(ERR_SYSTEM, tmp, strerror(errno));
            (void) dmove(fd, 0);
@@ -478,14 +565,13 @@ doio(t, pipein, pipeout)
            (void) ioctl(0, FIONCLEX, NULL);
        }
     }
            (void) ioctl(0, FIONCLEX, NULL);
        }
     }
-    if (cp = t->t_drit) {
+    if (t->t_drit) {
        char    tmp[MAXPATHLEN+1];
 
        char    tmp[MAXPATHLEN+1];
 
-       cp = globone(dp = Dfix1(cp), G_IGNORE);
+       cp = splicepipe(t, t->t_drit);
        (void) strncpy(tmp, short2str(cp), MAXPATHLEN);
        tmp[MAXPATHLEN] = '\0';
        xfree((ptr_t) cp);
        (void) strncpy(tmp, short2str(cp), MAXPATHLEN);
        tmp[MAXPATHLEN] = '\0';
        xfree((ptr_t) cp);
-       xfree((ptr_t) dp);
        /*
         * so > /dev/std{out,err} work
         */
        /*
         * so > /dev/std{out,err} work
         */
@@ -553,7 +639,7 @@ chkclob(cp)
 
     if (stat(cp, &stb) < 0)
        return;
 
     if (stat(cp, &stb) < 0)
        return;
-    if ((stb.st_mode & S_IFMT) == S_IFCHR)
+    if (S_ISCHR(stb.st_mode))
        return;
     stderror(ERR_EXISTS, cp);
 }
        return;
     stderror(ERR_EXISTS, cp);
 }