[comp.sources.bugs] OFFICIAL pty patch 3---SunOS 4.1, Ultrix 4.0, Convex UNIX 8.0

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (11/04/90)

Submitted-by: Dan Bernstein <brnstnd@kramden.acf.nyu.edu>
Archive-name: pty/patch03
Archive-date: Sun Nov  4 04:39:27 GMT 1990
Priority: MEDIUM

All sites should apply this patch. However, the only effect of this
patch is to increase portability, so sites with a working pty do not
need to recompile the program.

This is mainly a stopgap POSIX patch. You should add the following to
CCOPTS to compile pty on the following systems:

SunOS 4.1: -DSIGRET_TYPE=void -DPOSIX -DDEFICIENT_POSIX
Ultrix 4.0: -DSIGRET_TYPE=void -DPOSIX -DDEFICIENT_POSIX -YPOSIX -DPTYGROUP=5
Convex UNIX 8.0: -DSIGRET_TYPE=void -DPOSIX -DDEFICIENT_POSIX -DNO_FDPASSING

File descriptor passing does not work under this Convex UNIX release,
for unknown reasons.

Thanks to Seth Robertson for his help.


This patch includes the following:

Patches to various files to kludge some POSIX support.

Patches to master.c to handle a possible bug given certain systems'
definitions of FD_ISSET.

A dumb usleep.c so that everyone can take advantage of USLEEP.

Updates to CHANGES and README.


*** pty.c.old	Mon Oct 22 19:20:20 1990
--- pty.c	Mon Oct 22 20:12:43 1990
***************
*** 305,311 ****
--- 305,315 ----
   else
    {
     if ((fdtty = tty_getctrl()) == -1)
+ #ifndef DEFICIENT_POSIX
       fatalerr(2,"pty: fatal: cannot find control terminal; try -d?\n");
+ #else
+      fatalerr(2,"pty: fatal: cannot find control terminal; try -d? Is the real tty open?\n");
+ #endif
     if (tty_getmodes(fdtty,&tmotty) == -1)
       fatalerr(3,"pty: fatal: cannot get current tty modes\n");
       /* XXX: is there a way to recover more gracefully? */
***************
*** 349,354 ****
--- 353,367 ----
     /* After this, the signaller will handle tty modes. */
    }
   else if (f == 0)
