]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/ser-pipe.c
import gdb-1999-09-08 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 #ifdef HAVE_SYS_WAIT_H
27 #include <sys/wait.h>
28 #endif
29 #include <sys/socket.h>
30 #include <sys/time.h>
31 #include <fcntl.h>
32
33 #include "signals.h"
34 #include "gdb_string.h"
35
36 extern int (*ui_loop_hook) PARAMS ((int));
37
38 static int pipe_open PARAMS ((serial_t scb, const char *name));
39 static void pipe_raw PARAMS ((serial_t scb));
40 static int wait_for PARAMS ((serial_t scb, int timeout));
41 static int pipe_readchar PARAMS ((serial_t scb, int timeout));
42 static int pipe_setbaudrate PARAMS ((serial_t scb, int rate));
43 static int pipe_setstopbits PARAMS ((serial_t scb, int num));
44 static int pipe_write PARAMS ((serial_t scb, const char *str, int len));
45 /* FIXME: static void pipe_restore PARAMS ((serial_t scb)); */
46 static void pipe_close PARAMS ((serial_t scb));
47 static serial_ttystate pipe_get_tty_state PARAMS ((serial_t scb));
48 static int pipe_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
49 static int pipe_return_0 PARAMS ((serial_t));
50 static int pipe_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
51 serial_ttystate));
52 static void pipe_print_tty_state PARAMS ((serial_t, serial_ttystate));
53
54 extern void _initialize_ser_pipe PARAMS ((void));
55
56 #undef XMALLOC
57 #define XMALLOC(T) ((T*) xmalloc (sizeof (T)))
58
59
60 struct pipe_state
61 {
62 int pid;
63 };
64
65 /* Open up a raw pipe */
66
67 static int
68 pipe_open (scb, name)
69 serial_t scb;
70 const char *name;
71 {
72 #if !defined(O_NONBLOCK) || !defined(F_GETFL) || !defined(F_SETFL) || !HAVE_SOCKETPAIR
73 return -1;
74 #else
75 struct pipe_state *state;
76 /* This chunk: */
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
88 pid = vfork ();
89
90 /* Error. */
91 if (pid == -1)
92 {
93 close (pdes[0]);
94 close (pdes[1]);
95 return -1;
96 }
97
98 /* Child. */
99 if (pid == 0)
100 {
101 /* re-wire pdes[1] to stdin/stdout */
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);
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
117 execl ("/bin/sh", "sh", "-c", name + 1, NULL);
118 _exit (127);
119 }
120
121 /* Parent. */
122 close (pdes[1]);
123 /* :end chunk */
124 state = XMALLOC (struct pipe_state);
125 state->pid = pid;
126 scb->fd = pdes[0];
127 scb->state = state;
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
146 static serial_ttystate
147 pipe_get_tty_state (scb)
148 serial_t scb;
149 {
150 /* return garbage */
151 return xmalloc (sizeof (int));
152 }
153
154 static int
155 pipe_set_tty_state (scb, ttystate)
156 serial_t scb;
157 serial_ttystate ttystate;
158 {
159 return 0;
160 }
161
162 static int
163 pipe_return_0 (scb)
164 serial_t scb;
165 {
166 return 0;
167 }
168
169 static void
170 pipe_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
183 static int
184 wait_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
227 static int
228 pipe_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 {
277 status = SERIAL_TIMEOUT;
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
307 static int
308 pipe_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
316 static void
317 pipe_print_tty_state (scb, ttystate)
318 serial_t scb;
319 serial_ttystate ttystate;
320 {
321 /* Nothing to print. */
322 return;
323 }
324
325 static int
326 pipe_setbaudrate (scb, rate)
327 serial_t scb;
328 int rate;
329 {
330 return 0; /* Never fails! */
331 }
332
333 static int
334 pipe_setstopbits (scb, num)
335 serial_t scb;
336 int num;
337 {
338 return 0; /* Never fails! */
339 }
340
341 static int
342 pipe_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
361 static void
362 pipe_close (scb)
363 serial_t scb;
364 {
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 }
376 }
377
378 static 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
399 void
400 _initialize_ser_pipe ()
401 {
402 serial_add_interface (&pipe_ops);
403 }