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