home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #3 / amigamamagazinepolishissue1998.iso / szachy / gnu / amyboard-3.2.pl2 / childio.c < prev    next >
C/C++ Source or Header  |  1995-03-08  |  7KB  |  259 lines

  1. /*
  2.  * childio.c -- set up communication with child processes $Id:
  3.  * childio.c,v 1.2 1994/11/12 19:31:41 mann Exp mann $
  4.  *
  5.  * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
  6.  * Enhancements Copyright 1992-95 Free Software Foundation, Inc.
  7.  *
  8.  * The following terms apply to Digital Equipment Corporation's copyright
  9.  * interest in XBoard:
  10.  * ------------------------------------------------------------------------
  11.  * All Rights Reserved
  12.  *
  13.  * Permission to use, copy, modify, and distribute this software and its
  14.  * documentation for any purpose and without fee is hereby granted,
  15.  * provided that the above copyright notice appear in all copies and that
  16.  * both that copyright notice and this permission notice appear in
  17.  * supporting documentation, and that the name of Digital not be
  18.  * used in advertising or publicity pertaining to distribution of the
  19.  * software without specific, written prior permission.
  20.  *
  21.  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  22.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  23.  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  24.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  25.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  26.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  27.  * SOFTWARE.
  28.  * ------------------------------------------------------------------------
  29.  *
  30.  * The following terms apply to the enhanced version of XBoard distributed
  31.  * by the Free Software Foundation:
  32.  * ------------------------------------------------------------------------
  33.  * This program is free software; you can redistribute it and/or modify
  34.  * it under the terms of the GNU General Public License as published by
  35.  * the Free Software Foundation; either version 2 of the License, or
  36.  * (at your option) any later version.
  37.  *
  38.  * This program is distributed in the hope that it will be useful,
  39.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  40.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  41.  * GNU General Public License for more details.
  42.  *
  43.  * You should have received a copy of the GNU General Public License
  44.  * along with this program; if not, write to the Free Software
  45.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  46.  * ------------------------------------------------------------------------
  47.  *
  48.  * See the file ChangeLog for a revision history.  */
  49.  
  50. /* This file splits into two entirely different pieces of code
  51.    depending on whether USE_PTYS is 1.  The whole reason for all
  52.    the pty nonsense is that select() does not work on pipes in System-V
  53.    derivatives (at least some of them).  This is a problem because
  54.    XtAppAddInput works by adding its argument to a select that is done
  55.    deep inside Xlib.
  56. */
  57.  
  58. #include <signal.h>
  59. #if HAVE_UNISTD_H
  60. # include <unistd.h>
  61. #endif
  62.  
  63. #include "common.h"
  64. #include "frontend.h"
  65.  
  66. #if !USE_PTYS
  67. /* This code is for systems where pipes work properly */
  68.  
  69. void SetUpChildIO(to_prog, from_prog)
  70.      int to_prog[2], from_prog[2];
  71. {
  72.     signal(SIGPIPE, SIG_IGN);
  73.     pipe(to_prog);
  74.     pipe(from_prog);
  75. }
  76.  
  77. #else /* USE_PTYS == 1 */
  78. /* This code is for all systems where we must use ptys */
  79.  
  80. #include <errno.h>
  81. #include <sys/stat.h>
  82. #include <sys/ioctl.h>
  83. #if HAVE_STROPTS_H
  84. # include <stropts.h>
  85. #endif /* HAVE_STROPTS_H */
  86. #if HAVE_SYS_FCNTL_H
  87. # include <sys/fcntl.h>
  88. #else /* not HAVE_SYS_FCNTL_H */
  89. # if HAVE_FCNTL_H
  90. #  include <fcntl.h>
  91. # endif /* HAVE_FCNTL_H */
  92. #endif /* not HAVE_SYS_FCNTL_H */
  93.  
  94. int PseudoTTY P((char pty_name[]));
  95.  
  96. int SetUpChildIO(to_prog, from_prog)
  97.      int to_prog[2], from_prog[2];
  98. {
  99.     char pty_name[MSG_SIZ];
  100.  
  101.     if ((to_prog[1] = PseudoTTY(pty_name)) == -1) {
  102.     DisplayFatalError("Can't open pseudo-tty", errno, 1);
  103.     ExitEvent(1);
  104.     }
  105.     from_prog[0] = to_prog[1];
  106.     to_prog[0] = from_prog[1] = open(pty_name, O_RDWR, 0);
  107.  
  108. #if HAVE_STROPTS_H /* do we really need this??  pipe-like behavior is fine */
  109.     if (ioctl (to_prog[0], I_PUSH, "ptem") == -1 ||
  110.     ioctl (to_prog[0], I_PUSH, "ldterm") == -1 ||
  111.     ioctl (to_prog[0], I_PUSH, "ttcompat") == -1) {
  112. # ifdef NOTDEF /* seems some systems don't have or need ptem and ttcompat */
  113.     DisplayFatalError("Can't ioctl pseudo-tty", errno, 1);
  114.     ExitEvent(1);
  115. # endif /*NOTDEF*/
  116.     }
  117. #endif /* HAVE_STROPTS_H */
  118.  
  119. }
  120.  
  121. #if HAVE_GRANTPT
  122. /* This code is for SVR4 */
  123.  
  124. int PseudoTTY(pty_name)
  125.      char pty_name[];
  126. {
  127.     extern char *ptsname();
  128.     char *ptss;
  129.     int fd;
  130.     
  131.     fd = open("/dev/ptmx", O_RDWR);
  132.     if (fd < 0) return fd;
  133.     if (grantpt(fd) == -1) return -1;
  134.     if (unlockpt(fd) == -1) return -1;
  135.     if (!(ptss = ptsname(fd))) return -1;
  136.     strcpy(pty_name, ptss);
  137.     return fd;
  138. }
  139.  
  140. #else /* not HAVE_GRANTPT */
  141. #if HAVE__GETPTY
  142. /* This code is for IRIX */
  143.  
  144. int PseudoTTY(pty_name)
  145.      char pty_name[];
  146. {
  147.     int fd;
  148.     char *ptyn;
  149.  
  150.     ptyn = _getpty(&fd, O_RDWR, 0600, 0);
  151.     if (ptyn == NULL) return -1;
  152.     strcpy(pty_name, ptyn);
  153.     return fd;
  154. }
  155.  
  156. #else /* not HAVE__GETPTY */
  157. #if HAVE_LIBSEQ
  158. /* This code is for Sequent DYNIX/ptx.  Untested. --tpm */
  159.  
  160. int PseudoTTY(pty_name)
  161.      char pty_name[];
  162. {
  163.     int fd;
  164.     char *slave, *master;
  165.  
  166.     fd = getpseudotty(&slave, &master);
  167.     if (fd < 0) return fd;
  168.     strcpy(pty_name, slave);
  169.     return fd;
  170. }
  171.  
  172. #else /* not HAVE_LIBSEQ */
  173. /* This code is for all other systems */
  174. /* The code is adapted from GNU Emacs 19.24 */
  175.  
  176. #ifndef FIRST_PTY_LETTER
  177. #define FIRST_PTY_LETTER 'p'
  178. #endif
  179. #ifndef LAST_PTY_LETTER
  180. #define LAST_PTY_LETTER 'z'
  181. #endif
  182.  
  183. int PseudoTTY(pty_name)
  184.      char pty_name[];
  185. {
  186.   struct stat stb;
  187.   register c, i;
  188.   int fd;
  189.  
  190.   /* Some systems name their pseudoterminals so that there are gaps in
  191.      the usual sequence - for example, on HP9000/S700 systems, there
  192.      are no pseudoterminals with names ending in 'f'.  So we wait for
  193.      three failures in a row before deciding that we've reached the
  194.      end of the ptys.  */
  195.   int failed_count = 0;
  196.  
  197. #ifdef PTY_ITERATION
  198.   PTY_ITERATION
  199. #else
  200.   for (c = FIRST_PTY_LETTER; c <= LAST_PTY_LETTER; c++)
  201.     for (i = 0; i < 16; i++)
  202. #endif
  203.       {
  204. #ifdef PTY_NAME_SPRINTF
  205.     PTY_NAME_SPRINTF
  206. #else
  207.     sprintf (pty_name, "/dev/pty%c%x", c, i);
  208. #endif /* no PTY_NAME_SPRINTF */
  209.  
  210. #ifdef PTY_OPEN
  211.     PTY_OPEN;
  212. #else /* no PTY_OPEN */
  213.     if (stat (pty_name, &stb) < 0)
  214.       {
  215.         failed_count++;
  216.         if (failed_count >= 3)
  217.           return -1;
  218.       }
  219.     else
  220.       failed_count = 0;
  221.     fd = open (pty_name, O_RDWR, 0);
  222. #endif /* no PTY_OPEN */
  223.  
  224.     if (fd >= 0)
  225.       {
  226.         /* check to make certain that both sides are available
  227.            this avoids a nasty yet stupid bug in rlogins */
  228. #ifdef PTY_TTY_NAME_SPRINTF
  229.         PTY_TTY_NAME_SPRINTF
  230. #else
  231.             sprintf (pty_name, "/dev/tty%c%x", c, i);
  232. #endif /* no PTY_TTY_NAME_SPRINTF */
  233. #ifndef UNIPLUS
  234.         if (access (pty_name, 6) != 0)
  235.           {
  236.         close (fd);
  237.         continue;
  238.           }
  239. #endif /* not UNIPLUS */
  240. #ifdef IBMRTAIX
  241.           /* On AIX, the parent gets SIGHUP when a pty attached
  242.                  child dies.  So, we ignore SIGHUP once we've started
  243.                  a child on a pty.  Note that this may cause xboard
  244.                  not to die when it should, i.e., when its own
  245.                  controlling tty goes away.
  246.           */
  247.           signal(SIGHUP, SIG_IGN);
  248. #endif /* IBMRTAIX */
  249.         return fd;
  250.       }
  251.       }
  252.   return -1;
  253. }
  254.  
  255. #endif /* not HAVE_LIBSEQ */
  256. #endif /* not HAVE__GETPTY */
  257. #endif /* not HAVE_GRANTPT */
  258. #endif /* USE_PTYS */
  259.