Annotation of embedaddon/readline/examples/rlfe/pty.c, revision 1.1.1.1

1.1       misho       1: /* Copyright (c) 1993-2002
                      2:  *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
                      3:  *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
                      4:  * Copyright (c) 1987 Oliver Laumann
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify
                      7:  * it under the terms of the GNU General Public License as published by
                      8:  * the Free Software Foundation; either version 2, or (at your option)
                      9:  * any later version.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:  * GNU General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License
                     17:  * along with this program (see the file COPYING); if not, write to the
                     18:  * Free Software Foundation, Inc.,
                     19:  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
                     20:  *
                     21:  ****************************************************************
                     22:  */
                     23: #include "config.h"
                     24: 
                     25: #include <sys/types.h>
                     26: #include <sys/stat.h>
                     27: #include <fcntl.h>
                     28: #include <signal.h>
                     29: 
                     30: #include <unistd.h>
                     31: 
                     32: #include "screen.h"
                     33: 
                     34: #ifndef sun
                     35: # include <sys/ioctl.h>
                     36: #endif
                     37: 
                     38: /* for solaris 2.1, Unixware (SVR4.2) and possibly others */
                     39: #if defined (HAVE_SVR4_PTYS) && defined (HAVE_SYS_STROPTS_H)
                     40: # include <sys/stropts.h>
                     41: #endif
                     42: 
                     43: #if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL)
                     44: # include <sys/ttold.h>
                     45: #endif
                     46: 
                     47: #ifdef ISC
                     48: # include <sys/tty.h>
                     49: # include <sys/sioctl.h>
                     50: # include <sys/pty.h>
                     51: #endif
                     52: 
                     53: #ifdef sgi
                     54: # include <sys/sysmacros.h>
                     55: #endif /* sgi */
                     56: 
                     57: #include "extern.h"
                     58: 
                     59: /*
                     60:  * if no PTYRANGE[01] is in the config file, we pick a default
                     61:  */
                     62: #ifndef PTYRANGE0
                     63: # define PTYRANGE0 "qpr"
                     64: #endif
                     65: #ifndef PTYRANGE1
                     66: # define PTYRANGE1 "0123456789abcdef"
                     67: #endif
                     68: 
                     69: /* SVR4 pseudo ttys don't seem to work with SCO-5 */
                     70: #ifdef M_UNIX
                     71: # undef HAVE_SVR4_PTYS
                     72: #endif
                     73: 
                     74: extern int eff_uid;
                     75: 
                     76: /* used for opening a new pty-pair: */
                     77: static char PtyName[32], TtyName[32];
                     78: 
                     79: #if !(defined(sequent) || defined(_SEQUENT_) || defined(HAVE_SVR4_PTYS))
                     80: # ifdef hpux
                     81: static char PtyProto[] = "/dev/ptym/ptyXY";
                     82: static char TtyProto[] = "/dev/pty/ttyXY";
                     83: # else
                     84: #  ifdef M_UNIX
                     85: static char PtyProto[] = "/dev/ptypXY";
                     86: static char TtyProto[] = "/dev/ttypXY";
                     87: #  else
                     88: static char PtyProto[] = "/dev/ptyXY";
                     89: static char TtyProto[] = "/dev/ttyXY";
                     90: #  endif
                     91: # endif /* hpux */
                     92: #endif
                     93: 
                     94: static void initmaster __P((int));
                     95: 
                     96: #if defined(sun)
                     97: /* sun's utmp_update program opens the salve side, thus corrupting
                     98:  */
                     99: int pty_preopen = 1;
                    100: #else
                    101: int pty_preopen = 0;
                    102: #endif
                    103: 
                    104: /*
                    105:  *  Open all ptys with O_NOCTTY, just to be on the safe side
                    106:  *  (RISCos mips breaks otherwise)
                    107:  */
                    108: #ifndef O_NOCTTY
                    109: # define O_NOCTTY 0
                    110: #endif
                    111: 
                    112: /***************************************************************/
                    113: 
                    114: static void
                    115: initmaster(f)
                    116: int f;
                    117: {
                    118: #ifdef POSIX
                    119:   tcflush(f, TCIOFLUSH);
                    120: #else
                    121: # ifdef TIOCFLUSH
                    122:   (void) ioctl(f, TIOCFLUSH, (char *) 0);
                    123: # endif
                    124: #endif
                    125: #ifdef LOCKPTY
                    126:   (void) ioctl(f, TIOCEXCL, (char *) 0);
                    127: #endif
                    128: }
                    129: 
                    130: void
                    131: InitPTY(f)
                    132: int f;
                    133: {
                    134:   if (f < 0)
                    135:     return;
                    136: #if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) && !defined(linux) && !defined(__osf__) && !defined(M_UNIX)
                    137:   if (ioctl(f, I_PUSH, "ptem"))
                    138:     Panic(errno, "InitPTY: cannot I_PUSH ptem");
                    139:   if (ioctl(f, I_PUSH, "ldterm"))
                    140:     Panic(errno, "InitPTY: cannot I_PUSH ldterm");
                    141: # ifdef sun
                    142:   if (ioctl(f, I_PUSH, "ttcompat"))
                    143:     Panic(errno, "InitPTY: cannot I_PUSH ttcompat");
                    144: # endif
                    145: #endif
                    146: }
                    147: 
                    148: /***************************************************************/
                    149: 
                    150: #if defined(OSX) && !defined(PTY_DONE)
                    151: #define PTY_DONE
                    152: int
                    153: OpenPTY(ttyn)
                    154: char **ttyn;
                    155: {
                    156:   register int f;
                    157:   if ((f = open_controlling_pty(TtyName)) < 0)
                    158:     return -1;
                    159:   initmaster(f);
                    160:   *ttyn = TtyName;
                    161:   return f;
                    162: }
                    163: #endif
                    164: 
                    165: /***************************************************************/
                    166: 
                    167: #if (defined(sequent) || defined(_SEQUENT_)) && !defined(PTY_DONE)
                    168: #define PTY_DONE
                    169: int
                    170: OpenPTY(ttyn)
                    171: char **ttyn;
                    172: {
                    173:   char *m, *s;
                    174:   register int f;
                    175: 
                    176:   if ((f = getpseudotty(&s, &m)) < 0)
                    177:     return -1;
                    178: #ifdef _SEQUENT_
                    179:   fvhangup(s);
                    180: #endif
                    181:   strncpy(PtyName, m, sizeof(PtyName));
                    182:   strncpy(TtyName, s, sizeof(TtyName));
                    183:   initmaster(f);
                    184:   *ttyn = TtyName;
                    185:   return f;
                    186: }
                    187: #endif
                    188: 
                    189: /***************************************************************/
                    190: 
                    191: #if defined(__sgi) && !defined(PTY_DONE)
                    192: #define PTY_DONE
                    193: int
                    194: OpenPTY(ttyn)
                    195: char **ttyn;
                    196: {
                    197:   int f;
                    198:   char *name, *_getpty(); 
                    199:   sigret_t (*sigcld)__P(SIGPROTOARG);
                    200: 
                    201:   /*
                    202:    * SIGCHLD set to SIG_DFL for _getpty() because it may fork() and
                    203:    * exec() /usr/adm/mkpts
                    204:    */
                    205:   sigcld = signal(SIGCHLD, SIG_DFL);
                    206:   name = _getpty(&f, O_RDWR | O_NONBLOCK, 0600, 0);
                    207:   signal(SIGCHLD, sigcld);
                    208: 
                    209:   if (name == 0)
                    210:     return -1;
                    211:   initmaster(f);
                    212:   *ttyn = name;
                    213:   return f;
                    214: }
                    215: #endif
                    216: 
                    217: /***************************************************************/
                    218: 
                    219: #if defined(MIPS) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
                    220: #define PTY_DONE
                    221: int
                    222: OpenPTY(ttyn)
                    223: char **ttyn;
                    224: {
                    225:   register int f;
                    226:   struct stat buf;
                    227:    
                    228:   strcpy(PtyName, "/dev/ptc");
                    229:   if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
                    230:     return -1;
                    231:   if (fstat(f, &buf) < 0)
                    232:     {
                    233:       close(f);
                    234:       return -1;
                    235:     }
                    236:   sprintf(TtyName, "/dev/ttyq%d", minor(buf.st_rdev));
                    237:   initmaster(f);
                    238:   *ttyn = TtyName;
                    239:   return f;
                    240: }
                    241: #endif
                    242: 
                    243: /***************************************************************/
                    244: 
                    245: #if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE)
                    246: #define PTY_DONE
                    247: int
                    248: OpenPTY(ttyn)
                    249: char **ttyn;
                    250: {
                    251:   register int f;
                    252:   char *m, *ptsname();
                    253:   int unlockpt __P((int)), grantpt __P((int));
                    254: #if defined(HAVE_GETPT) && defined(linux)
                    255:   int getpt __P((void));
                    256: #endif
                    257:   sigret_t (*sigcld)__P(SIGPROTOARG);
                    258: 
                    259:   strcpy(PtyName, "/dev/ptmx");
                    260: #if defined(HAVE_GETPT) && defined(linux)
                    261:   if ((f = getpt()) == -1)
                    262: #else
                    263:   if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1)
                    264: #endif
                    265:     return -1;
                    266: 
                    267:   /*
                    268:    * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and
                    269:    * exec()s pt_chmod
                    270:    */
                    271:   sigcld = signal(SIGCHLD, SIG_DFL);
                    272:   if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f))
                    273:     {
                    274:       signal(SIGCHLD, sigcld);
                    275:       close(f);
                    276:       return -1;
                    277:     } 
                    278:   signal(SIGCHLD, sigcld);
                    279:   strncpy(TtyName, m, sizeof(TtyName));
                    280:   initmaster(f);
                    281:   *ttyn = TtyName;
                    282:   return f;
                    283: }
                    284: #endif
                    285: 
                    286: /***************************************************************/
                    287: 
                    288: #if defined(_AIX) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
                    289: #define PTY_DONE
                    290: 
                    291: int
                    292: OpenPTY(ttyn)
                    293: char **ttyn;
                    294: {
                    295:   register int f;
                    296: 
                    297:   /* a dumb looking loop replaced by mycrofts code: */
                    298:   strcpy (PtyName, "/dev/ptc");
                    299:   if ((f = open (PtyName, O_RDWR | O_NOCTTY)) < 0)
                    300:     return -1;
                    301:   strncpy(TtyName, ttyname(f), sizeof(TtyName));
                    302:   if (eff_uid && access(TtyName, R_OK | W_OK))
                    303:     {
                    304:       close(f);
                    305:       return -1;
                    306:     }
                    307:   initmaster(f);
                    308: # ifdef _IBMR2
                    309:   pty_preopen = 1;
                    310: # endif
                    311:   *ttyn = TtyName;
                    312:   return f;
                    313: }
                    314: #endif
                    315: 
                    316: /***************************************************************/
                    317: 
                    318: #if defined(HAVE_OPENPTY) && !defined(PTY_DONE)
                    319: #define PTY_DONE
                    320: int
                    321: OpenPTY(ttyn)
                    322: char **ttyn;
                    323: {
                    324:   int f, s;
                    325:   if (openpty(&f, &s, TtyName, NULL, NULL) != 0)
                    326:     return -1;
                    327:   close(s);
                    328:   initmaster(f);
                    329:   pty_preopen = 1;
                    330:   *ttyn = TtyName;
                    331:   return f;    
                    332: }
                    333: #endif
                    334: 
                    335: /***************************************************************/
                    336: 
                    337: #ifndef PTY_DONE
                    338: int
                    339: OpenPTY(ttyn)
                    340: char **ttyn;
                    341: {
                    342:   register char *p, *q, *l, *d;
                    343:   register int f;
                    344: 
                    345:   debug("OpenPTY: Using BSD style ptys.\n");
                    346:   strcpy(PtyName, PtyProto);
                    347:   strcpy(TtyName, TtyProto);
                    348:   for (p = PtyName; *p != 'X'; p++)
                    349:     ;
                    350:   for (q = TtyName; *q != 'X'; q++)
                    351:     ;
                    352:   for (l = PTYRANGE0; (*p = *l) != '\0'; l++)
                    353:     {
                    354:       for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++)
                    355:        {
                    356:          debug1("OpenPTY tries '%s'\n", PtyName);
                    357:          if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1)
                    358:            continue;
                    359:          q[0] = *l;
                    360:          q[1] = *d;
                    361:          if (eff_uid && access(TtyName, R_OK | W_OK))
                    362:            {
                    363:              close(f);
                    364:              continue;
                    365:            }
                    366: #if defined(sun) && defined(TIOCGPGRP) && !defined(SUNOS3)
                    367:          /* Hack to ensure that the slave side of the pty is
                    368:           * unused. May not work in anything other than SunOS4.1
                    369:           */
                    370:            {
                    371:              int pgrp;
                    372: 
                    373:              /* tcgetpgrp does not work (uses TIOCGETPGRP)! */
                    374:              if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO)
                    375:                {
                    376:                  close(f);
                    377:                  continue;
                    378:                }
                    379:            }
                    380: #endif
                    381:          initmaster(f);
                    382:          *ttyn = TtyName;
                    383:          return f;
                    384:        }
                    385:     }
                    386:   return -1;
                    387: }
                    388: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>