home *** CD-ROM | disk | FTP | other *** search
- /* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
- */
- /*
- * The stuff in this file mostly comes from the "screen" program.
- * Included with permission from Juergen Weigert.
- * Copied from "pty.c". "putenv.c" was used for putenv() in misc2.c.
- *
- * It has been modified to work better with Vim.
- * The parts that are not used in Vim have been deleted.
- * See the "screen" sources for the complete stuff.
- */
-
- /* Copyright (c) 1993
- * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- * Copyright (c) 1987 Oliver Laumann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
- /* RCS_ID("$Id: pty.c,v 1.2 1999/09/19 19:50:51 mool Exp $ FAU") */
-
- #include "vim.h"
-
- #ifdef HAVE_FCNTL_H
- # include <fcntl.h>
- #endif
-
- #include <signal.h>
-
- #ifdef __CYGWIN32__
- # include <sys/termios.h>
- #endif
-
- #if HAVE_SYS_IOCTL_H
- # include <sys/ioctl.h>
- #endif
-
- #if HAVE_STROPTS_H
- #include <sys/types.h>
- #ifdef sinix
- #define buf_T __system_buf_t__
- #endif
- #include <stropts.h>
- #ifdef sinix
- #undef buf_T
- #endif
- # ifdef sun
- # include <sys/conf.h>
- # endif
- #endif
-
- #if HAVE_UNISTD_H
- # include <unistd.h>
- #endif
-
- #if HAVE_TERMIO_H
- # include <termio.h>
- #else
- # if HAVE_TERMIOS_H
- # include <termios.h>
- # endif
- #endif
-
- #if HAVE_SYS_STREAM_H
- # include <sys/stream.h>
- #endif
-
- #if HAVE_SYS_PTEM_H
- # include <sys/ptem.h>
- #endif
-
- #if !defined(sun) && !defined(VMS) && !defined(MACOS)
- # include <sys/ioctl.h>
- #endif
-
- #if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL)
- # include <sys/ttold.h>
- #endif
-
- #ifdef ISC
- # include <sys/tty.h>
- # include <sys/sioctl.h>
- # include <sys/pty.h>
- #endif
-
- #ifdef sgi
- # include <sys/sysmacros.h>
- #endif
-
- #if defined(_INCLUDE_HPUX_SOURCE) && !defined(hpux)
- # define hpux
- #endif
-
- /*
- * if no PTYRANGE[01] is in the config file, we pick a default
- */
- #ifndef PTYRANGE0
- # define PTYRANGE0 "qprs"
- #endif
- #ifndef PTYRANGE1
- # define PTYRANGE1 "0123456789abcdef"
- #endif
-
- /* SVR4 pseudo ttys don't seem to work with SCO-5 */
- #ifdef M_UNIX
- # undef HAVE_SVR4_PTYS
- #endif
-
- static void initmaster __ARGS((int));
-
- /*
- * Open all ptys with O_NOCTTY, just to be on the safe side
- * (RISCos mips breaks otherwise)
- */
- #ifndef O_NOCTTY
- # define O_NOCTTY 0
- #endif
-
- static void
- initmaster(f)
- int f;
- {
- #ifndef VMS
- # ifdef POSIX
- tcflush(f, TCIOFLUSH);
- # else
- # ifdef TIOCFLUSH
- (void)ioctl(f, TIOCFLUSH, (char *) 0);
- # endif
- # endif
- # ifdef LOCKPTY
- (void)ioctl(f, TIOCEXCL, (char *) 0);
- # endif
- #endif
- }
-
- /*
- * This causes a hang on some systems, but is required for a properly working
- * pty on others. Needs to be tuned...
- */
- int
- SetupSlavePTY(fd)
- int fd;
- {
- if (fd < 0)
- return 0;
- #if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) && !defined(linux) && !defined(__osf__) && !defined(M_UNIX)
- # if defined(HAVE_SYS_PTEM_H) || defined(hpux)
- if (ioctl(fd, I_PUSH, "ptem") != 0)
- return -1;
- # endif
- if (ioctl(fd, I_PUSH, "ldterm") != 0)
- return -1;
- # ifdef sun
- if (ioctl(fd, I_PUSH, "ttcompat") != 0)
- return -1;
- # endif
- #endif
- return 0;
- }
-
-
- #if defined(OSX) && !defined(PTY_DONE)
- #define PTY_DONE
- int
- OpenPTY(ttyn)
- char **ttyn;
- {
- int f;
- static char TtyName[32];
-
- if ((f = open_controlling_pty(TtyName)) < 0)
- return -1;
- initmaster(f);
- *ttyn = TtyName;
- return f;
- }
- #endif
-
- #if (defined(sequent) || defined(_SEQUENT_)) && defined(HAVE_GETPSEUDOTTY) \
- && !defined(PTY_DONE)
- #define PTY_DONE
- int
- OpenPTY(ttyn)
- char **ttyn;
- {
- char *m, *s;
- int f;
- /* used for opening a new pty-pair: */
- static char PtyName[32];
- static char TtyName[32];
-
- if ((f = getpseudotty(&s, &m)) < 0)
- return -1;
- #ifdef _SEQUENT_
- fvhangup(s);
- #endif
- strncpy(PtyName, m, sizeof(PtyName));
- strncpy(TtyName, s, sizeof(TtyName));
- initmaster(f);
- *ttyn = TtyName;
- return f;
- }
- #endif
-
- #if defined(__sgi) && !defined(PTY_DONE)
- #define PTY_DONE
- int
- OpenPTY(ttyn)
- char **ttyn;
- {
- int f;
- char *name;
- RETSIGTYPE (*sigcld)__ARGS(SIGPROTOARG);
-
- /*
- * SIGCHLD set to SIG_DFL for _getpty() because it may fork() and
- * exec() /usr/adm/mkpts
- */
- sigcld = signal(SIGCHLD, SIG_DFL);
- name = _getpty(&f, O_RDWR | O_NONBLOCK | O_EXTRA, 0600, 0);
- signal(SIGCHLD, sigcld);
-
- if (name == 0)
- return -1;
- initmaster(f);
- *ttyn = name;
- return f;
- }
- #endif
-
- #if defined(MIPS) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
- #define PTY_DONE
- int
- OpenPTY(ttyn)
- char **ttyn;
- {
- int f;
- struct stat buf;
- /* used for opening a new pty-pair: */
- static char TtyName[32];
-
- if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_NONBLOCK | O_EXTRA, 0)) < 0)
- return -1;
- if (mch_fstat(f, &buf) < 0)
- {
- close(f);
- return -1;
- }
- sprintf(TtyName, "/dev/ttyq%d", minor(buf.st_rdev));
- initmaster(f);
- *ttyn = TtyName;
- return f;
- }
- #endif
-
- #if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux)
-
- /* NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work! */
- #define PTY_DONE
- int
- OpenPTY(ttyn)
- char **ttyn;
- {
- int f;
- char *m, *ptsname();
- int unlockpt __ARGS((int)), grantpt __ARGS((int));
- RETSIGTYPE (*sigcld)__ARGS(SIGPROTOARG);
- /* used for opening a new pty-pair: */
- static char TtyName[32];
-
- if ((f = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_EXTRA, 0)) == -1)
- return -1;
-
- /*
- * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and
- * exec()s pt_chmod
- */
- sigcld = signal(SIGCHLD, SIG_DFL);
- if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f))
- {
- signal(SIGCHLD, sigcld);
- close(f);
- return -1;
- }
- signal(SIGCHLD, sigcld);
- strncpy(TtyName, m, sizeof(TtyName));
- initmaster(f);
- *ttyn = TtyName;
- return f;
- }
- #endif
-
- #if defined(_AIX) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
- #define PTY_DONE
-
- #ifdef _IBMR2
- int aixhack = -1;
- #endif
-
- int
- OpenPTY(ttyn)
- char **ttyn;
- {
- int f;
- /* used for opening a new pty-pair: */
- static char TtyName[32];
-
- /* a dumb looking loop replaced by mycrofts code: */
- if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_EXTRA)) < 0)
- return -1;
- strncpy(TtyName, ttyname(f), sizeof(TtyName));
- if (geteuid() && mch_access(TtyName, R_OK | W_OK))
- {
- close(f);
- return -1;
- }
- initmaster(f);
- # ifdef _IBMR2
- if (aixhack >= 0)
- close(aixhack);
- if ((aixhack = open(TtyName, O_RDWR | O_NOCTTY | O_EXTRA, 0)) < 0)
- {
- close(f);
- return -1;
- }
- # endif
- *ttyn = TtyName;
- return f;
- }
- #endif
-
- #ifndef PTY_DONE
-
- # ifdef hpux
- static char PtyProto[] = "/dev/ptym/ptyXY";
- static char TtyProto[] = "/dev/pty/ttyXY";
- # else
- # ifdef __BEOS__
- static char PtyProto[] = "/dev/pt/XY";
- static char TtyProto[] = "/dev/tt/XY";
- # else
- static char PtyProto[] = "/dev/ptyXY";
- static char TtyProto[] = "/dev/ttyXY";
- # endif
- # endif
-
- int
- OpenPTY(ttyn)
- char **ttyn;
- {
- char *p, *q, *l, *d;
- int f;
- /* used for opening a new pty-pair: */
- static char PtyName[32];
- static char TtyName[32];
-
- strcpy(PtyName, PtyProto);
- strcpy(TtyName, TtyProto);
- for (p = PtyName; *p != 'X'; p++)
- ;
- for (q = TtyName; *q != 'X'; q++)
- ;
- for (l = PTYRANGE0; (*p = *l) != '\0'; l++)
- {
- for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++)
- {
- #if !defined(MACOS) || defined(USE_CARBONIZED)
- if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_EXTRA, 0)) == -1)
- #else
- if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_EXTRA)) == -1)
- #endif
- continue;
- q[0] = *l;
- q[1] = *d;
- #ifndef MACOS
- if (geteuid() && mch_access(TtyName, R_OK | W_OK))
- {
- close(f);
- continue;
- }
- #endif
- #if defined(sun) && defined(TIOCGPGRP) && !defined(SUNOS3)
- /* Hack to ensure that the slave side of the pty is
- * unused. May not work in anything other than SunOS4.1
- */
- {
- int pgrp;
-
- /* tcgetpgrp does not work (uses TIOCGETPGRP)! */
- if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO)
- {
- close(f);
- continue;
- }
- }
- #endif
- initmaster(f);
- *ttyn = TtyName;
- return f;
- }
- }
- return -1;
- }
- #endif
-