15796c8dcSSimon Schubert /* Serial interface for a pipe to a separate program 2*cf7f2e2dSJohn Marino Copyright (C) 1999, 2000, 2001, 2007, 2008, 2009, 2010 35796c8dcSSimon Schubert Free Software Foundation, Inc. 45796c8dcSSimon Schubert 55796c8dcSSimon Schubert Contributed by Cygnus Solutions. 65796c8dcSSimon Schubert 75796c8dcSSimon Schubert This file is part of GDB. 85796c8dcSSimon Schubert 95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 125796c8dcSSimon Schubert (at your option) any later version. 135796c8dcSSimon Schubert 145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 175796c8dcSSimon Schubert GNU General Public License for more details. 185796c8dcSSimon Schubert 195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 205796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 215796c8dcSSimon Schubert 225796c8dcSSimon Schubert #include "defs.h" 235796c8dcSSimon Schubert #include "serial.h" 245796c8dcSSimon Schubert #include "ser-base.h" 255796c8dcSSimon Schubert #include "ser-unix.h" 265796c8dcSSimon Schubert 275796c8dcSSimon Schubert #include "gdb_vfork.h" 285796c8dcSSimon Schubert 295796c8dcSSimon Schubert #include <sys/types.h> 305796c8dcSSimon Schubert #include <sys/socket.h> 315796c8dcSSimon Schubert #include <sys/time.h> 325796c8dcSSimon Schubert #include <fcntl.h> 335796c8dcSSimon Schubert #include "gdb_string.h" 345796c8dcSSimon Schubert 355796c8dcSSimon Schubert #include <signal.h> 365796c8dcSSimon Schubert 375796c8dcSSimon Schubert static int pipe_open (struct serial *scb, const char *name); 385796c8dcSSimon Schubert static void pipe_close (struct serial *scb); 395796c8dcSSimon Schubert 405796c8dcSSimon Schubert extern void _initialize_ser_pipe (void); 415796c8dcSSimon Schubert 425796c8dcSSimon Schubert struct pipe_state 435796c8dcSSimon Schubert { 445796c8dcSSimon Schubert int pid; 455796c8dcSSimon Schubert }; 465796c8dcSSimon Schubert 475796c8dcSSimon Schubert /* Open up a raw pipe */ 485796c8dcSSimon Schubert 495796c8dcSSimon Schubert static int 505796c8dcSSimon Schubert pipe_open (struct serial *scb, const char *name) 515796c8dcSSimon Schubert { 525796c8dcSSimon Schubert #if !HAVE_SOCKETPAIR 535796c8dcSSimon Schubert return -1; 545796c8dcSSimon Schubert #else 555796c8dcSSimon Schubert struct pipe_state *state; 565796c8dcSSimon Schubert /* This chunk: */ 575796c8dcSSimon Schubert /* Copyright (c) 1988, 1993 585796c8dcSSimon Schubert * The Regents of the University of California. All rights reserved. 595796c8dcSSimon Schubert * 605796c8dcSSimon Schubert * This code is derived from software written by Ken Arnold and 615796c8dcSSimon Schubert * published in UNIX Review, Vol. 6, No. 8. 625796c8dcSSimon Schubert */ 635796c8dcSSimon Schubert int pdes[2]; 645796c8dcSSimon Schubert int err_pdes[2]; 655796c8dcSSimon Schubert int pid; 66*cf7f2e2dSJohn Marino 675796c8dcSSimon Schubert if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0) 685796c8dcSSimon Schubert return -1; 695796c8dcSSimon Schubert if (socketpair (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0) 70*cf7f2e2dSJohn Marino { 71*cf7f2e2dSJohn Marino close (pdes[0]); 72*cf7f2e2dSJohn Marino close (pdes[1]); 735796c8dcSSimon Schubert return -1; 74*cf7f2e2dSJohn Marino } 755796c8dcSSimon Schubert 765796c8dcSSimon Schubert /* Create the child process to run the command in. Note that the 775796c8dcSSimon Schubert apparent call to vfork() below *might* actually be a call to 785796c8dcSSimon Schubert fork() due to the fact that autoconf will ``#define vfork fork'' 795796c8dcSSimon Schubert on certain platforms. */ 805796c8dcSSimon Schubert pid = vfork (); 815796c8dcSSimon Schubert 825796c8dcSSimon Schubert /* Error. */ 835796c8dcSSimon Schubert if (pid == -1) 845796c8dcSSimon Schubert { 855796c8dcSSimon Schubert close (pdes[0]); 865796c8dcSSimon Schubert close (pdes[1]); 875796c8dcSSimon Schubert close (err_pdes[0]); 885796c8dcSSimon Schubert close (err_pdes[1]); 895796c8dcSSimon Schubert return -1; 905796c8dcSSimon Schubert } 915796c8dcSSimon Schubert 925796c8dcSSimon Schubert if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1) 935796c8dcSSimon Schubert { 945796c8dcSSimon Schubert close (err_pdes[0]); 955796c8dcSSimon Schubert close (err_pdes[1]); 965796c8dcSSimon Schubert err_pdes[0] = err_pdes[1] = -1; 975796c8dcSSimon Schubert } 985796c8dcSSimon Schubert 995796c8dcSSimon Schubert /* Child. */ 1005796c8dcSSimon Schubert if (pid == 0) 1015796c8dcSSimon Schubert { 102*cf7f2e2dSJohn Marino /* We don't want ^c to kill the connection. */ 103*cf7f2e2dSJohn Marino #ifdef HAVE_SETSID 104*cf7f2e2dSJohn Marino pid_t sid = setsid (); 105*cf7f2e2dSJohn Marino if (sid == -1) 106*cf7f2e2dSJohn Marino signal (SIGINT, SIG_IGN); 107*cf7f2e2dSJohn Marino #else 108*cf7f2e2dSJohn Marino signal (SIGINT, SIG_IGN); 109*cf7f2e2dSJohn Marino #endif 110*cf7f2e2dSJohn Marino 1115796c8dcSSimon Schubert /* re-wire pdes[1] to stdin/stdout */ 1125796c8dcSSimon Schubert close (pdes[0]); 1135796c8dcSSimon Schubert if (pdes[1] != STDOUT_FILENO) 1145796c8dcSSimon Schubert { 1155796c8dcSSimon Schubert dup2 (pdes[1], STDOUT_FILENO); 1165796c8dcSSimon Schubert close (pdes[1]); 1175796c8dcSSimon Schubert } 1185796c8dcSSimon Schubert dup2 (STDOUT_FILENO, STDIN_FILENO); 1195796c8dcSSimon Schubert 1205796c8dcSSimon Schubert if (err_pdes[0] != -1) 1215796c8dcSSimon Schubert { 1225796c8dcSSimon Schubert close (err_pdes[0]); 1235796c8dcSSimon Schubert dup2 (err_pdes[1], STDERR_FILENO); 1245796c8dcSSimon Schubert close (err_pdes[1]); 1255796c8dcSSimon Schubert } 1265796c8dcSSimon Schubert #if 0 1275796c8dcSSimon Schubert /* close any stray FD's - FIXME - how? */ 1285796c8dcSSimon Schubert /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams 1295796c8dcSSimon Schubert from previous popen() calls that remain open in the 1305796c8dcSSimon Schubert parent process are closed in the new child process. */ 1315796c8dcSSimon Schubert for (old = pidlist; old; old = old->next) 1325796c8dcSSimon Schubert close (fileno (old->fp)); /* don't allow a flush */ 1335796c8dcSSimon Schubert #endif 1345796c8dcSSimon Schubert execl ("/bin/sh", "sh", "-c", name, (char *) 0); 1355796c8dcSSimon Schubert _exit (127); 1365796c8dcSSimon Schubert } 1375796c8dcSSimon Schubert 1385796c8dcSSimon Schubert /* Parent. */ 1395796c8dcSSimon Schubert close (pdes[1]); 140*cf7f2e2dSJohn Marino if (err_pdes[1] != -1) 141*cf7f2e2dSJohn Marino close (err_pdes[1]); 1425796c8dcSSimon Schubert /* :end chunk */ 1435796c8dcSSimon Schubert state = XMALLOC (struct pipe_state); 1445796c8dcSSimon Schubert state->pid = pid; 1455796c8dcSSimon Schubert scb->fd = pdes[0]; 1465796c8dcSSimon Schubert scb->error_fd = err_pdes[0]; 1475796c8dcSSimon Schubert scb->state = state; 1485796c8dcSSimon Schubert 1495796c8dcSSimon Schubert /* If we don't do this, GDB simply exits when the remote side dies. */ 1505796c8dcSSimon Schubert signal (SIGPIPE, SIG_IGN); 1515796c8dcSSimon Schubert return 0; 1525796c8dcSSimon Schubert #endif 1535796c8dcSSimon Schubert } 1545796c8dcSSimon Schubert 1555796c8dcSSimon Schubert static void 1565796c8dcSSimon Schubert pipe_close (struct serial *scb) 1575796c8dcSSimon Schubert { 1585796c8dcSSimon Schubert struct pipe_state *state = scb->state; 159*cf7f2e2dSJohn Marino 1605796c8dcSSimon Schubert if (state != NULL) 1615796c8dcSSimon Schubert { 1625796c8dcSSimon Schubert int pid = state->pid; 1635796c8dcSSimon Schubert close (scb->fd); 1645796c8dcSSimon Schubert scb->fd = -1; 165*cf7f2e2dSJohn Marino if (scb->error_fd != -1) 166*cf7f2e2dSJohn Marino close (scb->error_fd); 167*cf7f2e2dSJohn Marino scb->error_fd = -1; 1685796c8dcSSimon Schubert xfree (state); 1695796c8dcSSimon Schubert scb->state = NULL; 1705796c8dcSSimon Schubert kill (pid, SIGTERM); 171*cf7f2e2dSJohn Marino /* Might be useful to check that the child does die, 172*cf7f2e2dSJohn Marino and while we're waiting for it to die print any remaining 173*cf7f2e2dSJohn Marino stderr output. */ 1745796c8dcSSimon Schubert } 1755796c8dcSSimon Schubert } 1765796c8dcSSimon Schubert 1775796c8dcSSimon Schubert void 1785796c8dcSSimon Schubert _initialize_ser_pipe (void) 1795796c8dcSSimon Schubert { 1805796c8dcSSimon Schubert struct serial_ops *ops = XMALLOC (struct serial_ops); 181*cf7f2e2dSJohn Marino 1825796c8dcSSimon Schubert memset (ops, 0, sizeof (struct serial_ops)); 1835796c8dcSSimon Schubert ops->name = "pipe"; 1845796c8dcSSimon Schubert ops->next = 0; 1855796c8dcSSimon Schubert ops->open = pipe_open; 1865796c8dcSSimon Schubert ops->close = pipe_close; 1875796c8dcSSimon Schubert ops->readchar = ser_base_readchar; 1885796c8dcSSimon Schubert ops->write = ser_base_write; 1895796c8dcSSimon Schubert ops->flush_output = ser_base_flush_output; 1905796c8dcSSimon Schubert ops->flush_input = ser_base_flush_input; 1915796c8dcSSimon Schubert ops->send_break = ser_base_send_break; 1925796c8dcSSimon Schubert ops->go_raw = ser_base_raw; 1935796c8dcSSimon Schubert ops->get_tty_state = ser_base_get_tty_state; 1945796c8dcSSimon Schubert ops->set_tty_state = ser_base_set_tty_state; 1955796c8dcSSimon Schubert ops->print_tty_state = ser_base_print_tty_state; 1965796c8dcSSimon Schubert ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; 1975796c8dcSSimon Schubert ops->setbaudrate = ser_base_setbaudrate; 1985796c8dcSSimon Schubert ops->setstopbits = ser_base_setstopbits; 1995796c8dcSSimon Schubert ops->drain_output = ser_base_drain_output; 2005796c8dcSSimon Schubert ops->async = ser_base_async; 2015796c8dcSSimon Schubert ops->read_prim = ser_unix_read_prim; 2025796c8dcSSimon Schubert ops->write_prim = ser_unix_write_prim; 2035796c8dcSSimon Schubert serial_add_interface (ops); 2045796c8dcSSimon Schubert } 205