This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.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 }