date and time created 91/03/07 20:28:05 by bostic
[unix-history] / usr / src / bin / csh / sem.c
index c6588fd..55d3914 100644 (file)
@@ -5,17 +5,21 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char *sccsid = "@(#)sem.c       5.2 (Berkeley) %G%";
+static char *sccsid = "@(#)sem.c       5.8 (Berkeley) %G%";
 #endif
 
 #include "sh.h"
 #include "sh.proc.h"
 #endif
 
 #include "sh.h"
 #include "sh.proc.h"
+#include <sys/file.h>
 #include <sys/ioctl.h>
 #include <sys/ioctl.h>
+#include "pathnames.h"
 
 /*
  * C shell
  */
 
 
 /*
  * C shell
  */
 
+static int nosigchld = 0, osigmask;
+static int onosigchld = 0, oosigmask;
 /*VARARGS 1*/
 execute(t, wanttty, pipein, pipeout)
        register struct command *t;
 /*VARARGS 1*/
 execute(t, wanttty, pipein, pipeout)
        register struct command *t;
@@ -115,19 +119,45 @@ execute(t, wanttty, pipein, pipeout)
 #ifdef VFORK
                    if (t->t_dtyp == TPAR || t->t_dflg&(FREDO|FAND) || bifunc)
 #endif
 #ifdef VFORK
                    if (t->t_dtyp == TPAR || t->t_dflg&(FREDO|FAND) || bifunc)
 #endif
-                       { forked++; pid = pfork(t, wanttty); }
+                       { forked++; 
+                         if (wanttty >= 0 && !nosigchld) {
+                               osigmask = sigblock(sigmask(SIGCHLD));
+                               nosigchld = 1;
+                         }
+
+                         pid = pfork(t, wanttty);
+                         if (pid == 0 && nosigchld) {
+                               sigsetmask(osigmask);
+                               nosigchld = 0;
+                         }
+                       }
 #ifdef VFORK
                    else {
 #ifdef VFORK
                    else {
-                       int vffree();
+                       sig_t vffree;
                        int ochild, osetintr, ohaderr, odidfds;
                        int oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp;
                        int ochild, osetintr, ohaderr, odidfds;
                        int oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp;
-                       int omask;
+                       long omask;
 
 
+                       /* 
+                        * Prepare for the vfork by saving everything
+                        * that the child corrupts before it exec's.
+                        * Note that in some signal implementations
+                        * which keep the signal info in user space
+                        * (e.g. Sun's) it will also be necessary to
+                        * save and restore the current sigvec's for
+                        * the signals the child touches before it
+                        * exec's.
+                        */
+                       if (wanttty >= 0 && !nosigchld && !noexec) {
+                               osigmask = sigblock(sigmask(SIGCHLD));
+                               nosigchld = 1;
+                       }
                        omask = sigblock(sigmask(SIGCHLD));
                        ochild = child; osetintr = setintr;
                        ohaderr = haderr; odidfds = didfds;
                        oSHIN = SHIN; oSHOUT = SHOUT;
                        oSHDIAG = SHDIAG; oOLDSTD = OLDSTD; otpgrp = tpgrp;
                        omask = sigblock(sigmask(SIGCHLD));
                        ochild = child; osetintr = setintr;
                        ohaderr = haderr; odidfds = didfds;
                        oSHIN = SHIN; oSHOUT = SHOUT;
                        oSHDIAG = SHDIAG; oOLDSTD = OLDSTD; otpgrp = tpgrp;
+                       oosigmask = osigmask; onosigchld = nosigchld;
                        Vsav = Vdp = 0; Vav = 0;
                        pid = vfork();
                        if (pid < 0) {
                        Vsav = Vdp = 0; Vav = 0;
                        pid = vfork();
                        if (pid < 0) {
@@ -135,23 +165,28 @@ execute(t, wanttty, pipein, pipeout)
                                error("No more processes");
                        }
                        forked++;
                                error("No more processes");
                        }
                        forked++;
-                       if (pid) {
+                       if (pid) {      /* parent */
                                child = ochild; setintr = osetintr;
                                haderr = ohaderr; didfds = odidfds;
                                SHIN = oSHIN;
                                SHOUT = oSHOUT; SHDIAG = oSHDIAG;
                                OLDSTD = oOLDSTD; tpgrp = otpgrp;
                                child = ochild; setintr = osetintr;
                                haderr = ohaderr; didfds = odidfds;
                                SHIN = oSHIN;
                                SHOUT = oSHOUT; SHDIAG = oSHDIAG;
                                OLDSTD = oOLDSTD; tpgrp = otpgrp;
+                               osigmask = oosigmask; nosigchld = onosigchld;
                                xfree(Vsav); Vsav = 0;
                                xfree(Vdp); Vdp = 0;
                                xfree((char *)Vav); Vav = 0;
                                /* this is from pfork() */
                                palloc(pid, t);
                                (void) sigsetmask(omask);
                                xfree(Vsav); Vsav = 0;
                                xfree(Vdp); Vdp = 0;
                                xfree((char *)Vav); Vav = 0;
                                /* this is from pfork() */
                                palloc(pid, t);
                                (void) sigsetmask(omask);
-                       } else {
+                       } else {        /* child */
                                /* this is from pfork() */
                                int pgrp;
                                bool ignint = 0;
 
                                /* this is from pfork() */
                                int pgrp;
                                bool ignint = 0;
 
+                               if (nosigchld) {
+                                       sigsetmask(osigmask);
+                                       nosigchld = 0;
+                               }
                                if (setintr)
                                        ignint =
                                            (tpgrp == -1 && (t->t_dflg&FINT))
                                if (setintr)
                                        ignint =
                                            (tpgrp == -1 && (t->t_dflg&FINT))
@@ -177,11 +212,11 @@ execute(t, wanttty, pipein, pipeout)
                                        (void) signal(SIGINT, SIG_IGN);
                                        (void) signal(SIGQUIT, SIG_IGN);
                                }
                                        (void) signal(SIGINT, SIG_IGN);
                                        (void) signal(SIGQUIT, SIG_IGN);
                                }
+                               if (wanttty >= 0 && tpgrp >= 0)
+                                       (void) setpgrp(0, pgrp);
                                if (wanttty > 0)
                                        (void) ioctl(FSHTTY, TIOCSPGRP,
                                                (char *)&pgrp);
                                if (wanttty > 0)
                                        (void) ioctl(FSHTTY, TIOCSPGRP,
                                                (char *)&pgrp);
-                               if (wanttty >= 0 && tpgrp >= 0)
-                                       (void) setpgrp(0, pgrp);
                                if (tpgrp > 0)
                                        tpgrp = 0;
                                if (t->t_dflg & FNOHUP)
                                if (tpgrp > 0)
                                        tpgrp = 0;
                                if (t->t_dflg & FNOHUP)
@@ -205,8 +240,17 @@ execute(t, wanttty, pipein, pipeout)
                                (void) close(pipein[0]);
                                (void) close(pipein[1]);
                        }
                                (void) close(pipein[0]);
                                (void) close(pipein[1]);
                        }
