Annotation of embedaddon/readline/examples/rlfe/pty.c, revision 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>