added depend label
[unix-history] / usr / src / usr.bin / ex / ex_subr.c
index bf76ec3..d513862 100644 (file)
@@ -1,5 +1,13 @@
-/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_subr.c   4.2 %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 = "@(#)ex_subr.c   7.11 (Berkeley) %G%";
+#endif not lint
+
 #include "ex.h"
 #include "ex_re.h"
 #include "ex_tty.h"
 #include "ex.h"
 #include "ex_re.h"
 #include "ex_tty.h"
@@ -66,7 +74,7 @@ comment()
        register int c;
 
        do {
        register int c;
 
        do {
-               c = getchar();
+               c = ex_getchar();
        } while (c != '\n' && c != EOF);
        if (c == EOF)
                ungetchar(c);
        } while (c != '\n' && c != EOF);
        if (c == EOF)
                ungetchar(c);
@@ -87,7 +95,6 @@ copyw(to, from, size)
        register line *from, *to;
        register int size;
 {
        register line *from, *to;
        register int size;
 {
-
        if (size > 0)
                do
                        *to++ = *from++;
        if (size > 0)
                do
                        *to++ = *from++;
@@ -191,7 +198,7 @@ getn(cp)
 
 ignnEOF()
 {
 
 ignnEOF()
 {
-       register int c = getchar();
+       register int c = ex_getchar();
 
        if (c == EOF)
                ungetchar(c);
 
        if (c == EOF)
                ungetchar(c);
@@ -243,12 +250,12 @@ killcnt(cnt)
        }
        if (!notable(cnt))
                return;
        }
        if (!notable(cnt))
                return;
-       printf("%d lines", cnt);
+       ex_printf("%d lines", cnt);
        if (value(TERSE) == 0) {
        if (value(TERSE) == 0) {
-               printf(" %c%s", Command[0] | ' ', Command + 1);
+               ex_printf(" %c%s", Command[0] | ' ', Command + 1);
                if (Command[strlen(Command) - 1] != 'e')
                if (Command[strlen(Command) - 1] != 'e')
-                       putchar('e');
-               putchar('d');
+                       ex_putchar('e');
+               ex_putchar('d');
        }
        putNFL();
 }
        }
        putNFL();
 }
@@ -334,7 +341,7 @@ mesg(str)
 
 /*VARARGS2*/
 merror(seekpt, i)
 
 /*VARARGS2*/
 merror(seekpt, i)
-#ifdef VMUNIX
+#ifndef EXSTRINGS
        char *seekpt;
 #else
 # ifdef lint
        char *seekpt;
 #else
 # ifdef lint
@@ -352,17 +359,17 @@ merror(seekpt, i)
        merror1(seekpt);
        if (*cp == '\n')
                putnl(), cp++;
        merror1(seekpt);
        if (*cp == '\n')
                putnl(), cp++;
-       if (inopen && CE)
+       if (inopen > 0 && CE)
                vclreol();
        if (SO && SE)
                putpad(SO);
                vclreol();
        if (SO && SE)
                putpad(SO);
-       printf(mesg(cp), i);
+       ex_printf(mesg(cp), i);
        if (SO && SE)
                putpad(SE);
 }
 
 merror1(seekpt)
        if (SO && SE)
                putpad(SE);
 }
 
 merror1(seekpt)
-#ifdef VMUNIX
+#ifndef EXSTRINGS
        char *seekpt;
 #else
 # ifdef lint
        char *seekpt;
 #else
 # ifdef lint
@@ -373,7 +380,7 @@ merror1(seekpt)
 #endif
 {
 
 #endif
 {
 
-#ifdef VMUNIX
+#ifndef EXSTRINGS
        strcpy(linebuf, seekpt);
 #else
        lseek(erfile, (long) seekpt, 0);
        strcpy(linebuf, seekpt);
 #else
        lseek(erfile, (long) seekpt, 0);
@@ -384,11 +391,20 @@ merror1(seekpt)
 
 morelines()
 {
 
 morelines()
 {
+#ifdef UNIX_SBRK
+       char *sbrk();
 
        if ((int) sbrk(1024 * sizeof (line)) == -1)
                return (-1);
        endcore += 1024;
        return (0);
 
        if ((int) sbrk(1024 * sizeof (line)) == -1)
                return (-1);
        endcore += 1024;
        return (0);
+#else
+       /*
+        * We can never be guaranteed that we can get more memory
+        * beyond "endcore".  So we just punt every time.
+        */
+       return -1;
+#endif
 }
 
 nonzero()
 }
 
 nonzero()
@@ -439,7 +455,7 @@ netchange(i)
        }
        if (!notable(i))
                return;
        }
        if (!notable(i))
                return;
-       printf(mesg("%d %slines@in file after %s"), i, cp, Command);
+       ex_printf(mesg("%d %slines@in file after %s"), i, cp, Command);
        putNFL();
 }
 
        putNFL();
 }
 
