use high precision time calls
[unix-history] / usr / src / bin / csh / csh.c
index fccedc2..74370a9 100644 (file)
@@ -1,4 +1,4 @@
-static char *sccsid = "@(#)csh.c 4.3 %G%";
+static char *sccsid = "@(#)csh.c 4.10 %G%";
 
 #include "sh.h"
 #include <sys/ioctl.h>
 
 #include "sh.h"
 #include <sys/ioctl.h>
@@ -13,7 +13,8 @@ static        char *sccsid = "@(#)csh.c 4.3 %G%";
  */
 
 char   *pathlist[] =   { ".", "/usr/ucb", "/bin", "/usr/bin", 0 };
  */
 
 char   *pathlist[] =   { ".", "/usr/ucb", "/bin", "/usr/bin", 0 };
-char   *dumphist[] =   { "history", "-c", "+1000" };
+char   *dumphist[] =   { "history", "-h", 0, 0 };
+char   *loadhist[] =   { "source", "-h", "~/.history", 0 };
 char   HIST = '!';
 char   HISTSUB = '^';
 bool   nofile;
 char   HIST = '!';
 char   HISTSUB = '^';
 bool   nofile;
@@ -113,6 +114,11 @@ main(c, av)
        sigset(SIGINT, parintr);                        /* ... restore */
        parterm = signal(SIGTERM, SIG_IGN);     /* parents terminability */
        signal(SIGTERM, parterm);                       /* ... restore */
        sigset(SIGINT, parintr);                        /* ... restore */
        parterm = signal(SIGTERM, SIG_IGN);     /* parents terminability */
        signal(SIGTERM, parterm);                       /* ... restore */
+       if (loginsh) {
+               signal(SIGHUP, phup);           /* exit processing on HUP */
+               signal(SIGXCPU, phup);          /* ...and on XCPU */
+               signal(SIGXFSZ, phup);          /* ...and on XFSZ */
+       }
 
        /*
         * Process the arguments.
 
        /*
         * Process the arguments.
@@ -285,7 +291,9 @@ retry:
                                if (ioctl(f, TIOCGETD, &oldisc) != 0) 
                                        goto notty;
                                if (oldisc != NTTYDISC) {
                                if (ioctl(f, TIOCGETD, &oldisc) != 0) 
                                        goto notty;
                                if (oldisc != NTTYDISC) {
-                       printf("Switching to new tty driver...\n");
+#ifdef DEBUG
+                                       printf("Switching to new tty driver...\n");
+#endif DEBUG
                                        ldisc = NTTYDISC;
                                        ioctl(f, TIOCSETD, &ldisc);
                                } else
                                        ldisc = NTTYDISC;
                                        ioctl(f, TIOCSETD, &ldisc);
                                } else
@@ -304,6 +312,8 @@ notty:
                        }
                }
        }
                        }
                }
        }
+       if (setintr == 0 && parintr == SIG_DFL)
+               setintr++;
        sigset(SIGCHLD, pchild);                /* while signals not ready */
 
        /*
        sigset(SIGCHLD, pchild);                /* while signals not ready */
 
        /*
@@ -318,11 +328,9 @@ notty:
                srccat(value("home"), "/.cshrc");
                if (!fast && !arginp && !onelflg)
                        dohash();
                srccat(value("home"), "/.cshrc");
                if (!fast && !arginp && !onelflg)
                        dohash();
+               dosource(loadhist);
                if (loginsh) {
                        srccat(value("home"), "/.login");
                if (loginsh) {
                        srccat(value("home"), "/.login");
-                       enterhist = 1;
-                       srccat(value("home"), "/.history");
-                       enterhist = 0;
                }
        }
 
                }
        }
 
@@ -351,6 +359,7 @@ notty:
                child++;
                goodbye();
        }
                child++;
                goodbye();
        }
+       rechist();
        exitstat();
 }
 
        exitstat();
 }
 
@@ -361,7 +370,9 @@ untty()
                setpgrp(0, opgrp);
                ioctl(FSHTTY, TIOCSPGRP, &opgrp);
                if (oldisc != -1 && oldisc != NTTYDISC) {
                setpgrp(0, opgrp);
                ioctl(FSHTTY, TIOCSPGRP, &opgrp);
                if (oldisc != -1 && oldisc != NTTYDISC) {
+#ifdef DEBUG
                        printf("\nReverting to old tty driver...\n");
                        printf("\nReverting to old tty driver...\n");
+#endif DEBUG
                        ioctl(FSHTTY, TIOCSETD, &oldisc);
                }
        }
                        ioctl(FSHTTY, TIOCSETD, &oldisc);
                }
        }
@@ -416,9 +427,9 @@ srccat(cp, dp)
        /* ioctl(unit, FIOCLEX, NULL); */
        xfree(ep);
 #ifdef INGRES
        /* ioctl(unit, FIOCLEX, NULL); */
        xfree(ep);
 #ifdef INGRES
-       srcunit(unit, 0);
+       srcunit(unit, 0, 0);
 #else
 #else
-       srcunit(unit, 1);
+       srcunit(unit, 1, 0);
 #endif
 }
 
 #endif
 }
 
@@ -426,9 +437,10 @@ srccat(cp, dp)
  * 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.  If onlyown it must be our file or our group or
  * we don't chance it. This occurs on ".cshrc"s and the like.
  */
-srcunit(unit, onlyown)
+srcunit(unit, onlyown, hflg)
        register int unit;
        bool onlyown;
        register int unit;
        bool onlyown;
