File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / examples / rlfe / pty.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 08:16:46 2014 UTC (10 years, 8 months ago) by misho
Branches: readline, MAIN
CVS tags: v8_2p0, v8_1p0, v6_3p10_cross, v6_3p10, v6_3, p6, HEAD
readline 6.3

    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>