+
+/*
+ * 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()
+{
+ int oovno;
+
+ signal(SIGEMT, onemt);
+ oovno = _ovno;
+ /* 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);
+ exit(0);
+ }
+ if (setexit() == 0) {
+ if (preserve()) {
+ cleanup(1);
+ exit(0);
+ }
+ }
+ 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 = fork();
+ if (pid < 0)
+ return (0);
+ if (pid == 0) {
+ close(0);
+ dup(tfile);
+ execl(EXPRESERVE, "expreserve", (char *) 0);
+ exit(1);
+ }
+ waitfor();
+ if (rpid == pid && status == 0)
+ return (1);
+ return (0);
+}
+
+#ifndef V6
+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;
+ int omask;
+ 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);
+ setty(f);
+ if (!inopen)
+ error(0);
+ else {
+ if (ioctl(0, TIOCGWINSZ, &win) >= 0)
+ if (win.ws_row != winsz.ws_row ||
+ win.ws_col != winsz.ws_col)
+ winch();
+ if (vcnt < 0) {
+ vcnt = -vcnt;
+ if (state == VISUAL)
+ vclear();
+ else if (state == CRTOPEN)
+ vcnt = 0;
+ }
+ vdirty(0, LINES);
+ vrepaint(cursor);
+ }
+}
+#endif