date and time created 91/03/14 12:01:54 by donn
[unix-history] / usr / src / bin / csh / csh.c
index cf78dec..787d169 100644 (file)
@@ -1,7 +1,18 @@
-static char *sccsid = "@(#)csh.c 4.5 %G%";
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley Software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char *sccsid = "@(#)csh.c       5.17 (Berkeley) %G%";
+#endif
 
 #include "sh.h"
 #include <sys/ioctl.h>
 
 #include "sh.h"
 #include <sys/ioctl.h>
+#include <sys/file.h>
+#include "pathnames.h"
+
 /*
  * C Shell
  *
 /*
  * C Shell
  *
@@ -12,35 +23,43 @@ static      char *sccsid = "@(#)csh.c 4.5 %G%";
  * April 1980
  */
 
  * April 1980
  */
 
-char   *pathlist[] =   { ".", "/usr/ucb", "/bin", "/usr/bin", 0 };
-char   *dumphist[] =   { "history", "-h", 0 };
+char   *pathlist[] =   { ".", _PATH_BIN, _PATH_USRBIN, 0 };
+char   *dumphist[] =   { "history", "-h", 0, 0 };
 char   *loadhist[] =   { "source", "-h", "~/.history", 0 };
 char   HIST = '!';
 char   HISTSUB = '^';
 char   *loadhist[] =   { "source", "-h", "~/.history", 0 };
 char   HIST = '!';
 char   HISTSUB = '^';
+bool   mflag;
 bool   nofile;
 bool   reenter;
 bool   nverbose;
 bool   nexececho;
 bool   quitit;
 bool   fast;
 bool   nofile;
 bool   reenter;
 bool   nverbose;
 bool   nexececho;
 bool   quitit;
 bool   fast;
+bool   batch;
 bool   prompt = 1;
 bool   enterhist = 0;
 
 bool   prompt = 1;
 bool   enterhist = 0;
 
