BSD 4_3 release
[unix-history] / usr / src / ucb / script.c
index 7fa59d0..fc518f5 100644 (file)
@@ -1,6 +1,18 @@
+/*
+ * 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
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)script.c    4.5 (Berkeley) 83/07/02";
-#endif
+static char sccsid[] = "@(#)script.c   5.4 (Berkeley) 11/13/85";
+#endif not lint
 
 /*
  * script
 
 /*
  * script
@@ -12,6 +24,7 @@ static char *sccsid = "@(#)script.c   4.5 (Berkeley) 83/07/02";
 #include <sys/ioctl.h>
 #include <sgtty.h>
 #include <sys/time.h>
 #include <sys/ioctl.h>
 #include <sgtty.h>
 #include <sys/time.h>
+#include <sys/file.h>
 
 char   *getenv();
 char   *ctime();
 
 char   *getenv();
 char   *ctime();
@@ -20,12 +33,14 @@ FILE        *fscript;
 int    master;
 int    slave;
 int    child;
 int    master;
 int    slave;
 int    child;
+int    subchild;
 char   *fname = "typescript";
 int    finish();
 
 struct sgttyb b;
 struct tchars tc;
 struct ltchars lc;
 char   *fname = "typescript";
 int    finish();
 
 struct sgttyb b;
 struct tchars tc;
 struct ltchars lc;
+struct winsize win;
 int    lb;
 int    l;
 char   *line = "/dev/ptyXX";
 int    lb;
 int    l;
 char   *line = "/dev/ptyXX";
@@ -35,7 +50,6 @@ main(argc, argv)
        int argc;
        char *argv[];
 {
        int argc;
        char *argv[];
 {
-       int f;
 
        shell = getenv("SHELL");
        if (shell == 0)
 
        shell = getenv("SHELL");
        if (shell == 0)
@@ -72,12 +86,12 @@ main(argc, argv)
                fail();
        }
        if (child == 0) {
                fail();
        }
        if (child == 0) {
-               f = fork();
-               if (f < 0) {
+               subchild = child = fork();
+               if (child < 0) {
                        perror("fork");
                        fail();
                }
                        perror("fork");
                        fail();
                }
-               if (f)
+               if (child)
                        dooutput();
                else
                        doshell();
                        dooutput();
                else
                        doshell();
@@ -101,10 +115,15 @@ doinput()
 finish()
 {
        union wait status;
 finish()
 {
        union wait status;
+       register int pid;
+       register int die = 0;
 
 
-       if (wait3(&status, WNOHANG, 0) != child)
-               return;
-       done();
+       while ((pid = wait3(&status, WNOHANG, 0)) > 0)
+               if (pid == child)
+                       die = 1;
+
+       if (die)
+               done();
 }
 
 dooutput()
 }
 
 dooutput()
@@ -123,28 +142,24 @@ dooutput()
                (void) write(1, obuf, cc);
                (void) fwrite(obuf, 1, cc, fscript);
        }
                (void) write(1, obuf, cc);
                (void) fwrite(obuf, 1, cc, fscript);
        }
-       tvec = time((time_t *)0);
-       fprintf(fscript,"\nscript done on %s", ctime(&tvec));
-       (void) fclose(fscript);
-       (void) close(master);
-       exit(0);
+       done();
 }
 
 doshell()
 {
        int t;
 
 }
 
 doshell()
 {
        int t;
 
-       t = open("/dev/tty", 2);
+       t = open("/dev/tty", O_RDWR);
        if (t >= 0) {
        if (t >= 0) {
-               ioctl(t, TIOCNOTTY, (char *)0);
+               (void) ioctl(t, TIOCNOTTY, (char *)0);
                (void) close(t);
        }
        getslave();
        (void) close(master);
        (void) fclose(fscript);
                (void) close(t);
        }
        getslave();
        (void) close(master);
        (void) fclose(fscript);
-       dup2(slave, 0);
-       dup2(slave, 1);
-       dup2(slave, 2);
+       (void) dup2(slave, 0);
+       (void) dup2(slave, 1);
+       (void) dup2(slave, 2);
        (void) close(slave);
        execl(shell, "sh", "-i", 0);
        perror(shell);
        (void) close(slave);
        execl(shell, "sh", "-i", 0);
        perror(shell);
@@ -158,7 +173,7 @@ fixtty()
        sbuf = b;
        sbuf.sg_flags |= RAW;
        sbuf.sg_flags &= ~ECHO;
        sbuf = b;
        sbuf.sg_flags |= RAW;
        sbuf.sg_flags &= ~ECHO;
-       ioctl(0, TIOCSETP, (char *)&sbuf);
+       (void) ioctl(0, TIOCSETP, (char *)&sbuf);
 }
 
 fail()
 }
 
 fail()
@@ -170,33 +185,52 @@ fail()
 
 done()
 {
 
 done()
 {
+       time_t tvec;
 
 
-       ioctl(0, TIOCSETP, (char *)&b);
-       printf("Script done, file is %s\n", fname);
+       if (subchild) {
+               tvec = time((time_t *)0);
+               fprintf(fscript,"\nscript done on %s", ctime(&tvec));
+               (void) fclose(fscript);
+               (void) close(master);
+       } else {
+               (void) ioctl(0, TIOCSETP, (char *)&b);
+               printf("Script done, file is %s\n", fname);
+       }
        exit(0);
 }
 
 getmaster()
 {
        exit(0);
 }
 
 getmaster()
 {
-       char c;
+       char *pty, *bank, *cp;
        struct stat stb;
        struct stat stb;
-       int i;
 
 
-       for (c = 'p'; c <= 's'; c++) {
-               line[strlen("/dev/pty")] = c;
-               line[strlen("/dev/ptyp")] = '0';
+       pty = &line[strlen("/dev/ptyp")];
+       for (bank = "pqrs"; *bank; bank++) {
+               line[strlen("/dev/pty")] = *bank;
+               *pty = '0';
                if (stat(line, &stb) < 0)
                        break;
                if (stat(line, &stb) < 0)
                        break;
-               for (i = 0; i < 16; i++) {
-                       line[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
-                       master = open(line, 2);
+               for (cp = "0123456789abcdef"; *cp; cp++) {
+                       *pty = *cp;
+                       master = open(line, O_RDWR);
                        if (master >= 0) {
                        if (master >= 0) {
-                               ioctl(0, TIOCGETP, (char *)&b);
-                               ioctl(0, TIOCGETC, (char *)&tc);
-                               ioctl(0, TIOCGETD, (char *)&l);
-                               ioctl(0, TIOCGLTC, (char *)&lc);
-                               ioctl(0, TIOCLGET, (char *)&lb);
-                               return;
+                               char *tp = &line[strlen("/dev/")];
+                               int ok;
+
+                               /* verify slave side is usable */
+                               *tp = 't';
+                               ok = access(line, R_OK|W_OK) == 0;
+                               *tp = 'p';
+                               if (ok) {
+                                   (void) ioctl(0, TIOCGETP, (char *)&b);
+                                   (void) ioctl(0, TIOCGETC, (char *)&tc);
+                                   (void) ioctl(0, TIOCGETD, (char *)&l);
+                                   (void) ioctl(0, TIOCGLTC, (char *)&lc);
+                                   (void) ioctl(0, TIOCLGET, (char *)&lb);
+                                   (void) ioctl(0, TIOCGWINSZ, (char *)&win);
+                                       return;
+                               }
+                               (void) close(master);
                        }
                }
        }
                        }
                }
        }
@@ -208,14 +242,15 @@ getslave()
 {
 
        line[strlen("/dev/")] = 't';
 {
 
        line[strlen("/dev/")] = 't';
-       slave = open(line, 2);
+       slave = open(line, O_RDWR);
        if (slave < 0) {
                perror(line);
                fail();
        }
        if (slave < 0) {
                perror(line);
                fail();
        }
-       ioctl(slave, TIOCSETP, (char *)&b);
-       ioctl(slave, TIOCSETC, (char *)&tc);
-       ioctl(slave, TIOCSLTC, (char *)&lc);
-       ioctl(slave, TIOCLSET, (char *)&lb);
-       ioctl(slave, TIOCSETD, (char *)&l);
+       (void) ioctl(slave, TIOCSETP, (char *)&b);
+       (void) ioctl(slave, TIOCSETC, (char *)&tc);
+       (void) ioctl(slave, TIOCSLTC, (char *)&lc);
+       (void) ioctl(slave, TIOCLSET, (char *)&lb);
+       (void) ioctl(slave, TIOCSETD, (char *)&l);
+       (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
 }
 }