]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ser-pipe.c
* config/tc-hppa.c (pa_ip): Fix thinkos in recent cleanup
[thirdparty/binutils-gdb.git] / gdb / ser-pipe.c
CommitLineData
daf3f280
JM
1/* Serial interface for a pipe to a separate program
2 Copyright 1999 Free Software Foundation, Inc.
3
4 Contributed by Cygnus Solutions.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23#include "defs.h"
24#include "serial.h"
25#include <sys/types.h>
96baa820 26#ifdef HAVE_SYS_WAIT_H
daf3f280 27#include <sys/wait.h>
96baa820 28#endif
daf3f280
JM
29#include <sys/socket.h>
30#include <sys/time.h>
31#include <fcntl.h>
daf3f280
JM
32
33#include "signals.h"
34#include "gdb_string.h"
35
36extern int (*ui_loop_hook) PARAMS ((int));
37
38static int pipe_open PARAMS ((serial_t scb, const char *name));
39static void pipe_raw PARAMS ((serial_t scb));
40static int wait_for PARAMS ((serial_t scb, int timeout));
41static int pipe_readchar PARAMS ((serial_t scb, int timeout));
42static int pipe_setbaudrate PARAMS ((serial_t scb, int rate));
43static int pipe_setstopbits PARAMS ((serial_t scb, int num));
44static int pipe_write PARAMS ((serial_t scb, const char *str, int len));
45/* FIXME: static void pipe_restore PARAMS ((serial_t scb)); */
46static void pipe_close PARAMS ((serial_t scb));
47static serial_ttystate pipe_get_tty_state PARAMS ((serial_t scb));
48static int pipe_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
49static int pipe_return_0 PARAMS ((serial_t));
50static int pipe_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
51 serial_ttystate));
52static void pipe_print_tty_state PARAMS ((serial_t, serial_ttystate));
53
54extern void _initialize_ser_pipe PARAMS ((void));
55
adf40b2e
JM
56#undef XMALLOC
57#define XMALLOC(T) ((T*) xmalloc (sizeof (T)))
58
59
60struct pipe_state
61 {
62 int pid;
63 };
64
daf3f280
JM
65/* Open up a raw pipe */
66
67static int
68pipe_open (scb, name)
69 serial_t scb;
70 const char *name;
71{
96baa820 72#if !defined(O_NONBLOCK) || !defined(F_GETFL) || !defined(F_SETFL) || !HAVE_SOCKETPAIR
daf3f280
JM
73 return -1;
74#else
adf40b2e 75 struct pipe_state *state;
daf3f280 76 /* This chunk: */
daf3f280
JM
77 /* Copyright (c) 1988, 1993
78 * The Regents of the University of California. All rights reserved.
79 *
80 * This code is derived from software written by Ken Arnold and
81 * published in UNIX Review, Vol. 6, No. 8.
82 */
83 int pdes[2];
84 int pid;
85 if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
86 return -1;
87
adf40b2e
JM
88 pid = vfork ();
89
90 /* Error. */
91 if (pid == -1)
daf3f280 92 {
daf3f280
JM
93 close (pdes[0]);
94 close (pdes[1]);
95 return -1;
adf40b2e
JM
96 }
97
98 /* Child. */
99 if (pid == 0)
100 {
101 /* re-wire pdes[1] to stdin/stdout */
daf3f280
JM
102 close (pdes[0]);
103 if (pdes[1] != STDOUT_FILENO)
104 {
105 dup2 (pdes[1], STDOUT_FILENO);
106 close (pdes[1]);
107 }
108 dup2 (STDOUT_FILENO, STDIN_FILENO);
adf40b2e
JM
109#if 0
110 /* close any stray FD's - FIXME - how? */
111 /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
112 from previous popen() calls that remain open in the
113 parent process are closed in the new child process. */
114 for (old = pidlist; old; old = old->next)
115 close (fileno (old->fp)); /* don't allow a flush */
116#endif
daf3f280
JM
117 execl ("/bin/sh", "sh", "-c", name + 1, NULL);
118 _exit (127);
119 }
120
adf40b2e 121 /* Parent. */
daf3f280 122 close (pdes[1]);
adf40b2e
JM
123 /* :end chunk */
124 state = XMALLOC (struct pipe_state);
125 state->pid = pid;
daf3f280 126 scb->fd = pdes[0];
adf40b2e 127 scb->state = state;
daf3f280
JM
128
129 /* Make it non-blocking */
130 {
131 int flags = fcntl (scb->fd, F_GETFL, 0);
132 if (fcntl (scb->fd, F_SETFL, flags | O_NONBLOCK) < 0)
133 {
134 perror ("ser-pipe");
135 pipe_close (scb);
136 return -1;
137 }
138 }
139
140 /* If we don't do this, GDB simply exits when the remote side dies. */
141 signal (SIGPIPE, SIG_IGN);
142 return 0;
143#endif
144}
145
146static serial_ttystate
147pipe_get_tty_state (scb)
148 serial_t scb;
149{
150 /* return garbage */
151 return xmalloc (sizeof (int));
152}
153
154static int
155pipe_set_tty_state (scb, ttystate)
156 serial_t scb;
157 serial_ttystate ttystate;
158{
159 return 0;
160}
161
162static int
163pipe_return_0 (scb)
164 serial_t scb;
165{
166 return 0;
167}
168
169static void
170pipe_raw (scb)
171 serial_t scb;
172{
173 return; /* Always in raw mode */
174}
175
176/* Wait for input on scb, with timeout seconds. Returns 0 on success,
177 otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
178
179 For termio{s}, we actually just setup VTIME if necessary, and let the
180 timeout occur in the read() in pipe_read().
181 */
182
183static int
184wait_for (scb, timeout)
185 serial_t scb;
186 int timeout;
187{
188 int numfds;
189 struct timeval tv;
190 fd_set readfds, exceptfds;
191
192 FD_ZERO (&readfds);
193 FD_ZERO (&exceptfds);
194
195 tv.tv_sec = timeout;
196 tv.tv_usec = 0;
197
198 FD_SET (scb->fd, &readfds);
199 FD_SET (scb->fd, &exceptfds);
200
201 while (1)
202 {
203 if (timeout >= 0)
204 numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
205 else
206 numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
207
208 if (numfds <= 0)
209 {
210 if (numfds == 0)
211 return SERIAL_TIMEOUT;
212 else if (errno == EINTR)
213 continue;
214 else
215 return SERIAL_ERROR; /* Got an error from select or poll */
216 }
217
218 return 0;
219 }
220}
221
222/* Read a character with user-specified timeout. TIMEOUT is number of seconds
223 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
224 char if successful. Returns -2 if timeout expired, EOF if line dropped
225 dead, or -3 for any other error (see errno in that case). */
226
227static int
228pipe_readchar (scb, timeout)
229 serial_t scb;
230 int timeout;
231{
232 int status;
233 int delta;
234
235 if (scb->bufcnt-- > 0)
236 return *scb->bufp++;
237
238 /* We have to be able to keep the GUI alive here, so we break the original
239 timeout into steps of 1 second, running the "keep the GUI alive" hook
240 each time through the loop.
241
242 Also, timeout = 0 means to poll, so we just set the delta to 0, so we
243 will only go through the loop once. */
244
245 delta = (timeout == 0 ? 0 : 1);
246 while (1)
247 {
248
249 /* N.B. The UI may destroy our world (for instance by calling
250 remote_stop,) in which case we want to get out of here as
251 quickly as possible. It is not safe to touch scb, since
252 someone else might have freed it. The ui_loop_hook signals that
253 we should exit by returning 1. */
254
255 if (ui_loop_hook)
256 {
257 if (ui_loop_hook (0))
258 return SERIAL_TIMEOUT;
259 }
260
261 status = wait_for (scb, delta);
262 timeout -= delta;
263
264 /* If we got a character or an error back from wait_for, then we can
265 break from the loop before the timeout is completed. */
266
267 if (status != SERIAL_TIMEOUT)
268 {
269 break;
270 }
271
272 /* If we have exhausted the original timeout, then generate
273 a SERIAL_TIMEOUT, and pass it out of the loop. */
274
275 else if (timeout == 0)
276 {
d4f3574e 277 status = SERIAL_TIMEOUT;
daf3f280
JM
278 break;
279 }
280 }
281
282 if (status < 0)
283 return status;
284
285 while (1)
286 {
287 scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
288 if (scb->bufcnt != -1 || errno != EINTR)
289 break;
290 }
291
292 if (scb->bufcnt <= 0)
293 {
294 if (scb->bufcnt == 0)
295 return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
296 distinguish between EOF & timeouts
297 someday] */
298 else
299 return SERIAL_ERROR; /* Got an error from read */
300 }
301
302 scb->bufcnt--;
303 scb->bufp = scb->buf;
304 return *scb->bufp++;
305}
306
307static int
308pipe_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
309 serial_t scb;
310 serial_ttystate new_ttystate;
311 serial_ttystate old_ttystate;
312{
313 return 0;
314}
315
316static void
317pipe_print_tty_state (scb, ttystate)
318 serial_t scb;
319 serial_ttystate ttystate;
320{
321 /* Nothing to print. */
322 return;
323}
324
325static int
326pipe_setbaudrate (scb, rate)
327 serial_t scb;
328 int rate;
329{
330 return 0; /* Never fails! */
331}
332
333static int
334pipe_setstopbits (scb, num)
335 serial_t scb;
336 int num;
337{
338 return 0; /* Never fails! */
339}
340
341static int
342pipe_write (scb, str, len)
343 serial_t scb;
344 const char *str;
345 int len;
346{
347 int cc;
348
349 while (len > 0)
350 {
351 cc = write (scb->fd, str, len);
352
353 if (cc < 0)
354 return 1;
355 len -= cc;
356 str += cc;
357 }
358 return 0;
359}
360
361static void
362pipe_close (scb)
363 serial_t scb;
364{
adf40b2e
JM
365 struct pipe_state *state = scb->state;
366 if (state != NULL)
367 {
368 int pid = state->pid;
369 close (scb->fd);
370 scb->fd = -1;
371 free (state);
372 scb->state = NULL;
373 kill (pid, SIGTERM);
374 /* Might be useful to check that the child does die. */
375 }
daf3f280
JM
376}
377
378static struct serial_ops pipe_ops =
379{
380 "pipe",
381 0,
382 pipe_open,
383 pipe_close,
384 pipe_readchar,
385 pipe_write,
386 pipe_return_0, /* flush output */
387 pipe_return_0, /* flush input */
388 pipe_return_0, /* send break */
389 pipe_raw,
390 pipe_get_tty_state,
391 pipe_set_tty_state,
392 pipe_print_tty_state,
393 pipe_noflush_set_tty_state,
394 pipe_setbaudrate,
395 pipe_setstopbits,
396 pipe_return_0, /* wait for output to drain */
397};
398
399void
400_initialize_ser_pipe ()
401{
402 serial_add_interface (&pipe_ops);
403}