-main(c, av)
-       int c;
-       char **av;
+extern gid_t getegid(), getgid();
+extern uid_t geteuid(), getuid();
+
+void pintr(), pchild(), srcunit();
+
+main(argc, argv)
+       int argc;
+       char **argv;
 {
        register char **v, *cp;
        register int f;
 {
        register char **v, *cp;
        register int f;
+       struct sigvec osv;
 
        settimes();                     /* Immed. estab. timing base */
 
        settimes();                     /* Immed. estab. timing base */
-       v = av;
+       v = argv;
        if (eq(v[0], "a.out"))          /* A.out's are quittable */
                quitit = 1;
        uid = getuid();
        if (eq(v[0], "a.out"))          /* A.out's are quittable */
                quitit = 1;
        uid = getuid();
-       loginsh = **v == '-';
+       loginsh = **v == '-' && argc == 1;
        if (loginsh)
        if (loginsh)
-               time(&chktim);
+               (void) time(&chktim);
 
        /*
         * Move the descriptors to safe places.
 
        /*
         * Move the descriptors to safe places.
@@ -76,29 +95,9 @@ main(c, av)
         */
        if ((cp = getenv("PATH")) == NOSTR)
                set1("path", saveblk(pathlist), &shvhed);
         */
        if ((cp = getenv("PATH")) == NOSTR)
                set1("path", saveblk(pathlist), &shvhed);
-       else {
-               register unsigned i = 0;
-               register char *dp;
-               register char **pv;
-
-               for (dp = cp; *dp; dp++)
-                       if (*dp == ':')
-                               i++;
-               pv = (char **)calloc(i+2, sizeof (char **));
-               for (dp = cp, i = 0; ;)
-                       if (*dp == ':') {
-                               *dp = 0;
-                               pv[i++] = savestr(*cp ? cp : ".");
-                               *dp++ = ':';
-                               cp = dp;
-                       } else if (*dp++ == 0) {
-                               pv[i++] = savestr(*cp ? cp : ".");
-                               break;
-                       }
-               pv[i] = 0;
-               set1("path", pv, &shvhed);
-       }
-       set("shell", SHELLPATH);
+       else
+               importpath(cp);
+       set("shell", _PATH_CSHELL);
 
        doldol = putn(getpid());                /* For $$ */
        shtemp = strspl("/tmp/sh", doldol);     /* For << */
 
        doldol = putn(getpid());                /* For $$ */
        shtemp = strspl("/tmp/sh", doldol);     /* For << */
@@ -110,37 +109,38 @@ main(c, av)
         * Our children inherit termination from our parent.
         * We catch it only if we are the login shell.
         */
         * Our children inherit termination from our parent.
         * We catch it only if we are the login shell.
         */
-       parintr = signal(SIGINT, SIG_IGN);      /* parents interruptibility */
-       sigset(SIGINT, parintr);                        /* ... restore */
-       parterm = signal(SIGTERM, SIG_IGN);     /* parents terminability */
-       signal(SIGTERM, parterm);                       /* ... restore */
-       if (loginsh)
-               signal(SIGHUP, phup);           /* exit processing on HUP */
+               /* parents interruptibility */
+       (void) sigvec(SIGINT, (struct sigvec *)0, &osv);
+       parintr = osv.sv_handler;
+               /* parents terminability */
+       (void) sigvec(SIGTERM, (struct sigvec *)0, &osv);
+       parterm = osv.sv_handler;
+       if (loginsh) {
+               sig_t phup;
+
+               (void) signal(SIGHUP, phup);    /* exit processing on HUP */
+               (void) signal(SIGXCPU, phup);   /* ...and on XCPU */
+               (void) signal(SIGXFSZ, phup);   /* ...and on XFSZ */
+       }
 
        /*
         * Process the arguments.
         *
         * Note that processing of -v/-x is actually delayed till after
         * script processing.
 
        /*
         * Process the arguments.
         *
         * Note that processing of -v/-x is actually delayed till after
         * script processing.
-        *
-        * We set the first character of our name to be '-' if we are
-        * a shell running interruptible commands.  Many programs which
-        * examine ps'es use this to filter such shells out.
         */
         */
-       c--, v++;
-       while (c > 0 && (cp = v[0])[0] == '-') {
+       argc--, v++;
+       while (argc > 0 && (cp = v[0])[0] == '-' && *++cp != '\0' && !batch) {
                do switch (*cp++) {
 
                do switch (*cp++) {
 
-               case 0:                 /* -    Interruptible, no prompt */
-                       prompt = 0;
-                       setintr++;
-                       nofile++;
+               case 'b':               /* -b   Next arg is input file */
+                       batch++;
                        break;
 
                case 'c':               /* -c   Command input from arg */
                        break;
 
                case 'c':               /* -c   Command input from arg */
-                       if (c == 1)
+                       if (argc == 1)
                                exit(0);
                                exit(0);
-                       c--, v++;
+                       argc--, v++;
                        arginp = v[0];
                        prompt = 0;
                        nofile++;
                        arginp = v[0];
                        prompt = 0;
                        nofile++;
@@ -159,6 +159,10 @@ main(c, av)
                        nofile++;
                        break;
 
                        nofile++;
                        break;
 
+               case 'm':               /* -m   read .cshrc (from su) */
+                       mflag++;
+                       break;
+
                case 'n':               /* -n   Don't execute */
                        noexec++;
                        break;
                case 'n':               /* -n   Don't execute */
                        noexec++;
                        break;
@@ -194,18 +198,18 @@ main(c, av)
                        break;
 
                } while (*cp);
                        break;
 
                } while (*cp);
-               v++, c--;
+               v++, argc--;
        }
 
        if (quitit)                     /* With all due haste, for debugging */
        }
 
        if (quitit)                     /* With all due haste, for debugging */
-               signal(SIGQUIT, SIG_DFL);
+               (void) signal(SIGQUIT, SIG_DFL);
 
        /*
 
        /*
-        * Unless prevented by -, -c, -i, -s, or -t, if there
+        * Unless prevented by -c, -i, -s, or -t, if there
         * are remaining arguments the first of them is the name
         * of a shell file from which to read commands.
         */
         * are remaining arguments the first of them is the name
         * of a shell file from which to read commands.
         */
-       if (nofile == 0 && c > 0) {
+       if (nofile == 0 && argc > 0) {
                nofile = open(v[0], 0);
                if (nofile < 0) {
                        child++;                /* So this ... */
                nofile = open(v[0], 0);
                if (nofile < 0) {
                        child++;                /* So this ... */
@@ -213,8 +217,14 @@ main(c, av)
                }
                file = v[0];
                SHIN = dmove(nofile, FSHIN);    /* Replace FSHIN */
                }
                file = v[0];
                SHIN = dmove(nofile, FSHIN);    /* Replace FSHIN */
+               (void) ioctl(SHIN, FIOCLEX, (char *)0);
                prompt = 0;
                prompt = 0;
-               c--, v++;
+               argc--, v++;
+       }
+       if (!batch && (uid != geteuid() || getgid() != getegid())) {
+               errno = EACCES;
+               child++;                        /* So this ... */
+               Perror("csh");                  /* ... doesn't return */
        }
        /*
         * Consider input a tty if it really is or we are interactive.
        }
        /*
         * Consider input a tty if it really is or we are interactive.
@@ -250,18 +260,17 @@ main(c, av)
         */
        shpgrp = getpgrp(0);
        opgrp = tpgrp = -1;
         */
        shpgrp = getpgrp(0);
        opgrp = tpgrp = -1;
-       oldisc = -1;
        if (setintr) {
        if (setintr) {
-               **av = '-';
+               **argv = '-';
                if (!quitit)            /* Wary! */
                if (!quitit)            /* Wary! */
-                       signal(SIGQUIT, SIG_IGN);
-               sigset(SIGINT, pintr);
-               sighold(SIGINT);
-               signal(SIGTERM, SIG_IGN);
+                       (void) signal(SIGQUIT, SIG_IGN);
+               (void) signal(SIGINT, pintr);
+               (void) sigblock(sigmask(SIGINT));
+               (void) signal(SIGTERM, SIG_IGN);
                if (quitit == 0 && arginp == 0) {
                if (quitit == 0 && arginp == 0) {
-                       signal(SIGTSTP, SIG_IGN);
-                       signal(SIGTTIN, SIG_IGN);
-                       signal(SIGTTOU, SIG_IGN);
+                       (void) signal(SIGTSTP, SIG_IGN);
+                       (void) signal(SIGTTIN, SIG_IGN);
+                       (void) signal(SIGTTOU, SIG_IGN);
                        /*
                         * Wait till in foreground, in case someone
                         * stupidly runs
                        /*
                         * Wait till in foreground, in case someone
                         * stupidly runs
@@ -277,31 +286,22 @@ main(c, av)
                        else
                                f = -1;
 retry:
                        else
                                f = -1;
 retry:
-                       if (ioctl(f, TIOCGPGRP, &tpgrp) == 0 && tpgrp != -1) {
+                       if (ioctl(f, TIOCGPGRP, (char *)&tpgrp) == 0 &&
+                           tpgrp != -1) {
                                int ldisc;
                                if (tpgrp != shpgrp) {
                                int ldisc;
                                if (tpgrp != shpgrp) {
-                                       int old = sigsys(SIGTTIN, SIG_DFL);
-                                       kill(0, SIGTTIN);
-                                       sigsys(SIGTTIN, old);
+                                       sig_t old = signal(SIGTTIN, SIG_DFL);
+                                       (void) kill(0, SIGTTIN);
+                                       (void) signal(SIGTTIN, old);
                                        goto retry;
                                }
                                        goto retry;
                                }
-                               if (ioctl(f, TIOCGETD, &oldisc) != 0) 
-                                       goto notty;
-                               if (oldisc != NTTYDISC) {
-#ifdef DEBUG
-                                       printf("Switching to new tty driver...\n");
-#endif DEBUG
-                                       ldisc = NTTYDISC;
-                                       ioctl(f, TIOCSETD, &ldisc);
-                               } else
-                                       oldisc = -1;
                                opgrp = shpgrp;
                                shpgrp = getpid();
                                tpgrp = shpgrp;
                                opgrp = shpgrp;
                                shpgrp = getpid();
                                tpgrp = shpgrp;
-                               ioctl(f, TIOCSPGRP, &shpgrp);
-                               setpgrp(0, shpgrp);
-                               dcopy(f, FSHTTY);
-                               ioctl(FSHTTY, FIOCLEX, 0);
+                               (void) setpgrp(0, shpgrp);
+                               (void) ioctl(f, TIOCSPGRP, (char *)&shpgrp);
+                               (void) ioctl(dcopy(f, FSHTTY), FIOCLEX,
+                                       (char *)0);
                        } else {
 notty:
   printf("Warning: no access to tty; thus no job control in this shell...\n");
                        } else {
 notty:
   printf("Warning: no access to tty; thus no job control in this shell...\n");
@@ -309,7 +309,9 @@ notty:
                        }
                }
        }
                        }
                }
        }
-       sigset(SIGCHLD, pchild);                /* while signals not ready */
+       if (setintr == 0 && parintr == SIG_DFL)
+               setintr++;
+       (void) signal(SIGCHLD, pchild); /* while signals not ready */
 
        /*
         * Set an exit here in case of an interrupt or error reading
 
        /*
         * Set an exit here in case of an interrupt or error reading
@@ -319,14 +321,27 @@ notty:
        haderr = 0;             /* In case second time through */
        if (!fast && reenter == 0) {
                reenter++;
        haderr = 0;             /* In case second time through */
        if (!fast && reenter == 0) {
                reenter++;
+               {
+               int osetintr, omask;
+                       osetintr = setintr;
+                       omask = sigblock(sigmask(SIGINT));
+                       setintr = 0;
+                       srcunit(open(_PATH_DOTCSHRC, O_RDONLY), 0, 0);
+                       if (!fast && !arginp && !onelflg)
+                               dohash();
+                       if (loginsh)
+                               srcunit(open(_PATH_DOTLOGIN, O_RDONLY), 0, 0);
+                       (void)sigsetmask(omask);
+                       setintr = osetintr;
+               }
                /* Will have value("home") here because set fast if don't */
                srccat(value("home"), "/.cshrc");
                /* Will have value("home") here because set fast if don't */
                srccat(value("home"), "/.cshrc");
-               if (!fast && !arginp && !onelflg)
+               if (!fast && !arginp && !onelflg && !havhash)
                        dohash();
                        dohash();
-               dosource(loadhist);
                if (loginsh) {
                        srccat(value("home"), "/.login");
                }
                if (loginsh) {
                        srccat(value("home"), "/.login");
                }
+               dosource(loadhist);
        }
 
        /*
        }
 
        /*
@@ -350,7 +365,7 @@ notty:
         */
        if (loginsh) {
                printf("logout\n");
         */
        if (loginsh) {
                printf("logout\n");
-               close(SHIN);
+               (void) close(SHIN);
                child++;
                goodbye();
        }
                child++;
                goodbye();
        }
@@ -362,19 +377,13 @@ untty()
 {
 
        if (tpgrp > 0) {
 {
 
        if (tpgrp > 0) {
-               setpgrp(0, opgrp);
-               ioctl(FSHTTY, TIOCSPGRP, &opgrp);
-               if (oldisc != -1 && oldisc != NTTYDISC) {
-#ifdef DEBUG
-                       printf("\nReverting to old tty driver...\n");
-#endif DEBUG
-                       ioctl(FSHTTY, TIOCSETD, &oldisc);
-               }
+               (void) setpgrp(0, opgrp);
+               (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&opgrp);
        }
 }
 
 importpath(cp)
        }
 }
 
 importpath(cp)
-char *cp;
+       char *cp;
 {
        register int i = 0;
        register char *dp;
 {
        register int i = 0;
        register char *dp;
@@ -390,7 +399,7 @@ char *cp;
         * There are i+1 directories in the path plus we need
         * room for a zero terminator.
         */
         * There are i+1 directories in the path plus we need
         * room for a zero terminator.
         */
-       pv = (char **) calloc(i+2, sizeof (char **));
+       pv = (char **) calloc((unsigned) (i + 2), sizeof (char **));
        dp = cp;
        i = 0;
        if (*dp)
        dp = cp;
        i = 0;
        if (*dp)
@@ -419,23 +428,20 @@ srccat(cp, dp)
        register char *ep = strspl(cp, dp);
        register int unit = dmove(open(ep, 0), -1);
 
        register char *ep = strspl(cp, dp);
        register int unit = dmove(open(ep, 0), -1);
 
-       /* ioctl(unit, FIOCLEX, NULL); */
+       (void) ioctl(unit, FIOCLEX, (char *)0);
        xfree(ep);
        xfree(ep);
-#ifdef INGRES
-       srcunit(unit, 0, 0);
-#else
-       srcunit(unit, 1, 0);
-#endif
+       srcunit(unit, mflag ? 0 : 1, 0);
 }
 
 /*
 }
 
 /*
- * Source to a unit.  If onlyown it must be our file or our group or
- * we don't chance it. This occurs on ".cshrc"s and the like.
+ * Source to a unit.
+ * This occurs on ".cshrc"s and the like.
  */
  */
+int    insource;
+static void
 srcunit(unit, onlyown, hflg)
        register int unit;
 srcunit(unit, onlyown, hflg)
        register int unit;
-       bool onlyown;
-       bool hflg;
+       bool onlyown, hflg;
 {
        /* We have to push down a lot of state here */
        /* All this could go into a structure */
 {
        /* We have to push down a lot of state here */
        /* All this could go into a structure */
@@ -454,6 +460,7 @@ srcunit(unit, onlyown, hflg)
        /* The (few) real local variables */
        jmp_buf oldexit;
        int reenter;
        /* The (few) real local variables */
        jmp_buf oldexit;
        int reenter;
+       long omask;
 
        if (unit < 0)
                return;
 
        if (unit < 0)
                return;
@@ -462,8 +469,9 @@ srcunit(unit, onlyown, hflg)
        if (onlyown) {
                struct stat stb;
 
        if (onlyown) {
                struct stat stb;
 
-               if (fstat(unit, &stb) < 0 || (stb.st_uid != uid && stb.st_gid != getgid())) {
-                       close(unit);
+               if (fstat(unit, &stb) < 0 ||
+                   (stb.st_uid != uid && stb.st_gid != getgid())) {
+                       (void) close(unit);
                        return;
                }
        }
                        return;
                }
        }
@@ -479,10 +487,11 @@ srcunit(unit, onlyown, hflg)
         * once.  This is less efficient globally on many variable references
         * however.
         */
         * once.  This is less efficient globally on many variable references
         * however.
         */
+       insource = 1;
        getexit(oldexit);
        reenter = 0;
        if (setintr)
        getexit(oldexit);
        reenter = 0;
        if (setintr)
-               sighold(SIGINT);
+               omask = sigblock(sigmask(SIGINT));
        setexit();
        reenter++;
        if (reenter == 1) {
        setexit();
        reenter++;
        if (reenter == 1) {
@@ -501,14 +510,14 @@ srcunit(unit, onlyown, hflg)
                 * we let ourselves be interrupted.
                 */
                if (setintr)
                 * we let ourselves be interrupted.
                 */
                if (setintr)
-                       sigrelse(SIGINT);
+                       (void) sigsetmask(omask);
 #ifdef TELL
                settell();
 #endif
                process(0);             /* 0 -> blow away on errors */
        }
        if (setintr)
 #ifdef TELL
                settell();
 #endif
                process(0);             /* 0 -> blow away on errors */
        }
        if (setintr)
-               sigrelse(SIGINT);
+               (void) sigsetmask(omask);
        if (oSHIN >= 0) {
                register int i;
 
        if (oSHIN >= 0) {
                register int i;
 
@@ -521,7 +530,7 @@ srcunit(unit, onlyown, hflg)
                /* Reset input arena */
                copy((char *)&B, (char *)&saveB, sizeof B);
 
                /* Reset input arena */
                copy((char *)&B, (char *)&saveB, sizeof B);
 
-               close(SHIN), SHIN = oSHIN;
+               (void) close(SHIN), SHIN = oSHIN;
                arginp = oarginp, onelflg = oonelflg;
                evalp = oevalp, evalvec = oevalvec;
                intty = oldintty, whyles = oldwhyl, gointr = ogointr;
                arginp = oarginp, onelflg = oonelflg;
                evalp = oevalp, evalvec = oevalvec;
                intty = oldintty, whyles = oldwhyl, gointr = ogointr;
@@ -540,6 +549,7 @@ srcunit(unit, onlyown, hflg)
         */
        if (reenter >= 2)
                error(NOSTR);
         */
        if (reenter >= 2)
                error(NOSTR);
+       insource = 0;
 }
 
 rechist()
 }
 
 rechist()
@@ -548,29 +558,34 @@ rechist()
        int fp, ftmp, oldidfds;
 
        if (!fast) {
        int fp, ftmp, oldidfds;
 
        if (!fast) {
-               strcpy(buf, value("home"));
-               strcat(buf, "/.history");
-               fp = creat(buf, 0777);
-               if (fp != -1) {
-                       oldidfds = didfds;
-                       didfds = 0;
-                       ftmp = SHOUT;
-                       SHOUT = fp;
-                       dohist(dumphist);
-                       close(fp);
-                       SHOUT = ftmp;
-                       didfds = oldidfds;
-               }
+               if (value("savehist")[0] == '\0')
+                       return;
+               (void) strcpy(buf, value("home"));
+               (void) strcat(buf, "/.history");
+               fp = creat(buf, 0666);
+               if (fp == -1)
+                       return;
+               oldidfds = didfds;
+               didfds = 0;
+               ftmp = SHOUT;
+               SHOUT = fp;
+               (void) strcpy(buf, value("savehist"));
+               dumphist[2] = buf;
+               dohist(dumphist);
+               (void) close(fp);
+               SHOUT = ftmp;
+               didfds = oldidfds;
        }
 }
 
 goodbye()
 {
        if (loginsh) {
        }
 }
 
 goodbye()
 {
        if (loginsh) {
-               signal(SIGQUIT, SIG_IGN);
-               sigset(SIGINT, SIG_IGN);
-               signal(SIGTERM, SIG_IGN);
+               (void) signal(SIGQUIT, SIG_IGN);
+               (void) signal(SIGINT, SIG_IGN);
+               (void) signal(SIGTERM, SIG_IGN);
                setintr = 0;            /* No interrupts after "logout" */
                setintr = 0;            /* No interrupts after "logout" */
+               srcunit(open(_PATH_DOTLOGOUT, O_RDONLY), 0, 0);
                if (adrof("home"))
                        srccat(value("home"), "/.logout");
        }
                if (adrof("home"))
                        srccat(value("home"), "/.logout");
        }
@@ -581,6 +596,9 @@ goodbye()
 exitstat()
 {
 
 exitstat()
 {
 
+#ifdef PROF
+       monitor(0);
+#endif
        /*
         * Note that if STATUS is corrupted (i.e. getn bombs)
         * then error will exit directly because we poke child here.
        /*
         * Note that if STATUS is corrupted (i.e. getn bombs)
         * then error will exit directly because we poke child here.
@@ -607,6 +625,7 @@ char        *jobargv[2] = { "jobs", 0 };
  * and finally go through the normal error mechanism, which
  * gets a chance to make the shell go away.
  */
  * and finally go through the normal error mechanism, which
  * gets a chance to make the shell go away.
  */
+void
 pintr()
 {
        pintr1(1);
 pintr()
 {
        pintr1(1);
@@ -616,9 +635,11 @@ pintr1(wantnl)
        bool wantnl;
 {
        register char **v;
        bool wantnl;
 {
        register char **v;
+       long omask;
 
 
+       omask = sigblock(0L);
        if (setintr) {
        if (setintr) {
-               sigrelse(SIGINT);
+               (void) sigsetmask(omask & ~sigmask(SIGINT));
                if (pjobs) {
                        pjobs = 0;
                        printf("\n");
                if (pjobs) {
                        pjobs = 0;
                        printf("\n");
@@ -626,9 +647,7 @@ pintr1(wantnl)
                        bferr("Interrupted");
                }
        }
                        bferr("Interrupted");
                }
        }
-       if (setintr)
-               sighold(SIGINT);
-       sigrelse(SIGCHLD);
+       (void) sigsetmask(omask & ~sigmask(SIGCHLD));
        draino();
 
        /*
        draino();
 
        /*
@@ -666,9 +685,8 @@ pintr1(wantnl)
 process(catch)
        bool catch;
 {
 process(catch)
        bool catch;
 {
-       register char *cp;
        jmp_buf osetexit;
        jmp_buf osetexit;
-       struct command *t;
+       register struct command *t;
 
        getexit(osetexit);
        for (;;) {
 
        getexit(osetexit);
        for (;;) {
@@ -683,7 +701,7 @@ process(catch)
                 * Interruptible during interactive reads
                 */
                if (setintr)
                 * Interruptible during interactive reads
                 */
                if (setintr)
-                       sigrelse(SIGINT);
+                       (void) sigsetmask(sigblock(0L) & ~sigmask(SIGINT));
 
                /*
                 * For the sake of reset()
 
                /*
                 * For the sake of reset()
@@ -718,7 +736,7 @@ process(catch)
                        chkstop--;
                if (neednote)
                        pnote();
                        chkstop--;
                if (neednote)
                        pnote();
-               if (intty && evalvec == 0) {
+               if (intty && prompt && evalvec == 0) {
                        mailchk();
                        /*
                         * If we are at the end of the input buffer
                        mailchk();
                        /*
                         * If we are at the end of the input buffer
@@ -727,22 +745,7 @@ process(catch)
                         * need or want to prompt.
                         */
                        if (fseekp == feobp)
                         * need or want to prompt.
                         */
                        if (fseekp == feobp)
-                               if (!whyles)
-                                       for (cp = value("prompt"); *cp; cp++)
-                                               if (*cp == HIST)
-                                                       printf("%d", eventno + 1);
-                                               else {
-                                                       if (*cp == '\\' && cp[1] == HIST)
-                                                               cp++;
-                                                       putchar(*cp | QUOTE);
-                                               }
-                               else
-                                       /*
-                                        * Prompt for forward reading loop
-                                        * body content.
-                                        */
-                                       printf("? ");
-                       flush();
+                               printprompt();
                }
                err = 0;
 
                }
                err = 0;
 
@@ -761,7 +764,7 @@ process(catch)
                 * The parser may lose space if interrupted.
                 */
                if (setintr)
                 * The parser may lose space if interrupted.
                 */
                if (setintr)
-                       sighold(SIGINT);
+                       (void) sigblock(sigmask(SIGINT));
 
                /*
                 * Save input text on the history list if 
 
                /*
                 * Save input text on the history list if 
@@ -821,12 +824,13 @@ dosource(t)
                t++;
                hflg++;
        }
                t++;
                hflg++;
        }
-       strcpy(buf, *t);
+       (void) strcpy(buf, *t);
        f = globone(buf);
        u = dmove(open(f, 0), -1);
        xfree(f);
        if (u < 0 && !hflg)
                Perror(f);
        f = globone(buf);
        u = dmove(open(f, 0), -1);
        xfree(f);
        if (u < 0 && !hflg)
                Perror(f);
+       (void) ioctl(u, FIOCLEX, (char *)0);
        srcunit(u, 0, hflg);
 }
 
        srcunit(u, 0, hflg);
 }
 
@@ -851,7 +855,7 @@ mailchk()
        v = adrof("mail");
        if (v == 0)
                return;
        v = adrof("mail");
        if (v == 0)
                return;
-       time(&t);
+       (void) time(&t);
        vp = v->vec;
        cnt = blklen(vp);
        intvl = (cnt && number(*vp)) ? (--cnt, getn(*vp++)) : MAILINTVL;
        vp = v->vec;
        cnt = blklen(vp);
        intvl = (cnt && number(*vp)) ? (--cnt, getn(*vp++)) : MAILINTVL;
@@ -862,7 +866,7 @@ mailchk()
        for (; *vp; vp++) {
                if (stat(*vp, &stb) < 0)
                        continue;
        for (; *vp; vp++) {
                if (stat(*vp, &stb) < 0)
                        continue;
-               new = stb.st_mtime > time0;
+               new = stb.st_mtime > time0.tv_sec;
                if (stb.st_size == 0 || stb.st_atime > stb.st_mtime ||
                    (stb.st_atime < chktim && stb.st_mtime < chktim) ||
                    loginsh && !new)
                if (stb.st_size == 0 || stb.st_atime > stb.st_mtime ||
                    (stb.st_atime < chktim && stb.st_mtime < chktim) ||
                    loginsh && !new)
@@ -889,7 +893,7 @@ gethdir(home)
 
        if (pp == 0)
                return (1);
 
        if (pp == 0)
                return (1);
-       strcpy(home, pp->pw_dir);
+       (void) strcpy(home, pp->pw_dir);
        return (0);
 }
 
        return (0);
 }
 
@@ -900,23 +904,44 @@ gethdir(home)
 initdesc()
 {
 
 initdesc()
 {
 
-       didcch = 0;                     /* Havent closed for child */
        didfds = 0;                     /* 0, 1, 2 aren't set up */
        didfds = 0;                     /* 0, 1, 2 aren't set up */
-       SHIN = dcopy(0, FSHIN);
-       SHOUT = dcopy(1, FSHOUT);
-       SHDIAG = dcopy(2, FSHDIAG);
-       OLDSTD = dcopy(SHIN, FOLDSTD);
+       (void) ioctl(SHIN = dcopy(0, FSHIN), FIOCLEX, (char *)0);
+       (void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, (char *)0);
+       (void) ioctl(SHDIAG = dcopy(2, FSHDIAG), FIOCLEX, (char *)0);
+       (void) ioctl(OLDSTD = dcopy(SHIN, FOLDSTD), FIOCLEX, (char *)0);
        closem();
 }
 
        closem();
 }
 
+#ifdef PROF
+done(i)
+#else
 exit(i)
 exit(i)
+#endif
        int i;
 {
 
        untty();
        int i;
 {
 
        untty();
-#ifdef PROF
-       IEH3exit(i);
-#else
        _exit(i);
        _exit(i);
-#endif
+}
+
+printprompt()
+{
+       register char *cp;
+
+       if (!whyles) {
+               for (cp = value("prompt"); *cp; cp++)
+                       if (*cp == HIST)
+                               printf("%d", eventno + 1);
+                       else {
+                               if (*cp == '\\' && cp[1] == HIST)
+                                       cp++;
+                               cshputchar(*cp | QUOTE);
+                       }
+       } else
+               /* 
+                * Prompt for forward reading loop
+                * body content.
+                */
+               printf("? ");
+       flush();
 }
 }