[BACK]Return to pty.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/Attic/pty.c between version 1.5 and 1.6

version 1.5, 1999/10/16 20:57:52 version 1.6, 1999/11/23 22:25:54
Line 30 
Line 30 
   
 /* Allocates and opens a pty.  Returns 0 if no pty could be allocated,  /* Allocates and opens a pty.  Returns 0 if no pty could be allocated,
    or nonzero if a pty was successfully allocated.  On success, open file     or nonzero if a pty was successfully allocated.  On success, open file
    descriptors for the pty and tty sides and the name of the tty side are     descriptors for the pty and tty sides and the name of the tty side are
    returned (the buffer must be able to hold at least 64 characters). */     returned (the buffer must be able to hold at least 64 characters). */
   
 int pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)  int
   pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
 {  {
 #ifdef HAVE_OPENPTY  #ifdef HAVE_OPENPTY
           /* openpty(3) exists in OSF/1 and some other os'es */
           int i;
   
   /* openpty(3) exists in OSF/1 and some other os'es */          i = openpty(ptyfd, ttyfd, namebuf, NULL, NULL);
           if (i < 0) {
   int i;                  error("openpty: %.100s", strerror(errno));
                   return 0;
   i = openpty(ptyfd, ttyfd, namebuf, NULL, NULL);          }
           return 1;
   if (i < 0)  
     {  
       error("openpty: %.100s", strerror(errno));  
       return 0;  
     }  
   
   return 1;  
   
 #else /* HAVE_OPENPTY */  #else /* HAVE_OPENPTY */
 #ifdef HAVE__GETPTY  #ifdef HAVE__GETPTY
           /* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates
              more pty's automagically when needed */
           char *slave;
   
   /* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more          slave = _getpty(ptyfd, O_RDWR, 0622, 0);
      pty's automagically when needed */          if (slave == NULL) {
                   error("_getpty: %.100s", strerror(errno));
   char *slave;                  return 0;
           }
   slave = _getpty(ptyfd, O_RDWR, 0622, 0);          strcpy(namebuf, slave);
   if (slave == NULL)          /* Open the slave side. */
     {          *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
       error("_getpty: %.100s", strerror(errno));          if (*ttyfd < 0) {
       return 0;                  error("%.200s: %.100s", namebuf, strerror(errno));
     }                  close(*ptyfd);
   strcpy(namebuf, slave);                  return 0;
   /* Open the slave side. */          }
   *ttyfd = open(namebuf, O_RDWR|O_NOCTTY);          return 1;
   if (*ttyfd < 0)  
     {  
       error("%.200s: %.100s", namebuf, strerror(errno));  
       close(*ptyfd);  
       return 0;  
     }  
   return 1;  
   
 #else /* HAVE__GETPTY */  #else /* HAVE__GETPTY */
 #ifdef HAVE_DEV_PTMX  #ifdef HAVE_DEV_PTMX
   /* This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3 also has          /* This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
      bsd-style ptys, but they simply do not work.) */             also has bsd-style ptys, but they simply do not work.) */
           int ptm;
           char *pts;
   
   int ptm;          ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
   char *pts;          if (ptm < 0) {
                   error("/dev/ptmx: %.100s", strerror(errno));
   ptm = open("/dev/ptmx", O_RDWR|O_NOCTTY);                  return 0;
   if (ptm < 0)          }
     {          if (grantpt(ptm) < 0) {
       error("/dev/ptmx: %.100s", strerror(errno));                  error("grantpt: %.100s", strerror(errno));
       return 0;                  return 0;
     }          }
   if (grantpt(ptm) < 0)          if (unlockpt(ptm) < 0) {
     {                  error("unlockpt: %.100s", strerror(errno));
       error("grantpt: %.100s", strerror(errno));                  return 0;
       return 0;          }
     }          pts = ptsname(ptm);
   if (unlockpt(ptm) < 0)          if (pts == NULL)
     {                  error("Slave pty side name could not be obtained.");
       error("unlockpt: %.100s", strerror(errno));          strcpy(namebuf, pts);
       return 0;          *ptyfd = ptm;
     }  
   pts = ptsname(ptm);  
   if (pts == NULL)  
     error("Slave pty side name could not be obtained.");  
   strcpy(namebuf, pts);  
   *ptyfd = ptm;  
   
   /* Open the slave side. */          /* Open the slave side. */
   *ttyfd = open(namebuf, O_RDWR|O_NOCTTY);          *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
   if (*ttyfd < 0)          if (*ttyfd < 0) {
     {                  error("%.100s: %.100s", namebuf, strerror(errno));
       error("%.100s: %.100s", namebuf, strerror(errno));                  close(*ptyfd);
       close(*ptyfd);                  return 0;
       return 0;          }
     }          /* Push the appropriate streams modules, as described in Solaris
   /* Push the appropriate streams modules, as described in Solaris pts(7). */             pts(7). */
   if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)          if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
     error("ioctl I_PUSH ptem: %.100s", strerror(errno));                  error("ioctl I_PUSH ptem: %.100s", strerror(errno));
   if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)          if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
     error("ioctl I_PUSH ldterm: %.100s", strerror(errno));                  error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
   if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)          if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
     error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));                  error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
   return 1;          return 1;
   
 #else /* HAVE_DEV_PTMX */  #else /* HAVE_DEV_PTMX */
 #ifdef HAVE_DEV_PTS_AND_PTC  #ifdef HAVE_DEV_PTS_AND_PTC
           /* AIX-style pty code. */
           const char *name;
   
   /* AIX-style pty code. */          *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
           if (*ptyfd < 0) {
   const char *name;                  error("Could not open /dev/ptc: %.100s", strerror(errno));
                   return 0;
   *ptyfd = open("/dev/ptc", O_RDWR|O_NOCTTY);          }
   if (*ptyfd < 0)          name = ttyname(*ptyfd);
     {          if (!name)
       error("Could not open /dev/ptc: %.100s", strerror(errno));                  fatal("Open of /dev/ptc returns device for which ttyname fails.");
       return 0;          strcpy(namebuf, name);
     }          *ttyfd = open(name, O_RDWR | O_NOCTTY);
   name = ttyname(*ptyfd);          if (*ttyfd < 0) {
   if (!name)                  error("Could not open pty slave side %.100s: %.100s",
     fatal("Open of /dev/ptc returns device for which ttyname fails.");                        name, strerror(errno));
   strcpy(namebuf, name);                  close(*ptyfd);
   *ttyfd = open(name, O_RDWR|O_NOCTTY);                  return 0;
   if (*ttyfd < 0)          }
     {          return 1;
       error("Could not open pty slave side %.100s: %.100s",  
             name, strerror(errno));  
       close(*ptyfd);  
       return 0;  
     }  
   return 1;  
   
 #else /* HAVE_DEV_PTS_AND_PTC */  #else /* HAVE_DEV_PTS_AND_PTC */
   /* BSD-style pty code. */          /* BSD-style pty code. */
           char buf[64];
           int i;
           const char *ptymajors =
           "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
           const char *ptyminors = "0123456789abcdef";
           int num_minors = strlen(ptyminors);
           int num_ptys = strlen(ptymajors) * num_minors;
   
   char buf[64];          for (i = 0; i < num_ptys; i++) {
   int i;                  snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
   const char *ptymajors =                           ptyminors[i % num_minors]);
     "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";                  *ptyfd = open(buf, O_RDWR | O_NOCTTY);
   const char *ptyminors = "0123456789abcdef";                  if (*ptyfd < 0)
   int num_minors = strlen(ptyminors);                          continue;
   int num_ptys = strlen(ptymajors) * num_minors;                  snprintf(namebuf, sizeof buf, "/dev/tty%c%c", ptymajors[i / num_minors],
                            ptyminors[i % num_minors]);
   
   for (i = 0; i < num_ptys; i++)                  /* Open the slave side. */
     {                  *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
       snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],                  if (*ttyfd < 0) {
               ptyminors[i % num_minors]);                          error("%.100s: %.100s", namebuf, strerror(errno));
       *ptyfd = open(buf, O_RDWR|O_NOCTTY);                          close(*ptyfd);
       if (*ptyfd < 0)                          return 0;
         continue;                  }
       snprintf(namebuf, sizeof buf, "/dev/tty%c%c", ptymajors[i / num_minors],                  return 1;
               ptyminors[i % num_minors]);  
   
       /* Open the slave side. */  
       *ttyfd = open(namebuf, O_RDWR|O_NOCTTY);  
       if (*ttyfd < 0)  
         {  
           error("%.100s: %.100s", namebuf, strerror(errno));  
           close(*ptyfd);  
           return 0;  
         }          }
       return 1;          return 0;
     }  
   return 0;  
 #endif /* HAVE_DEV_PTS_AND_PTC */  #endif /* HAVE_DEV_PTS_AND_PTC */
 #endif /* HAVE_DEV_PTMX */  #endif /* HAVE_DEV_PTMX */
 #endif /* HAVE__GETPTY */  #endif /* HAVE__GETPTY */
 #endif /* HAVE_OPENPTY */  #endif /* HAVE_OPENPTY */
 }  }
   
 /* Releases the tty.  Its ownership is returned to root, and permissions to  /* Releases the tty.  Its ownership is returned to root, and permissions to 0666. */
    0666. */  
   
 void pty_release(const char *ttyname)  void
   pty_release(const char *ttyname)
 {  {
   if (chown(ttyname, (uid_t)0, (gid_t)0) < 0)          if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0)
     debug("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno));                  debug("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno));
   if (chmod(ttyname, (mode_t)0666) < 0)          if (chmod(ttyname, (mode_t) 0666) < 0)
     debug("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno));                  debug("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno));
 }  }
   
 /* Makes the tty the processes controlling tty and sets it to sane modes. */  /* Makes the tty the processes controlling tty and sets it to sane modes. */
   
 void pty_make_controlling_tty(int *ttyfd, const char *ttyname)  void
   pty_make_controlling_tty(int *ttyfd, const char *ttyname)
 {  {
   int fd;          int fd;
   
   /* First disconnect from the old controlling tty. */          /* First disconnect from the old controlling tty. */
 #ifdef TIOCNOTTY  #ifdef TIOCNOTTY
   fd = open("/dev/tty", O_RDWR|O_NOCTTY);          fd = open("/dev/tty", O_RDWR | O_NOCTTY);
   if (fd >= 0)          if (fd >= 0) {
     {                  (void) ioctl(fd, TIOCNOTTY, NULL);
       (void)ioctl(fd, TIOCNOTTY, NULL);                  close(fd);
       close(fd);          }
     }  
 #endif /* TIOCNOTTY */  #endif /* TIOCNOTTY */
   if (setsid() < 0)          if (setsid() < 0)
     error("setsid: %.100s", strerror(errno));                  error("setsid: %.100s", strerror(errno));
   
   /* Verify that we are successfully disconnected from the controlling tty. */  
   fd = open("/dev/tty", O_RDWR|O_NOCTTY);  
   if (fd >= 0)  
     {  
       error("Failed to disconnect from controlling tty.");  
       close(fd);  
     }  
   
   /* Make it our controlling tty. */          /* Verify that we are successfully disconnected from the
              controlling tty. */
           fd = open("/dev/tty", O_RDWR | O_NOCTTY);
           if (fd >= 0) {
                   error("Failed to disconnect from controlling tty.");
                   close(fd);
           }
           /* Make it our controlling tty. */
 #ifdef TIOCSCTTY  #ifdef TIOCSCTTY
   debug("Setting controlling tty using TIOCSCTTY.");          debug("Setting controlling tty using TIOCSCTTY.");
   /* We ignore errors from this, because HPSUX defines TIOCSCTTY, but returns          /* We ignore errors from this, because HPSUX defines TIOCSCTTY,
      EINVAL with these arguments, and there is absolutely no documentation. */             but returns EINVAL with these arguments, and there is
   ioctl(*ttyfd, TIOCSCTTY, NULL);             absolutely no documentation. */
           ioctl(*ttyfd, TIOCSCTTY, NULL);
 #endif /* TIOCSCTTY */  #endif /* TIOCSCTTY */
   fd = open(ttyname, O_RDWR);          fd = open(ttyname, O_RDWR);
   if (fd < 0)          if (fd < 0)
     error("%.100s: %.100s", ttyname, strerror(errno));                  error("%.100s: %.100s", ttyname, strerror(errno));
   else          else
     close(fd);                  close(fd);
   
   /* Verify that we now have a controlling tty. */          /* Verify that we now have a controlling tty. */
   fd = open("/dev/tty", O_WRONLY);          fd = open("/dev/tty", O_WRONLY);
   if (fd < 0)          if (fd < 0)
     error("open /dev/tty failed - could not set controlling tty: %.100s",                  error("open /dev/tty failed - could not set controlling tty: %.100s",
           strerror(errno));                        strerror(errno));
   else          else {
     {                  close(fd);
       close(fd);          }
     }  
 }  }
   
 /* Changes the window size associated with the pty. */  /* Changes the window size associated with the pty. */
   
 void pty_change_window_size(int ptyfd, int row, int col,  void
                             int xpixel, int ypixel)  pty_change_window_size(int ptyfd, int row, int col,
                          int xpixel, int ypixel)
 {  {
   struct winsize w;          struct winsize w;
   w.ws_row = row;          w.ws_row = row;
   w.ws_col = col;          w.ws_col = col;
   w.ws_xpixel = xpixel;          w.ws_xpixel = xpixel;
   w.ws_ypixel = ypixel;          w.ws_ypixel = ypixel;
   (void)ioctl(ptyfd, TIOCSWINSZ, &w);          (void) ioctl(ptyfd, TIOCSWINSZ, &w);
 }  }
   

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6