]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ser-pipe.c
This commit was manufactured by cvs2svn to create branch
[thirdparty/binutils-gdb.git] / gdb / ser-pipe.c
CommitLineData
daf3f280 1/* Serial interface for a pipe to a separate program
9b254dd1 2 Copyright (C) 1999, 2000, 2001, 2007, 2008 Free Software Foundation, Inc.
daf3f280
JM
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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
daf3f280
JM
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
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
daf3f280
JM
20
21#include "defs.h"
22#include "serial.h"
3eb25fda 23#include "ser-base.h"
c2c6d25f
JM
24#include "ser-unix.h"
25
74c1b268
AC
26#include "gdb_vfork.h"
27
daf3f280 28#include <sys/types.h>
daf3f280
JM
29#include <sys/socket.h>
30#include <sys/time.h>
31#include <fcntl.h>
27b82ed2 32#include "gdb_string.h"
daf3f280 33
042be3a9 34#include <signal.h>
daf3f280 35
819cc324
AC
36static int pipe_open (struct serial *scb, const char *name);
37static void pipe_close (struct serial *scb);
adf40b2e 38
c2c6d25f 39extern void _initialize_ser_pipe (void);
adf40b2e
JM
40
41struct pipe_state
42 {
43 int pid;
44 };
45
daf3f280
JM
46/* Open up a raw pipe */
47
48static int
819cc324 49pipe_open (struct serial *scb, const char *name)
daf3f280 50{
2acceee2 51#if !HAVE_SOCKETPAIR
daf3f280
JM
52 return -1;
53#else
adf40b2e 54 struct pipe_state *state;
daf3f280 55 /* This chunk: */
daf3f280
JM
56 /* Copyright (c) 1988, 1993
57 * The Regents of the University of California. All rights reserved.
58 *
59 * This code is derived from software written by Ken Arnold and
60 * published in UNIX Review, Vol. 6, No. 8.
61 */
62 int pdes[2];
65cc4390 63 int err_pdes[2];
daf3f280
JM
64 int pid;
65 if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
66 return -1;
65cc4390
VP
67 if (socketpair (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
68 return -1;
daf3f280 69
7700434b
KB
70 /* Create the child process to run the command in. Note that the
71 apparent call to vfork() below *might* actually be a call to
72 fork() due to the fact that autoconf will ``#define vfork fork''
73 on certain platforms. */
adf40b2e
JM
74 pid = vfork ();
75
76 /* Error. */
77 if (pid == -1)
daf3f280 78 {
daf3f280
JM
79 close (pdes[0]);
80 close (pdes[1]);
65cc4390
VP
81 close (err_pdes[0]);
82 close (err_pdes[1]);
daf3f280 83 return -1;
adf40b2e
JM
84 }
85
65cc4390
VP
86 if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1)
87 {
88 close (err_pdes[0]);
89 close (err_pdes[1]);
90 err_pdes[0] = err_pdes[1] = -1;
91 }
92
adf40b2e
JM
93 /* Child. */
94 if (pid == 0)
95 {
96 /* re-wire pdes[1] to stdin/stdout */
daf3f280
JM
97 close (pdes[0]);
98 if (pdes[1] != STDOUT_FILENO)
99 {
100 dup2 (pdes[1], STDOUT_FILENO);
101 close (pdes[1]);
102 }
103 dup2 (STDOUT_FILENO, STDIN_FILENO);
65cc4390
VP
104
105 if (err_pdes[0] != -1)
106 {
107 close (err_pdes[0]);
108 dup2 (err_pdes[1], STDERR_FILENO);
109 close (err_pdes[1]);
110 }
adf40b2e
JM
111#if 0
112 /* close any stray FD's - FIXME - how? */
113 /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
114 from previous popen() calls that remain open in the
115 parent process are closed in the new child process. */
116 for (old = pidlist; old; old = old->next)
117 close (fileno (old->fp)); /* don't allow a flush */
118#endif
36662fde 119 execl ("/bin/sh", "sh", "-c", name, (char *) 0);
daf3f280
JM
120 _exit (127);
121 }
122
adf40b2e 123 /* Parent. */
daf3f280 124 close (pdes[1]);
adf40b2e
JM
125 /* :end chunk */
126 state = XMALLOC (struct pipe_state);
127 state->pid = pid;
daf3f280 128 scb->fd = pdes[0];
65cc4390 129 scb->error_fd = err_pdes[0];
adf40b2e 130 scb->state = state;
daf3f280 131
daf3f280
JM
132 /* If we don't do this, GDB simply exits when the remote side dies. */
133 signal (SIGPIPE, SIG_IGN);
134 return 0;
135#endif
136}
137
daf3f280 138static void
819cc324 139pipe_close (struct serial *scb)
daf3f280 140{
adf40b2e
JM
141 struct pipe_state *state = scb->state;
142 if (state != NULL)
143 {
144 int pid = state->pid;
145 close (scb->fd);
146 scb->fd = -1;
b8c9b27d 147 xfree (state);
adf40b2e
JM
148 scb->state = NULL;
149 kill (pid, SIGTERM);
150 /* Might be useful to check that the child does die. */
151 }
daf3f280
JM
152}
153
c2c6d25f 154static struct serial_ops pipe_ops;
daf3f280
JM
155
156void
c2c6d25f 157_initialize_ser_pipe (void)
daf3f280 158{
c2c6d25f 159 struct serial_ops *ops = XMALLOC (struct serial_ops);
2fdbdd39 160 memset (ops, 0, sizeof (struct serial_ops));
c2c6d25f
JM
161 ops->name = "pipe";
162 ops->next = 0;
163 ops->open = pipe_open;
164 ops->close = pipe_close;
b4505029 165 ops->readchar = ser_base_readchar;
dd5da072
MM
166 ops->write = ser_base_write;
167 ops->flush_output = ser_base_flush_output;
168 ops->flush_input = ser_base_flush_input;
169 ops->send_break = ser_base_send_break;
170 ops->go_raw = ser_base_raw;
171 ops->get_tty_state = ser_base_get_tty_state;
172 ops->set_tty_state = ser_base_set_tty_state;
173 ops->print_tty_state = ser_base_print_tty_state;
174 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
175 ops->setbaudrate = ser_base_setbaudrate;
176 ops->setstopbits = ser_base_setstopbits;
177 ops->drain_output = ser_base_drain_output;
178 ops->async = ser_base_async;
b4505029
MM
179 ops->read_prim = ser_unix_read_prim;
180 ops->write_prim = ser_unix_write_prim;
c2c6d25f 181 serial_add_interface (ops);
daf3f280 182}