15796c8dcSSimon Schubert /* Serial interface for a pipe to a separate program
2*ef5ccd6cSJohn Marino Copyright (C) 1999-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert
45796c8dcSSimon Schubert Contributed by Cygnus Solutions.
55796c8dcSSimon Schubert
65796c8dcSSimon Schubert This file is part of GDB.
75796c8dcSSimon Schubert
85796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert (at your option) any later version.
125796c8dcSSimon Schubert
135796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
165796c8dcSSimon Schubert GNU General Public License for more details.
175796c8dcSSimon Schubert
185796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
205796c8dcSSimon Schubert
215796c8dcSSimon Schubert #include "defs.h"
225796c8dcSSimon Schubert #include "serial.h"
235796c8dcSSimon Schubert #include "ser-base.h"
245796c8dcSSimon Schubert #include "ser-unix.h"
255796c8dcSSimon Schubert
265796c8dcSSimon Schubert #include "gdb_vfork.h"
275796c8dcSSimon Schubert
285796c8dcSSimon Schubert #include <sys/types.h>
295796c8dcSSimon Schubert #include <sys/socket.h>
305796c8dcSSimon Schubert #include <sys/time.h>
315796c8dcSSimon Schubert #include <fcntl.h>
325796c8dcSSimon Schubert #include "gdb_string.h"
335796c8dcSSimon Schubert
345796c8dcSSimon Schubert #include <signal.h>
355796c8dcSSimon Schubert
365796c8dcSSimon Schubert static int pipe_open (struct serial *scb, const char *name);
375796c8dcSSimon Schubert static void pipe_close (struct serial *scb);
385796c8dcSSimon Schubert
395796c8dcSSimon Schubert extern void _initialize_ser_pipe (void);
405796c8dcSSimon Schubert
415796c8dcSSimon Schubert struct pipe_state
425796c8dcSSimon Schubert {
435796c8dcSSimon Schubert int pid;
445796c8dcSSimon Schubert };
455796c8dcSSimon Schubert
46c50c785cSJohn Marino /* Open up a raw pipe. */
475796c8dcSSimon Schubert
485796c8dcSSimon Schubert static int
pipe_open(struct serial * scb,const char * name)495796c8dcSSimon Schubert pipe_open (struct serial *scb, const char *name)
505796c8dcSSimon Schubert {
515796c8dcSSimon Schubert #if !HAVE_SOCKETPAIR
525796c8dcSSimon Schubert return -1;
535796c8dcSSimon Schubert #else
545796c8dcSSimon Schubert struct pipe_state *state;
555796c8dcSSimon Schubert /* This chunk: */
565796c8dcSSimon Schubert /* Copyright (c) 1988, 1993
575796c8dcSSimon Schubert * The Regents of the University of California. All rights reserved.
585796c8dcSSimon Schubert *
595796c8dcSSimon Schubert * This code is derived from software written by Ken Arnold and
605796c8dcSSimon Schubert * published in UNIX Review, Vol. 6, No. 8.
615796c8dcSSimon Schubert */
625796c8dcSSimon Schubert int pdes[2];
635796c8dcSSimon Schubert int err_pdes[2];
645796c8dcSSimon Schubert int pid;
65cf7f2e2dSJohn Marino
665796c8dcSSimon Schubert if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
675796c8dcSSimon Schubert return -1;
685796c8dcSSimon Schubert if (socketpair (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
69cf7f2e2dSJohn Marino {
70cf7f2e2dSJohn Marino close (pdes[0]);
71cf7f2e2dSJohn Marino close (pdes[1]);
725796c8dcSSimon Schubert return -1;
73cf7f2e2dSJohn Marino }
745796c8dcSSimon Schubert
755796c8dcSSimon Schubert /* Create the child process to run the command in. Note that the
765796c8dcSSimon Schubert apparent call to vfork() below *might* actually be a call to
775796c8dcSSimon Schubert fork() due to the fact that autoconf will ``#define vfork fork''
785796c8dcSSimon Schubert on certain platforms. */
795796c8dcSSimon Schubert pid = vfork ();
805796c8dcSSimon Schubert
815796c8dcSSimon Schubert /* Error. */
825796c8dcSSimon Schubert if (pid == -1)
835796c8dcSSimon Schubert {
845796c8dcSSimon Schubert close (pdes[0]);
855796c8dcSSimon Schubert close (pdes[1]);
865796c8dcSSimon Schubert close (err_pdes[0]);
875796c8dcSSimon Schubert close (err_pdes[1]);
885796c8dcSSimon Schubert return -1;
895796c8dcSSimon Schubert }
905796c8dcSSimon Schubert
915796c8dcSSimon Schubert if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1)
925796c8dcSSimon Schubert {
935796c8dcSSimon Schubert close (err_pdes[0]);
945796c8dcSSimon Schubert close (err_pdes[1]);
955796c8dcSSimon Schubert err_pdes[0] = err_pdes[1] = -1;
965796c8dcSSimon Schubert }
975796c8dcSSimon Schubert
985796c8dcSSimon Schubert /* Child. */
995796c8dcSSimon Schubert if (pid == 0)
1005796c8dcSSimon Schubert {
101cf7f2e2dSJohn Marino /* We don't want ^c to kill the connection. */
102cf7f2e2dSJohn Marino #ifdef HAVE_SETSID
103cf7f2e2dSJohn Marino pid_t sid = setsid ();
104cf7f2e2dSJohn Marino if (sid == -1)
105cf7f2e2dSJohn Marino signal (SIGINT, SIG_IGN);
106cf7f2e2dSJohn Marino #else
107cf7f2e2dSJohn Marino signal (SIGINT, SIG_IGN);
108cf7f2e2dSJohn Marino #endif
109cf7f2e2dSJohn Marino
110c50c785cSJohn Marino /* Re-wire pdes[1] to stdin/stdout. */
1115796c8dcSSimon Schubert close (pdes[0]);
1125796c8dcSSimon Schubert if (pdes[1] != STDOUT_FILENO)
1135796c8dcSSimon Schubert {
1145796c8dcSSimon Schubert dup2 (pdes[1], STDOUT_FILENO);
1155796c8dcSSimon Schubert close (pdes[1]);
1165796c8dcSSimon Schubert }
1175796c8dcSSimon Schubert dup2 (STDOUT_FILENO, STDIN_FILENO);
1185796c8dcSSimon Schubert
1195796c8dcSSimon Schubert if (err_pdes[0] != -1)
1205796c8dcSSimon Schubert {
1215796c8dcSSimon Schubert close (err_pdes[0]);
1225796c8dcSSimon Schubert dup2 (err_pdes[1], STDERR_FILENO);
1235796c8dcSSimon Schubert close (err_pdes[1]);
1245796c8dcSSimon Schubert }
1255796c8dcSSimon Schubert #if 0
1265796c8dcSSimon Schubert /* close any stray FD's - FIXME - how? */
1275796c8dcSSimon Schubert /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
1285796c8dcSSimon Schubert from previous popen() calls that remain open in the
1295796c8dcSSimon Schubert parent process are closed in the new child process. */
1305796c8dcSSimon Schubert for (old = pidlist; old; old = old->next)
131c50c785cSJohn Marino close (fileno (old->fp)); /* Don't allow a flush. */
1325796c8dcSSimon Schubert #endif
1335796c8dcSSimon Schubert execl ("/bin/sh", "sh", "-c", name, (char *) 0);
1345796c8dcSSimon Schubert _exit (127);
1355796c8dcSSimon Schubert }
1365796c8dcSSimon Schubert
1375796c8dcSSimon Schubert /* Parent. */
1385796c8dcSSimon Schubert close (pdes[1]);
139cf7f2e2dSJohn Marino if (err_pdes[1] != -1)
140cf7f2e2dSJohn Marino close (err_pdes[1]);
1415796c8dcSSimon Schubert /* :end chunk */
1425796c8dcSSimon Schubert state = XMALLOC (struct pipe_state);
1435796c8dcSSimon Schubert state->pid = pid;
1445796c8dcSSimon Schubert scb->fd = pdes[0];
1455796c8dcSSimon Schubert scb->error_fd = err_pdes[0];
1465796c8dcSSimon Schubert scb->state = state;
1475796c8dcSSimon Schubert
1485796c8dcSSimon Schubert /* If we don't do this, GDB simply exits when the remote side dies. */
1495796c8dcSSimon Schubert signal (SIGPIPE, SIG_IGN);
1505796c8dcSSimon Schubert return 0;
1515796c8dcSSimon Schubert #endif
1525796c8dcSSimon Schubert }
1535796c8dcSSimon Schubert
1545796c8dcSSimon Schubert static void
pipe_close(struct serial * scb)1555796c8dcSSimon Schubert pipe_close (struct serial *scb)
1565796c8dcSSimon Schubert {
1575796c8dcSSimon Schubert struct pipe_state *state = scb->state;
158cf7f2e2dSJohn Marino
1595796c8dcSSimon Schubert close (scb->fd);
1605796c8dcSSimon Schubert scb->fd = -1;
161c50c785cSJohn Marino
162c50c785cSJohn Marino if (state != NULL)
163c50c785cSJohn Marino {
164*ef5ccd6cSJohn Marino int wait_result, status;
165*ef5ccd6cSJohn Marino
166*ef5ccd6cSJohn Marino /* Don't kill the task right away, give it a chance to shut down cleanly.
167*ef5ccd6cSJohn Marino But don't wait forever though. */
168*ef5ccd6cSJohn Marino #define PIPE_CLOSE_TIMEOUT 5
169*ef5ccd6cSJohn Marino
170c50c785cSJohn Marino /* Assume the program will exit after SIGTERM. Might be
171c50c785cSJohn Marino useful to print any remaining stderr output from
172c50c785cSJohn Marino scb->error_fd while waiting. */
173*ef5ccd6cSJohn Marino #define SIGTERM_TIMEOUT INT_MAX
174*ef5ccd6cSJohn Marino
175*ef5ccd6cSJohn Marino wait_result = -1;
176*ef5ccd6cSJohn Marino #ifdef HAVE_WAITPID
177*ef5ccd6cSJohn Marino wait_result = wait_to_die_with_timeout (state->pid, &status,
178*ef5ccd6cSJohn Marino PIPE_CLOSE_TIMEOUT);
179c50c785cSJohn Marino #endif
180*ef5ccd6cSJohn Marino if (wait_result == -1)
181*ef5ccd6cSJohn Marino {
182*ef5ccd6cSJohn Marino kill (state->pid, SIGTERM);
183*ef5ccd6cSJohn Marino #ifdef HAVE_WAITPID
184*ef5ccd6cSJohn Marino wait_to_die_with_timeout (state->pid, &status, SIGTERM_TIMEOUT);
185*ef5ccd6cSJohn Marino #endif
186*ef5ccd6cSJohn Marino }
187*ef5ccd6cSJohn Marino
188cf7f2e2dSJohn Marino if (scb->error_fd != -1)
189cf7f2e2dSJohn Marino close (scb->error_fd);
190cf7f2e2dSJohn Marino scb->error_fd = -1;
1915796c8dcSSimon Schubert xfree (state);
1925796c8dcSSimon Schubert scb->state = NULL;
1935796c8dcSSimon Schubert }
1945796c8dcSSimon Schubert }
1955796c8dcSSimon Schubert
196c50c785cSJohn Marino int
gdb_pipe(int pdes[2])197c50c785cSJohn Marino gdb_pipe (int pdes[2])
198c50c785cSJohn Marino {
199c50c785cSJohn Marino #if !HAVE_SOCKETPAIR
200c50c785cSJohn Marino errno = ENOSYS;
201c50c785cSJohn Marino return -1;
202c50c785cSJohn Marino #else
203c50c785cSJohn Marino
204c50c785cSJohn Marino if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
205c50c785cSJohn Marino return -1;
206c50c785cSJohn Marino
207c50c785cSJohn Marino /* If we don't do this, GDB simply exits when the remote side
208c50c785cSJohn Marino dies. */
209c50c785cSJohn Marino signal (SIGPIPE, SIG_IGN);
210c50c785cSJohn Marino return 0;
211c50c785cSJohn Marino #endif
212c50c785cSJohn Marino }
213c50c785cSJohn Marino
2145796c8dcSSimon Schubert void
_initialize_ser_pipe(void)2155796c8dcSSimon Schubert _initialize_ser_pipe (void)
2165796c8dcSSimon Schubert {
2175796c8dcSSimon Schubert struct serial_ops *ops = XMALLOC (struct serial_ops);
218cf7f2e2dSJohn Marino
2195796c8dcSSimon Schubert memset (ops, 0, sizeof (struct serial_ops));
2205796c8dcSSimon Schubert ops->name = "pipe";
2215796c8dcSSimon Schubert ops->next = 0;
2225796c8dcSSimon Schubert ops->open = pipe_open;
2235796c8dcSSimon Schubert ops->close = pipe_close;
2245796c8dcSSimon Schubert ops->readchar = ser_base_readchar;
2255796c8dcSSimon Schubert ops->write = ser_base_write;
2265796c8dcSSimon Schubert ops->flush_output = ser_base_flush_output;
2275796c8dcSSimon Schubert ops->flush_input = ser_base_flush_input;
2285796c8dcSSimon Schubert ops->send_break = ser_base_send_break;
2295796c8dcSSimon Schubert ops->go_raw = ser_base_raw;
2305796c8dcSSimon Schubert ops->get_tty_state = ser_base_get_tty_state;
231c50c785cSJohn Marino ops->copy_tty_state = ser_base_copy_tty_state;
2325796c8dcSSimon Schubert ops->set_tty_state = ser_base_set_tty_state;
2335796c8dcSSimon Schubert ops->print_tty_state = ser_base_print_tty_state;
2345796c8dcSSimon Schubert ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
2355796c8dcSSimon Schubert ops->setbaudrate = ser_base_setbaudrate;
2365796c8dcSSimon Schubert ops->setstopbits = ser_base_setstopbits;
2375796c8dcSSimon Schubert ops->drain_output = ser_base_drain_output;
2385796c8dcSSimon Schubert ops->async = ser_base_async;
2395796c8dcSSimon Schubert ops->read_prim = ser_unix_read_prim;
2405796c8dcSSimon Schubert ops->write_prim = ser_unix_write_prim;
2415796c8dcSSimon Schubert serial_add_interface (ops);
2425796c8dcSSimon Schubert }
243