@@ -493,7 +509,7 @@ qcolumn(lim, gp)
                lim[1] = x;
        if (gp)
                while (*gp)
                lim[1] = x;
        if (gp)
                while (*gp)
-                       putchar(*gp++);
+                       ex_putchar(*gp++);
        Outchar = OO;
        return (vcntcol);
 }
        Outchar = OO;
        return (vcntcol);
 }
@@ -541,7 +557,11 @@ save(a1, a2)
        more = (a2 - a1 + 1) - (unddol - dol);
        while (more > (endcore - truedol))
                if (morelines() < 0)
        more = (a2 - a1 + 1) - (unddol - dol);
        while (more > (endcore - truedol))
                if (morelines() < 0)
-                       error("Out of memory@saving lines for undo - try using ed or re");
+#ifdef UNIX_SBRK
+                       error("Out of memory@saving lines for undo - try using ed");
+#else
+                       error("Out of memory@saving lines for undo - try increasing linelimit");
+#endif
        if (more)
                (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
                    (truedol - unddol));
        if (more)
                (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
                    (truedol - unddol));
@@ -576,7 +596,7 @@ span()
        return (addr2 - addr1 + 1);
 }
 
        return (addr2 - addr1 + 1);
 }
 
-sync()
+ex_sync()
 {
 
        chng = 0;
 {
 
        chng = 0;
@@ -619,62 +639,6 @@ smerror(seekpt, cp)
                putpad(SE);
 }
 
                putpad(SE);
 }
 
-#define        std_nerrs (sizeof std_errlist / sizeof std_errlist[0])
-
-#define        error(i)        i
-
-#ifdef lint
-char   *std_errlist[] = {
-#else
-# ifdef VMUNIX
-char   *std_errlist[] = {
-# else
-short  std_errlist[] = {
-# endif
-#endif
-       error("Error 0"),
-       error("Not super-user"),
-       error("No such file or directory"),
-       error("No such process"),
-       error("Interrupted system call"),
-       error("Physical I/O error"),
-       error("No such device or address"),
-       error("Argument list too long"),
-       error("Exec format error"),
-       error("Bad file number"),
-       error("No children"),
-       error("No more processes"),
-       error("Not enough core"),
-       error("Permission denied"),
-       error("Bad address"),
-       error("Block device required"),
-       error("Mount device busy"),
-       error("File exists"),
-       error("Cross-device link"),
-       error("No such device"),
-       error("Not a directory"),
-       error("Is a directory"),
-       error("Invalid argument"),
-       error("File table overflow"),
-       error("Too many open files"),
-       error("Not a typewriter"),
-       error("Text file busy"),
-       error("File too large"),
-       error("No space left on device"),
-       error("Illegal seek"),
-       error("Read-only file system"),
-       error("Too many links"),
-       error("Broken pipe")
-#ifndef QUOTA
-       , error("Math argument")
-       , error("Result too large")
-#else
-       , error("Quota exceeded")
-#endif
-};
-
-#undef error
-
 char *
 strend(cp)
        register char *cp;
 char *
 strend(cp)
        register char *cp;
@@ -695,12 +659,26 @@ strcLIN(dp)
 syserror()
 {
        register int e = errno;
 syserror()
 {
        register int e = errno;
+#ifndef        vms
+       extern int sys_nerr;
+       extern char *sys_errlist[];
+#else
+       extern noshare int sys_nerr;
+       extern noshare char *sys_errlist[];
+#endif
 
        dirtcnt = 0;
 
        dirtcnt = 0;
-       putchar(' ');
-       if (e >= 0 && errno <= std_nerrs)
-               error(std_errlist[e]);
+       ex_putchar(' ');
+       if (e >= 0 && e <= sys_nerr)
+               error(sys_errlist[e]);
        else
        else
+#ifdef vms
+               if (e == EVMSERR) {
+                       error("VMS system error %d", vaxc$errno);
+                       perror("vmserror");
+               }
+               else
+#endif
                error("System error %d", e);
 }
 
                error("System error %d", e);
 }
 
@@ -733,7 +711,7 @@ vfindcol(i)
        Outchar = qcount;
        ignore(qcolumn(linebuf - 1, NOSTR));
        for (cp = linebuf; *cp && vcntcol < i; cp++)
        Outchar = qcount;
        ignore(qcolumn(linebuf - 1, NOSTR));
        for (cp = linebuf; *cp && vcntcol < i; cp++)
-               putchar(*cp);
+               ex_putchar(*cp);
        if (cp != linebuf)
                cp--;
        Outchar = OO;
        if (cp != linebuf)
                cp--;
        Outchar = OO;
@@ -806,3 +784,183 @@ markit(addr)
        if (addr != dot && addr >= one && addr <= dol)
                markDOT();
 }
        if (addr != dot && addr >= one && addr <= dol)
                markDOT();
 }
