home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / unix / question / 10846 < prev    next >
Encoding:
Text File  |  1992-09-08  |  6.0 KB  |  231 lines

  1. Path: sparky!uunet!auspex-gw!guy
  2. From: guy@Auspex.COM (Guy Harris)
  3. Newsgroups: comp.unix.questions
  4. Subject: Re: portable replacement for pty ?
  5. Message-ID: <14514@auspex-gw.auspex.com>
  6. Date: 9 Sep 92 07:02:20 GMT
  7. References: <1992Sep9.014215.25693@informix.com>
  8. Sender: news@auspex-gw.auspex.com
  9. Organization: Auspex Systems, Santa Clara
  10. Lines: 216
  11. Nntp-Posting-Host: auspex-gw.auspex.com
  12. Nntp-Posting-Host: auspex.auspex.com
  13. Originator: news@auspex-gw.Auspex.COM
  14.  
  15. >After some searching around various
  16. >SVR3 and SVR4 machines, there is a "ptmx" set of devices that seems to
  17. >parallel the ttys (like ptys would), but although they all have ptmx in place,
  18. >ptmx doesn't show up in man pages on *any* of these.  I've looked at AT&T SVR4
  19. >R2.1,
  20.  
  21. In the grand System V "the manual page you want is often in a manual
  22. other than the obvious one" tradition (how many people not already aware
  23. of that little SV peculiarity would expect the tty "ioctl"s to be
  24. documented in the *System Administrator's* Reference Manual?), the SVR4
  25. pseudo-tty mechanism is documented in manual pages at the back of
  26.  
  27.     UNIX(R) System V Release 4 Programmer's Guide: STREAMS
  28.  
  29. as well as in the "STREAMS-based Pseudo-Terminal Subsystem" section of
  30. that document.
  31.  
  32. The mechanism that showed up in some SVR3 systems is a predecessor of
  33. that mechanism; it has some of the stuff in there, but not all of it.
  34.  
  35. No, it's not portable, but then "UNIX pseudo-tty" and "portable"
  36. generally don't belong in close proximity; here, for example, is the
  37. "allocate a pseudo-tty" code from the Andrew Toolkit.  It doesn't yet
  38. have support for SVR4 pseudo-ttys, but just dealing with HP-UX, various
  39. flavors of AIX, IRIX, and some other systems has already complicated it
  40. (and that's just the "allocate a pseudo-tty" routine; for big fun, try
  41. checking out the "tm" application).
  42.  
  43. The moral of the story is "wrap access to pseudo-ttys in a wrapper
  44. library, with different implementations on different UNIX flavors":
  45.  
  46. /* ********************************************************************** *\
  47.  *         Copyright IBM Corporation 1988,1991 - All Rights Reserved      *
  48.  *        For full copyright information see:'andrew/config/COPYRITE'     *
  49. \* ********************************************************************** */
  50. static char rcsid[]="$Header: /afs/andrew.cmu.edu/itc/src/projects/andrew/overhead/util/lib/RCS/getpty.c,v 1.11 1991/09/12 17:26:20 bobg Exp $";
  51.  
  52. /*
  53. This module contains the routine getpty.  It returns file descriptors
  54. for a pty. It takes two pointers to ints and returns the file decriptors.
  55. It returns TRUE if it succeeds.
  56. */
  57.  
  58. #include <andrewos.h>
  59.  
  60. #ifdef SGI_4D_ENV
  61. #include <sys/stat.h>
  62. #include <sys/sysmacros.h>
  63. #endif
  64.  
  65. #include <fcntl.h>
  66. #include <sys/param.h>
  67.  
  68. #ifdef hpux
  69. #include <sys/bsdtty.h>
  70. #include <sys/ptyio.h>
  71. #endif /* hpux */
  72.  
  73. #ifndef    SGI_4D_ENV  /* for bug in makedepend */
  74. #if SY_AIX221
  75. #include <sys/ioctl.h>
  76. #include <sys/devinfo.h>
  77. #include <sys/pty.h>
  78. #include <sys/tty.h>
  79. #endif /* SY_AIX221 */
  80. #endif
  81.  
  82.  
  83. #ifdef hpux
  84. #define MASTER_PTY_PREFIX "/dev/ptym/pty"
  85. #define SLAVE_PTY_PREFIX "/dev/pty/tty"
  86. #define MAX_PTYS 64
  87. #endif /* HPUX */
  88.  
  89. #if SY_AIX221
  90. #define MASTER_PTY_PREFIX "/dev/ptc"
  91. #define SLAVE_PTY_PREFIX "/dev/pts"
  92. #define MAX_PTYS 256
  93. #endif /* SY_AIX221 */
  94.  
  95. #ifndef MASTER_PTY_PREFIX
  96. #define MASTER_PTY_PREFIX "/dev/pty"
  97. #define SLAVE_PTY_PREFIX "/dev/tty"
  98. #define MAX_PTYS 256
  99. #endif
  100.  
  101. #if POSIX_ENV
  102. #define OPEN_FLAGS O_RDWR|O_NOCTTY
  103. #else
  104. #define OPEN_FLAGS O_RDWR
  105. #endif
  106.  
  107. static char *GetPtyNumberString(num)
  108. int num;
  109. {
  110. static char ptyNum[10];
  111.  
  112. #if SY_AIX221 || defined (SGI_4D_ENV)
  113.     sprintf(ptyNum, "%d", num);
  114. #else /* SY_AIX221 */
  115.     ptyNum[0] = 'p' + (num/16);
  116.     ptyNum[1] = "0123456789abcdef"[num%16];
  117.     ptyNum[2] = '\0';
  118. #endif /* SY_AIX221 */
  119.     return ptyNum;
  120. }
  121.  
  122. int GetPtyandName(masterFD, slaveFD,name,len)
  123. int *masterFD;
  124. int *slaveFD;
  125. char *name;
  126. int len;
  127. {
  128. #if SY_AIX31
  129.     /* AIX 3.1 lets us open a single device "/dev/ptc" which
  130.      * finds an available pty for us.  ttyname() returns the
  131.      * name of that device.
  132.      */
  133.     int master;
  134.     int slave;
  135.     char *ptyname;
  136.  
  137.     if ((master = open("/dev/ptc", OPEN_FLAGS)) < 0)
  138.     return 0;    /* none left */
  139.     if ((ptyname = ttyname(master)) == NULL) {
  140.     /* major weirdness */
  141.     close(master);
  142.     return 0;
  143.     }
  144.     if ((slave = open(ptyname, OPEN_FLAGS)) < 0) {
  145.     /* more weirdness */
  146.     close(master);
  147.     return 0;
  148.     }
  149.     if (name != NULL)
  150.         strncpy(name,ptyname,len);
  151.     if (masterFD != NULL)
  152.     *masterFD = master;
  153.     if (slaveFD != NULL)
  154.     *slaveFD = slave;
  155.     return 1;
  156. #else
  157. #ifdef SGI_4D_ENV
  158.     int master;
  159.     int slave;
  160.     char ptyname[30];
  161.     struct stat stBuf;
  162.  
  163.     do {
  164.     if ((master = open("/dev/ptc", OPEN_FLAGS)) < 0)
  165.         return 0;    /* none left */
  166.     if (fstat(master, &stBuf) < 0) {
  167.         return 0;
  168.     }
  169.     sprintf(ptyname, "/dev/ttyq%d", minor(stBuf.st_rdev));
  170.     slave = open(ptyname, OPEN_FLAGS);
  171.     } while (slave < 0);
  172.  
  173.     if (name != NULL)
  174.         strncpy(name,ptyname,len);
  175.     if (masterFD != NULL)
  176.     *masterFD = master;
  177.     if (slaveFD != NULL)
  178.     *slaveFD = slave;
  179.     return 1;
  180.  
  181. #else
  182.     int PtyNumber = 0;
  183.     char ptcname[MAXPATHLEN];
  184.     char ptyname[MAXPATHLEN];
  185.     char *ptyNum;
  186.     int master;
  187.     int slave;
  188.  
  189.     while (PtyNumber++ < MAX_PTYS) {
  190.     ptyNum = GetPtyNumberString(PtyNumber);
  191.     strcpy(ptcname, MASTER_PTY_PREFIX);
  192.     strcat(ptcname, ptyNum);
  193.     if ((master = open (ptcname, OPEN_FLAGS)) >= 0) {
  194. #if SY_AIX221
  195.     {
  196.             /* Be sure this pty really is available. */
  197.         int value;
  198.  
  199.         if ((value = ioctl(master, PTYSTATUS, 0)) == -1 || (value & 0xffff) != 0 || (value >> 16) != 1)  {
  200.         close(master);
  201.         continue;
  202.         }
  203.     }
  204. #endif /* SY_AIX221 */
  205.         strcpy(ptyname, SLAVE_PTY_PREFIX);
  206.         strcat(ptyname, ptyNum);
  207.         if(name != NULL) strncpy(name,ptyname,len);
  208.         if ((slave = open(ptyname, OPEN_FLAGS)) >= 0)  {
  209.         if (masterFD != NULL)
  210.             *masterFD = master;
  211.         if (slaveFD != NULL)
  212.             *slaveFD = slave;
  213.         return 1;
  214.         }
  215.         else
  216.         close(master);
  217.     }
  218.     }
  219.  
  220.     return 0;
  221. #endif /* SGI_4D_ENV */
  222. #endif /* SY_AIX31 */
  223. }
  224.  
  225. int GetPty(masterFD, slaveFD)
  226. int *masterFD;
  227. int *slaveFD;
  228. {
  229.     return GetPtyandName(masterFD, slaveFD,NULL,0);
  230. }
  231.