-                       if ((t->t_dflg & (FPOU|FAND)) == 0)
-                               pwait();
+                       if ((t->t_dflg & FPOU) == 0) {
+                               if (nosigchld) {
+#ifdef foobarbaz
+                                       printf("DID\n");
+#endif
+                                       sigsetmask(osigmask);
+                                       nosigchld = 0;
+                               }
+                               if ((t->t_dflg & FAND) == 0)
+                                       pwait();
+                       }
                        break;
                }
                doio(t, pipein, pipeout);
                        break;
                }
                doio(t, pipein, pipeout);
@@ -336,7 +380,7 @@ doio(t, pipein, pipeout)
                        (void) close(pipein[1]);
                } else if ((flags & FINT) && tpgrp == -1) {
                        (void) close(0);
                        (void) close(pipein[1]);
                } else if ((flags & FINT) && tpgrp == -1) {
                        (void) close(0);
-                       (void) open("/dev/null", 0);
+                       (void) open(_PATH_DEVNULL, 0);
                } else
                        (void) dup(OLDSTD);
        }
                } else
                        (void) dup(OLDSTD);
        }
@@ -344,9 +388,7 @@ doio(t, pipein, pipeout)
        if (cp = t->t_drit) {
                cp = globone(Dfix1(cp));
                xfree(cp);
        if (cp = t->t_drit) {
                cp = globone(Dfix1(cp));
                xfree(cp);
-               if ((flags & FCAT) && open(cp, 1) >= 0)
-                       (void) lseek(1, (off_t)0, 2);
-               else {
+               if (!(flags & FCAT) || open(cp, O_WRONLY|O_APPEND, 0) < 0) {
                        if (!(flags & FANY) && adrof("noclobber")) {
                                if (flags & FCAT)
                                        Perror(cp);
                        if (!(flags & FANY) && adrof("noclobber")) {
                                if (flags & FCAT)
                                        Perror(cp);