+   {
+ #ifdef POSIX
+    (void) setsid(); /* cannot fail, we are not a group leader after fork */
+    /* XXX: but should test and deatherrp(10) anyway */
+    /* XXX: should integrate this with tty_dissoc() */
+    /* XXX: should exterminate the blight of kernel cttys and POSIX sessions */
+    if ((f = open(fnsty,O_RDWR)) != -1) /* XXX: shameful variable reuse */
+      (void) close(f);
+ #endif
     if ((f = fork()) == -1)
      {
       (void) kill(pid,SIGTERM); /*XXX*/
***************
*** 367,372 ****
--- 380,386 ----
           fatal(1);
       master(fnsty,f);
      }
+   }
   else
    {
     (void) setreuid(uid,euid);
*** slave.c.old	Mon Oct 22 19:20:18 1990
--- slave.c	Mon Oct 22 19:21:59 1990
***************
*** 18,24 ****
--- 18,26 ----
  
   if (fdtty > -1)
    {
+ #ifndef POSIX
     (void) tty_dissoc(fdtty); /* must succeed */
+ #endif
     (void) close(fdtty);
    }
   if (fdre > -1)
*** tty.c.old	Mon Oct 22 19:16:20 1990
--- tty.c	Mon Oct 22 20:47:37 1990
***************
*** 6,11 ****
--- 6,17 ----
  #include "err.h"
  #include "tty.h"
  
+ #ifdef DEFICIENT_POSIX
+ #include <sys/types.h> /*XXX*/
+ #include <sys/stat.h> /*XXX*/
+ #include "misc.h"
+ #endif
+ 
  #define generic GENERIC *
  
  static int ioc(fd,req,arg) /* non-interruptable ioctl */
***************
*** 27,32 ****
--- 33,71 ----
   int dummy;
  
  #define ISTTY(f) (ioc(f,(unsigned long) TIOCGPGRP,(generic) &dummy) == 0)
+ 
+ #ifdef POSIX
+ #ifdef DEFICIENT_POSIX
+ /* If you understand why this section of code is here, you'll understand
+ why I say: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUUUUUUUUUUUUUUUUUUGGGGGGGGHHHH!
+ */
+   {
+    int fddevtty;
+    char *fnrealtty;
+    int fdrealtty;
+    struct stat stdevtty;
+    struct stat st;
+    int i;
+ 
+    if ((fddevtty = open("/dev/tty",O_RDWR)) == -1)
+      return -1;
+    if (!(fnrealtty = real_ttyname(fddevtty)))
+      return -1; /* XXX: we hope this doesn't happen */
+    if ((fdrealtty = open(fnrealtty,O_RDWR)) == -1)
+      return -1; /* gaargh! could be EXCL, or any number of other things */
+    if (fstat(fddevtty,&stdevtty) == -1)
+      return -1;
+    (void) close(fddevtty);
+    for (i = getdtablesize();i >= 0;i--)
+      if (i != fdrealtty)
+        if (fstat(i,&st) != -1)
+          if ((st.st_dev == stdevtty.st_dev) && (st.st_ino == stdevtty.st_ino))
+ 	   (void) dup2(fdrealtty,i); /* kaboom */
+    return fdrealtty; /*XXX*/
+    (void) close(fdrealtty);
+   }
+ #endif
+ #endif
  
   if (ISTTY(3))
     return 3;
*** CHANGES.old	Wed Oct 24 22:53:43 1990
--- CHANGES	Wed Oct 24 22:57:19 1990
***************
*** 1,3 ****
--- 1,9 ----
+ 10/24/90: Patch 3, stopgap POSIX patch.
+ 10/24/90: Updated README. INSTALL/config.h should also be updated for POSIX.
+ 10/24/90: Fixed potential FD_ISSET bug: fd may not be range checked.
+ 10/23/90: SunOS 4.1 kludges seem to do the job under Ultrix 4.0. Yay.
+ 10/22/90: Working SunOS 4.1 patch. Thanks to Seth Robertson for his help.
+ 
  10/19/90: Patch 2. Next patch will be a stopgap POSIX patch.
  10/19/90: Mentioned part07 in README.
  10/19/90: Made a separate part07 with correct control characters in the files.
*** master.c.old	Wed Oct 24 22:52:48 1990
--- master.c	Wed Oct 24 22:53:36 1990
***************
*** 627,633 ****
       sig_startring(); /* blocking? never heard of it */
  #endif
  
!      if (FD_ISSET(fdin,&rfds))
        {
         /* ptybuflen must be smaller than ptybufsiz. */
         r = read(fdin,ptybuf + ptybuflen,ptybufsiz - ptybuflen);
--- 627,633 ----
       sig_startring(); /* blocking? never heard of it */
  #endif
  
!      if ((fdin != -1) && (FD_ISSET(fdin,&rfds)))
        {
         /* ptybuflen must be smaller than ptybufsiz. */
         r = read(fdin,ptybuf + ptybuflen,ptybufsiz - ptybuflen);
***************
*** 662,668 ****
         else
  	 outbuflen += r;
        }
!      if (FD_ISSET(fdout,&wfds))
        {
         r = write(fdout,outbuf,outbuflen);
         if (r == -1)
--- 662,668 ----
         else
  	 outbuflen += r;
        }
!      if ((fdout != -1) && (FD_ISSET(fdout,&wfds)))
        {
         r = write(fdout,outbuf,outbuflen);
         if (r == -1)
*** README.old	Wed Oct 24 23:00:21 1990
--- README	Wed Oct 24 23:11:30 1990
***************
*** 16,27 ****
  power of a pty port, please let the author know.
  
  
! pty does not work under POSIX-based machines (such as SunOS 4.1), even
! when it works perfectly under their predecessors (such as SunOS 4.0.3).
! The main problem is POSIX's introduction of sessions and the way it
! kills a non-orphaned process in an orphaned process group. There are
! other incompatibilities, mostly minor but some (like accounting and
! setuid problems) important. The author is working on a POSIX port.
  
  If files {INSTALL,util/{write,wall,lock,script.tidy}}.bad do not exist,
  some beeps and backspaces may be missing. A new part07 to the pty
--- 16,35 ----
  power of a pty port, please let the author know.
  
  
! POSIX-based machines (such as SunOS 4.1) are not backwards compatible
! with their predecessors (such as SunOS 4.0.3). The main headaches are
! POSIX's introduction of sessions and the way it kills a non-orphaned
! process in an orphaned process group. There are other incompatibilities,
! mostly minor but some (like accounting and setuid problems) important.
! Current systems such as SunOS 4.1 and Ultrix 4.0 exacerbate the problems
! by handling job control incorrectly. The author is working on a thorough
! POSIX rewrite.
! 
! This version of pty includes stopgap patches so that you can run it
! under SunOS 4.1 and Ultrix 4.0. To enable the patches, define -DPOSIX
! and -DDEFICIENT_POSIX in CCOPTS in the Makefile. Under Ultrix 4.0, also
! define -YPOSIX. Make sure to do this now---the configuration scripts
! have not yet been updated, so you won't see this notice again.
  
  If files {INSTALL,util/{write,wall,lock,script.tidy}}.bad do not exist,
  some beeps and backspaces may be missing. A new part07 to the pty
*** usleep.c.old	Wed Oct 24 23:31:17 1990
--- usleep.c	Wed Oct 24 23:31:23 1990
***************
*** 0 ****
--- 1,13 ----
+ #include <sys/types.h>
+ #include <sys/time.h>
+ 
+ usleep(d)
+ int d;
+ {
+  struct timeval tv;
+ 
+  tv.tv_usec = d;
+  tv.tv_sec = 0;
+ 
+  select(1,0,0,0,&tv);
+ }