+       bool 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 */
@@ -437,6 +449,8 @@ srcunit(unit, onlyown)
        char *ogointr = gointr, *oarginp = arginp;
        char *oevalp = evalp, **oevalvec = evalvec;
        int oonelflg = onelflg;
        char *ogointr = gointr, *oarginp = arginp;
        char *oevalp = evalp, **oevalvec = evalvec;
        int oonelflg = onelflg;
+       bool oenterhist = enterhist;
+       char OHIST = HIST;
 #ifdef TELL
        bool otell = cantell;
 #endif
 #ifdef TELL
        bool otell = cantell;
 #endif
@@ -484,6 +498,9 @@ srcunit(unit, onlyown)
                oSHIN = SHIN, SHIN = unit, arginp = 0, onelflg = 0;
                intty = isatty(SHIN), whyles = 0, gointr = 0;
                evalvec = 0; evalp = 0;
                oSHIN = SHIN, SHIN = unit, arginp = 0, onelflg = 0;
                intty = isatty(SHIN), whyles = 0, gointr = 0;
                evalvec = 0; evalp = 0;
+               enterhist = hflg;
+               if (enterhist)
+                       HIST = '\0';
                /*
                 * Now if we are allowing commands to be interrupted,
                 * we let ourselves be interrupted.
                /*
                 * Now if we are allowing commands to be interrupted,
                 * we let ourselves be interrupted.
@@ -513,6 +530,9 @@ srcunit(unit, onlyown)
                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;
+               if (enterhist)
+                       HIST = OHIST;
+               enterhist = oenterhist;
 #ifdef TELL
                cantell = otell;
 #endif
 #ifdef TELL
                cantell = otell;
 #endif
@@ -527,25 +547,35 @@ srcunit(unit, onlyown)
                error(NOSTR);
 }
 
                error(NOSTR);
 }
 
-goodbye()
+rechist()
 {
        char buf[BUFSIZ];
        int fp, ftmp, oldidfds;
 
 {
        char buf[BUFSIZ];
        int fp, ftmp, oldidfds;
 
-       if (loginsh) {
+       if (!fast) {
+               if (value("savehist")[0] == '\0')
+                       return;
                strcpy(buf, value("home"));
                strcat(buf, "/.history");
                fp = creat(buf, 0777);
                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 (fp == -1)
+                       return;
+               oldidfds = didfds;
+               didfds = 0;
+               ftmp = SHOUT;
+               SHOUT = fp;
+               strcpy(buf, value("savehist"));
+               dumphist[2] = buf;
+               dohist(dumphist);
+               close(fp);
+               SHOUT = ftmp;
+               didfds = oldidfds;
+       }
+}
+
+goodbye()
+{
+       if (loginsh) {
                signal(SIGQUIT, SIG_IGN);
                sigset(SIGINT, SIG_IGN);
                signal(SIGTERM, SIG_IGN);
                signal(SIGQUIT, SIG_IGN);
                sigset(SIGINT, SIG_IGN);
                signal(SIGTERM, SIG_IGN);
@@ -553,6 +583,7 @@ goodbye()
                if (adrof("home"))
                        srccat(value("home"), "/.logout");
        }
                if (adrof("home"))
                        srccat(value("home"), "/.logout");
        }
+       rechist();
        exitstat();
 }
 
        exitstat();
 }
 
@@ -568,6 +599,15 @@ exitstat()
        exit(getn(value("status")));
 }
 
        exit(getn(value("status")));
 }
 
+/*
+ * in the event of a HUP we want to save the history
+ */
+phup()
+{
+       rechist();
+       exit(1);
+}
+
 char   *jobargv[2] = { "jobs", 0 };
 /*
  * Catch an interrupt, e.g. during lexical input.
 char   *jobargv[2] = { "jobs", 0 };
 /*
  * Catch an interrupt, e.g. during lexical input.
@@ -719,7 +759,8 @@ process(catch)
                 * Echo not only on VERBOSE, but also with history expansion.
                 * If there is a lexical error then we forego history echo.
                 */
                 * Echo not only on VERBOSE, but also with history expansion.
                 * If there is a lexical error then we forego history echo.
                 */
-               if (lex(&paraml) && !err && intty || adrof("verbose")) {
+               if (lex(&paraml) && !err && intty ||
+                   adrof("verbose")) {
                        haderr = 1;
                        prlex(&paraml);
                        haderr = 0;
                        haderr = 1;
                        prlex(&paraml);
                        haderr = 0;
@@ -741,9 +782,10 @@ process(catch)
                        savehist(&paraml);
 
                /*
                        savehist(&paraml);
 
                /*
-                * Print lexical error messages.
+                * Print lexical error messages, except when sourcing
+                * history lists.
                 */
                 */
-               if (err)
+               if (!enterhist && err)
                        error(err);
 
                /*
                        error(err);
 
                /*
@@ -780,14 +822,21 @@ dosource(t)
 {
        register char *f;
        register int u;
 {
        register char *f;
        register int u;
+       bool hflg = 0;
+       char buf[BUFSIZ];
 
        t++;
 
        t++;
-       f = globone(*t);
+       if (*t && eq(*t, "-h")) {
+               t++;
+               hflg++;
+       }
+       strcpy(buf, *t);
+       f = globone(buf);
        u = dmove(open(f, 0), -1);
        xfree(f);
        u = dmove(open(f, 0), -1);
        xfree(f);
-       if (u < 0)
+       if (u < 0 && !hflg)
                Perror(f);
                Perror(f);
-       srcunit(u, 0);
+       srcunit(u, 0, hflg);
 }
 
 /*
 }
 
 /*
@@ -822,7 +871,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)