home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / pty.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-28  |  8.8 KB  |  426 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  * See README.txt for an overview of the Vim source code.
  8.  */
  9. /*
  10.  * The stuff in this file mostly comes from the "screen" program.
  11.  * Included with permission from Juergen Weigert.
  12.  * Copied from "pty.c".  "putenv.c" was used for putenv() in misc2.c.
  13.  *
  14.  * It has been modified to work better with Vim.
  15.  * The parts that are not used in Vim have been deleted.
  16.  * See the "screen" sources for the complete stuff.
  17.  */
  18.  
  19. /* Copyright (c) 1993
  20.  *    Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  21.  *    Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  22.  * Copyright (c) 1987 Oliver Laumann
  23.  *
  24.  * This program is free software; you can redistribute it and/or modify
  25.  * it under the terms of the GNU General Public License as published by
  26.  * the Free Software Foundation; either version 2, or (at your option)
  27.  * any later version.
  28.  *
  29.  * This program is distributed in the hope that it will be useful,
  30.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  31.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  32.  * GNU General Public License for more details.
  33.  *
  34.  * You should have received a copy of the GNU General Public License
  35.  * along with this program (see the file COPYING); if not, write to the
  36.  * Free Software Foundation, Inc.,
  37.  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  38.  */
  39.  
  40. /* RCS_ID("$Id: pty.c,v 1.2 1999/09/19 19:50:51 mool Exp $ FAU") */
  41.  
  42. #include "vim.h"
  43.  
  44. #ifdef HAVE_FCNTL_H
  45. # include <fcntl.h>
  46. #endif
  47.  
  48. #include <signal.h>
  49.  
  50. #ifdef __CYGWIN32__
  51. # include <sys/termios.h>
  52. #endif
  53.  
  54. #if HAVE_SYS_IOCTL_H
  55. # include <sys/ioctl.h>
  56. #endif
  57.  
  58. #if HAVE_STROPTS_H
  59. #include <sys/types.h>
  60. #ifdef sinix
  61. #define buf_T __system_buf_t__
  62. #endif
  63. #include <stropts.h>
  64. #ifdef sinix
  65. #undef buf_T
  66. #endif
  67. # ifdef sun
  68. #  include <sys/conf.h>
  69. # endif
  70. #endif
  71.  
  72. #if HAVE_UNISTD_H
  73. # include <unistd.h>
  74. #endif
  75.  
  76. #if HAVE_TERMIO_H
  77. # include <termio.h>
  78. #else
  79. # if HAVE_TERMIOS_H
  80. #  include <termios.h>
  81. # endif
  82. #endif
  83.  
  84. #if HAVE_SYS_STREAM_H
  85. # include <sys/stream.h>
  86. #endif
  87.  
  88. #if HAVE_SYS_PTEM_H
  89. # include <sys/ptem.h>
  90. #endif
  91.  
  92. #if !defined(sun) && !defined(VMS) && !defined(MACOS)
  93. # include <sys/ioctl.h>
  94. #endif
  95.  
  96. #if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL)
  97. # include <sys/ttold.h>
  98. #endif
  99.  
  100. #ifdef ISC
  101. # include <sys/tty.h>
  102. # include <sys/sioctl.h>
  103. # include <sys/pty.h>
  104. #endif
  105.  
  106. #ifdef sgi
  107. # include <sys/sysmacros.h>
  108. #endif
  109.  
  110. #if defined(_INCLUDE_HPUX_SOURCE) && !defined(hpux)
  111. # define hpux
  112. #endif
  113.  
  114. /*
  115.  * if no PTYRANGE[01] is in the config file, we pick a default
  116.  */
  117. #ifndef PTYRANGE0
  118. # define PTYRANGE0 "qprs"
  119. #endif
  120. #ifndef PTYRANGE1
  121. # define PTYRANGE1 "0123456789abcdef"
  122. #endif
  123.  
  124. /* SVR4 pseudo ttys don't seem to work with SCO-5 */
  125. #ifdef M_UNIX
  126. # undef HAVE_SVR4_PTYS
  127. #endif
  128.  
  129. static void initmaster __ARGS((int));
  130.  
  131. /*
  132.  *  Open all ptys with O_NOCTTY, just to be on the safe side
  133.  *  (RISCos mips breaks otherwise)
  134.  */
  135. #ifndef O_NOCTTY
  136. # define O_NOCTTY 0
  137. #endif
  138.  
  139.     static void
  140. initmaster(f)
  141.     int f;
  142. {
  143. #ifndef VMS
  144. # ifdef POSIX
  145.     tcflush(f, TCIOFLUSH);
  146. # else
  147. #  ifdef TIOCFLUSH
  148.     (void)ioctl(f, TIOCFLUSH, (char *) 0);
  149. #  endif
  150. # endif
  151. # ifdef LOCKPTY
  152.     (void)ioctl(f, TIOCEXCL, (char *) 0);
  153. # endif
  154. #endif
  155. }
  156.  
  157. /*
  158.  * This causes a hang on some systems, but is required for a properly working
  159.  * pty on others.  Needs to be tuned...
  160.  */
  161.     int
  162. SetupSlavePTY(fd)
  163.     int fd;
  164. {
  165.     if (fd < 0)
  166.     return 0;
  167. #if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) && !defined(linux) && !defined(__osf__) && !defined(M_UNIX)
  168. # if defined(HAVE_SYS_PTEM_H) || defined(hpux)
  169.     if (ioctl(fd, I_PUSH, "ptem") != 0)
  170.     return -1;
  171. # endif
  172.     if (ioctl(fd, I_PUSH, "ldterm") != 0)
  173.     return -1;
  174. # ifdef sun
  175.     if (ioctl(fd, I_PUSH, "ttcompat") != 0)
  176.     return -1;
  177. # endif
  178. #endif
  179.     return 0;
  180. }
  181.  
  182.  
  183. #if defined(OSX) && !defined(PTY_DONE)
  184. #define PTY_DONE
  185.     int
  186. OpenPTY(ttyn)
  187.     char **ttyn;
  188. {
  189.     int        f;
  190.     static char TtyName[32];
  191.  
  192.     if ((f = open_controlling_pty(TtyName)) < 0)
  193.     return -1;
  194.     initmaster(f);
  195.     *ttyn = TtyName;
  196.     return f;
  197. }
  198. #endif
  199.  
  200. #if (defined(sequent) || defined(_SEQUENT_)) && defined(HAVE_GETPSEUDOTTY) \
  201.     && !defined(PTY_DONE)
  202. #define PTY_DONE
  203.     int
  204. OpenPTY(ttyn)
  205.     char **ttyn;
  206. {
  207.     char    *m, *s;
  208.     int        f;
  209.     /* used for opening a new pty-pair: */
  210.     static char PtyName[32];
  211.     static char TtyName[32];
  212.  
  213.     if ((f = getpseudotty(&s, &m)) < 0)
  214.     return -1;
  215. #ifdef _SEQUENT_
  216.     fvhangup(s);
  217. #endif
  218.     strncpy(PtyName, m, sizeof(PtyName));
  219.     strncpy(TtyName, s, sizeof(TtyName));
  220.     initmaster(f);
  221.     *ttyn = TtyName;
  222.     return f;
  223. }
  224. #endif
  225.  
  226. #if defined(__sgi) && !defined(PTY_DONE)
  227. #define PTY_DONE
  228.     int
  229. OpenPTY(ttyn)
  230.     char **ttyn;
  231. {
  232.     int f;
  233.     char *name;
  234.     RETSIGTYPE (*sigcld)__ARGS(SIGPROTOARG);
  235.  
  236.     /*
  237.      * SIGCHLD set to SIG_DFL for _getpty() because it may fork() and
  238.      * exec() /usr/adm/mkpts
  239.      */
  240.     sigcld = signal(SIGCHLD, SIG_DFL);
  241.     name = _getpty(&f, O_RDWR | O_NONBLOCK | O_EXTRA, 0600, 0);
  242.     signal(SIGCHLD, sigcld);
  243.  
  244.     if (name == 0)
  245.     return -1;
  246.     initmaster(f);
  247.     *ttyn = name;
  248.     return f;
  249. }
  250. #endif
  251.  
  252. #if defined(MIPS) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
  253. #define PTY_DONE
  254.     int
  255. OpenPTY(ttyn)
  256.     char **ttyn;
  257. {
  258.     int        f;
  259.     struct stat buf;
  260.     /* used for opening a new pty-pair: */
  261.     static char TtyName[32];
  262.  
  263.     if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_NONBLOCK | O_EXTRA, 0)) < 0)
  264.     return -1;
  265.     if (mch_fstat(f, &buf) < 0)
  266.     {
  267.     close(f);
  268.     return -1;
  269.     }
  270.     sprintf(TtyName, "/dev/ttyq%d", minor(buf.st_rdev));
  271.     initmaster(f);
  272.     *ttyn = TtyName;
  273.     return f;
  274. }
  275. #endif
  276.  
  277. #if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux)
  278.  
  279. /* NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work! */
  280. #define PTY_DONE
  281.     int
  282. OpenPTY(ttyn)
  283.     char **ttyn;
  284. {
  285.     int        f;
  286.     char    *m, *ptsname();
  287.     int unlockpt __ARGS((int)), grantpt __ARGS((int));
  288.     RETSIGTYPE (*sigcld)__ARGS(SIGPROTOARG);
  289.     /* used for opening a new pty-pair: */
  290.     static char TtyName[32];
  291.  
  292.     if ((f = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_EXTRA, 0)) == -1)
  293.     return -1;
  294.  
  295.     /*
  296.      * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and
  297.      * exec()s pt_chmod
  298.      */
  299.     sigcld = signal(SIGCHLD, SIG_DFL);
  300.     if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f))
  301.     {
  302.     signal(SIGCHLD, sigcld);
  303.     close(f);
  304.     return -1;
  305.     }
  306.     signal(SIGCHLD, sigcld);
  307.     strncpy(TtyName, m, sizeof(TtyName));
  308.     initmaster(f);
  309.     *ttyn = TtyName;
  310.     return f;
  311. }
  312. #endif
  313.  
  314. #if defined(_AIX) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
  315. #define PTY_DONE
  316.  
  317. #ifdef _IBMR2
  318. int aixhack = -1;
  319. #endif
  320.  
  321.     int
  322. OpenPTY(ttyn)
  323.     char **ttyn;
  324. {
  325.     int        f;
  326.     /* used for opening a new pty-pair: */
  327.     static char TtyName[32];
  328.  
  329.     /* a dumb looking loop replaced by mycrofts code: */
  330.     if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_EXTRA)) < 0)
  331.     return -1;
  332.     strncpy(TtyName, ttyname(f), sizeof(TtyName));
  333.     if (geteuid() && mch_access(TtyName, R_OK | W_OK))
  334.     {
  335.     close(f);
  336.     return -1;
  337.     }
  338.     initmaster(f);
  339. # ifdef _IBMR2
  340.     if (aixhack >= 0)
  341.     close(aixhack);
  342.     if ((aixhack = open(TtyName, O_RDWR | O_NOCTTY | O_EXTRA, 0)) < 0)
  343.     {
  344.     close(f);
  345.     return -1;
  346.     }
  347. # endif
  348.     *ttyn = TtyName;
  349.     return f;
  350. }
  351. #endif
  352.  
  353. #ifndef PTY_DONE
  354.  
  355. # ifdef hpux
  356. static char PtyProto[] = "/dev/ptym/ptyXY";
  357. static char TtyProto[] = "/dev/pty/ttyXY";
  358. # else
  359. #  ifdef __BEOS__
  360. static char PtyProto[] = "/dev/pt/XY";
  361. static char TtyProto[] = "/dev/tt/XY";
  362. #  else
  363. static char PtyProto[] = "/dev/ptyXY";
  364. static char TtyProto[] = "/dev/ttyXY";
  365. #  endif
  366. # endif
  367.  
  368.     int
  369. OpenPTY(ttyn)
  370.     char **ttyn;
  371. {
  372.     char    *p, *q, *l, *d;
  373.     int        f;
  374.     /* used for opening a new pty-pair: */
  375.     static char PtyName[32];
  376.     static char TtyName[32];
  377.  
  378.     strcpy(PtyName, PtyProto);
  379.     strcpy(TtyName, TtyProto);
  380.     for (p = PtyName; *p != 'X'; p++)
  381.     ;
  382.     for (q = TtyName; *q != 'X'; q++)
  383.     ;
  384.     for (l = PTYRANGE0; (*p = *l) != '\0'; l++)
  385.     {
  386.     for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++)
  387.     {
  388. #if !defined(MACOS) || defined(USE_CARBONIZED)
  389.         if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_EXTRA, 0)) == -1)
  390. #else
  391.         if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_EXTRA)) == -1)
  392. #endif
  393.         continue;
  394.         q[0] = *l;
  395.         q[1] = *d;
  396. #ifndef MACOS
  397.         if (geteuid() && mch_access(TtyName, R_OK | W_OK))
  398.         {
  399.         close(f);
  400.         continue;
  401.         }
  402. #endif
  403. #if defined(sun) && defined(TIOCGPGRP) && !defined(SUNOS3)
  404.         /* Hack to ensure that the slave side of the pty is
  405.          * unused. May not work in anything other than SunOS4.1
  406.          */
  407.         {
  408.         int pgrp;
  409.  
  410.         /* tcgetpgrp does not work (uses TIOCGETPGRP)! */
  411.         if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO)
  412.         {
  413.             close(f);
  414.             continue;
  415.         }
  416.         }
  417. #endif
  418.         initmaster(f);
  419.         *ttyn = TtyName;
  420.         return f;
  421.     }
  422.     }
  423.     return -1;
  424. }
  425. #endif
  426.