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