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