+
+/*
+ * The following code is defensive programming against a bug in the
+ * pdp-11 overlay implementation.  Sometimes it goes nuts and asks
+ * for an overlay with some garbage number, which generates an emt
+ * trap.  This is a less than elegant solution, but it is somewhat
+ * better than core dumping and losing your work, leaving your tty
+ * in a weird state, etc.
+ */
+int _ovno;
+onemt()
+{
+       signal(SIGEMT, onemt);
+       /* 2 and 3 are valid on 11/40 type vi, so */
+       if (_ovno < 0 || _ovno > 3)
+               _ovno = 0;
+       error("emt trap, _ovno is %d @ - try again");
+}
+
+/*
+ * When a hangup occurs our actions are similar to a preserve
+ * command.  If the buffer has not been [Modified], then we do
+ * nothing but remove the temporary files and exit.
+ * Otherwise, we sync the temp file and then attempt a preserve.
+ * If the preserve succeeds, we unlink our temp files.
+ * If the preserve fails, we leave the temp files as they are
+ * as they are a backup even without preservation if they
+ * are not removed.
+ */
+onhup()
+{
+
+       /*
+        * USG tty driver can send multiple HUP's!!
+        */
+       signal(SIGINT, SIG_IGN);
+       signal(SIGHUP, SIG_IGN);
+       if (chng == 0) {
+               cleanup(1);
+               ex_exit(0);
+       }
+       if (setexit() == 0) {
+               if (preserve()) {
+                       cleanup(1);
+                       ex_exit(0);
+               }
+       }
+       ex_exit(1);
+}
+
+/*
+ * An interrupt occurred.  Drain any output which
+ * is still in the output buffering pipeline.
+ * Catch interrupts again.  Unless we are in visual
+ * reset the output state (out of -nl mode, e.g).
+ * Then like a normal error (with the \n before Interrupt
+ * suppressed in visual mode).
+ */
+onintr()
+{
+
+#ifndef CBREAK
+       signal(SIGINT, onintr);
+#else
+       signal(SIGINT, inopen ? vintr : onintr);
+#endif
+       alarm(0);       /* in case we were called from map */
+       draino();
+       if (!inopen) {
+               pstop();
+               setlastchar('\n');
+#ifdef CBREAK
+       }
+#else
+       } else
+               vraw();
+#endif
+       error("\nInterrupt" + inopen);
+}
+
+/*
+ * If we are interruptible, enable interrupts again.
+ * In some critical sections we turn interrupts off,
+ * but not very often.
+ */
+setrupt()
+{
+
+       if (ruptible) {
+#ifndef CBREAK
+               signal(SIGINT, onintr);
+#else
+               signal(SIGINT, inopen ? vintr : onintr);
+#endif
+#ifdef SIGTSTP
+               if (dosusp)
+                       signal(SIGTSTP, onsusp);
+#endif
+       }
+}
+
+preserve()
+{
+
+#ifdef VMUNIX
+       tflush();
+#endif
+       synctmp();
+       pid = vfork();
+       if (pid < 0)
+               return (0);
+       if (pid == 0) {
+               close(0);
+               dup(tfile);
+               execl(EXPRESERVE, "expreserve", (char *) 0);
+               ex_exit(1);
+       }
+       waitfor();
+       if (rpid == pid && status == 0)
+               return (1);
+       return (0);
+}
+
+#ifndef V6
+ex_exit(i)
+       int i;
+{
+
+# ifdef TRACE
+       if (trace)
+               fclose(trace);
+# endif
+       _exit(i);
+}
+#endif
+
+#ifdef SIGTSTP
+/*
+ * We have just gotten a susp.  Suspend and prepare to resume.
+ */
+onsusp()
+{
+       ttymode f;
+       struct winsize win;
+
+       f = setty(normf);
+       vnfl();
+       putpad(TE);
+       flush();
+
+       (void) sigsetmask(0);
+       signal(SIGTSTP, SIG_DFL);
+       kill(0, SIGTSTP);
+
+       /* the pc stops here */
+
+       signal(SIGTSTP, onsusp);
+       vcontin(0);
+       ignore(setty(f));
+       if (!inopen)
+               error((char *) 0);
+       else {
+#ifdef TIOCGWINSZ
+               if (ioctl(0, TIOCGWINSZ, &win) >= 0)
+                       if (win.ws_row != winsz.ws_row ||
+                           win.ws_col != winsz.ws_col)
+                               winch();
+#endif
+               if (vcnt < 0) {
+                       vcnt = -vcnt;
+                       if (state == VISUAL)
+                               vclear();
+                       else if (state == CRTOPEN)
+                               vcnt = 0;
+               }
+               vdirty(0, LINES);
+               vrepaint(cursor);
+       }
+}
+#endif