198944Sobrien/* Serial interface for a pipe to a separate program 298944Sobrien Copyright 1999, 2000, 2001 Free Software Foundation, Inc. 398944Sobrien 498944Sobrien Contributed by Cygnus Solutions. 598944Sobrien 698944Sobrien This file is part of GDB. 798944Sobrien 898944Sobrien This program is free software; you can redistribute it and/or modify 998944Sobrien it under the terms of the GNU General Public License as published by 1098944Sobrien the Free Software Foundation; either version 2 of the License, or 1198944Sobrien (at your option) any later version. 1298944Sobrien 1398944Sobrien This program is distributed in the hope that it will be useful, 1498944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1598944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698944Sobrien GNU General Public License for more details. 1798944Sobrien 1898944Sobrien You should have received a copy of the GNU General Public License 1998944Sobrien along with this program; if not, write to the Free Software 2098944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2198944Sobrien Boston, MA 02111-1307, USA. */ 2298944Sobrien 2398944Sobrien#include "defs.h" 2498944Sobrien#include "serial.h" 2598944Sobrien#include "ser-unix.h" 2698944Sobrien 2798944Sobrien#include "gdb_vfork.h" 2898944Sobrien 2998944Sobrien#include <sys/types.h> 3098944Sobrien#include <sys/socket.h> 3198944Sobrien#include <sys/time.h> 3298944Sobrien#include <fcntl.h> 3398944Sobrien#include "gdb_string.h" 3498944Sobrien 3598944Sobrien#include <signal.h> 3698944Sobrien 3798944Sobrienstatic int pipe_open (struct serial *scb, const char *name); 3898944Sobrienstatic void pipe_close (struct serial *scb); 3998944Sobrien 4098944Sobrienextern void _initialize_ser_pipe (void); 4198944Sobrien 4298944Sobrienstruct pipe_state 4398944Sobrien { 4498944Sobrien int pid; 4598944Sobrien }; 4698944Sobrien 4798944Sobrien/* Open up a raw pipe */ 4898944Sobrien 4998944Sobrienstatic int 5098944Sobrienpipe_open (struct serial *scb, const char *name) 5198944Sobrien{ 5298944Sobrien#if !HAVE_SOCKETPAIR 5398944Sobrien return -1; 5498944Sobrien#else 5598944Sobrien struct pipe_state *state; 5698944Sobrien /* This chunk: */ 5798944Sobrien /* Copyright (c) 1988, 1993 5898944Sobrien * The Regents of the University of California. All rights reserved. 5998944Sobrien * 6098944Sobrien * This code is derived from software written by Ken Arnold and 6198944Sobrien * published in UNIX Review, Vol. 6, No. 8. 6298944Sobrien */ 6398944Sobrien int pdes[2]; 6498944Sobrien int pid; 6598944Sobrien if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0) 6698944Sobrien return -1; 6798944Sobrien 6898944Sobrien /* Create the child process to run the command in. Note that the 6998944Sobrien apparent call to vfork() below *might* actually be a call to 7098944Sobrien fork() due to the fact that autoconf will ``#define vfork fork'' 7198944Sobrien on certain platforms. */ 7298944Sobrien pid = vfork (); 7398944Sobrien 7498944Sobrien /* Error. */ 7598944Sobrien if (pid == -1) 7698944Sobrien { 7798944Sobrien close (pdes[0]); 7898944Sobrien close (pdes[1]); 7998944Sobrien return -1; 8098944Sobrien } 8198944Sobrien 8298944Sobrien /* Child. */ 8398944Sobrien if (pid == 0) 8498944Sobrien { 8598944Sobrien /* re-wire pdes[1] to stdin/stdout */ 8698944Sobrien close (pdes[0]); 8798944Sobrien if (pdes[1] != STDOUT_FILENO) 8898944Sobrien { 8998944Sobrien dup2 (pdes[1], STDOUT_FILENO); 9098944Sobrien close (pdes[1]); 9198944Sobrien } 9298944Sobrien dup2 (STDOUT_FILENO, STDIN_FILENO); 9398944Sobrien#if 0 9498944Sobrien /* close any stray FD's - FIXME - how? */ 9598944Sobrien /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams 9698944Sobrien from previous popen() calls that remain open in the 9798944Sobrien parent process are closed in the new child process. */ 9898944Sobrien for (old = pidlist; old; old = old->next) 9998944Sobrien close (fileno (old->fp)); /* don't allow a flush */ 10098944Sobrien#endif 101130803Smarcel execl ("/bin/sh", "sh", "-c", name, (char *) 0); 10298944Sobrien _exit (127); 10398944Sobrien } 10498944Sobrien 10598944Sobrien /* Parent. */ 10698944Sobrien close (pdes[1]); 10798944Sobrien /* :end chunk */ 10898944Sobrien state = XMALLOC (struct pipe_state); 10998944Sobrien state->pid = pid; 11098944Sobrien scb->fd = pdes[0]; 11198944Sobrien scb->state = state; 11298944Sobrien 11398944Sobrien /* If we don't do this, GDB simply exits when the remote side dies. */ 11498944Sobrien signal (SIGPIPE, SIG_IGN); 11598944Sobrien return 0; 11698944Sobrien#endif 11798944Sobrien} 11898944Sobrien 11998944Sobrienstatic void 12098944Sobrienpipe_close (struct serial *scb) 12198944Sobrien{ 12298944Sobrien struct pipe_state *state = scb->state; 12398944Sobrien if (state != NULL) 12498944Sobrien { 12598944Sobrien int pid = state->pid; 12698944Sobrien close (scb->fd); 12798944Sobrien scb->fd = -1; 12898944Sobrien xfree (state); 12998944Sobrien scb->state = NULL; 13098944Sobrien kill (pid, SIGTERM); 13198944Sobrien /* Might be useful to check that the child does die. */ 13298944Sobrien } 13398944Sobrien} 13498944Sobrien 13598944Sobrienstatic struct serial_ops pipe_ops; 13698944Sobrien 13798944Sobrienvoid 13898944Sobrien_initialize_ser_pipe (void) 13998944Sobrien{ 14098944Sobrien struct serial_ops *ops = XMALLOC (struct serial_ops); 141130803Smarcel memset (ops, 0, sizeof (struct serial_ops)); 14298944Sobrien ops->name = "pipe"; 14398944Sobrien ops->next = 0; 14498944Sobrien ops->open = pipe_open; 14598944Sobrien ops->close = pipe_close; 14698944Sobrien ops->readchar = ser_unix_readchar; 14798944Sobrien ops->write = ser_unix_write; 14898944Sobrien ops->flush_output = ser_unix_nop_flush_output; 14998944Sobrien ops->flush_input = ser_unix_flush_input; 15098944Sobrien ops->send_break = ser_unix_nop_send_break; 15198944Sobrien ops->go_raw = ser_unix_nop_raw; 15298944Sobrien ops->get_tty_state = ser_unix_nop_get_tty_state; 15398944Sobrien ops->set_tty_state = ser_unix_nop_set_tty_state; 15498944Sobrien ops->print_tty_state = ser_unix_nop_print_tty_state; 15598944Sobrien ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state; 15698944Sobrien ops->setbaudrate = ser_unix_nop_setbaudrate; 15798944Sobrien ops->setstopbits = ser_unix_nop_setstopbits; 15898944Sobrien ops->drain_output = ser_unix_nop_drain_output; 15998944Sobrien ops->async = ser_unix_async; 16098944Sobrien serial_add_interface (ops); 16198944Sobrien} 162