Consistent use of (C) after "Copyright".
[deliverable/binutils-gdb.git] / gdb / ser-pipe.c
CommitLineData
daf3f280 1/* Serial interface for a pipe to a separate program
28e7fd62 2 Copyright (C) 1999-2013 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
c378eb4e 46/* Open up a raw pipe. */
daf3f280
JM
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 64 int pid;
433759f7 65
daf3f280
JM
66 if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
67 return -1;
65cc4390 68 if (socketpair (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
ff9f22f1
DE
69 {
70 close (pdes[0]);
71 close (pdes[1]);
72 return -1;
73 }
daf3f280 74
7700434b
KB
75 /* Create the child process to run the command in. Note that the
76 apparent call to vfork() below *might* actually be a call to
77 fork() due to the fact that autoconf will ``#define vfork fork''
78 on certain platforms. */
adf40b2e
JM
79 pid = vfork ();
80
c378eb4e 81 /* Error. */
adf40b2e 82 if (pid == -1)
daf3f280 83 {
daf3f280
JM
84 close (pdes[0]);
85 close (pdes[1]);
65cc4390
VP
86 close (err_pdes[0]);
87 close (err_pdes[1]);
daf3f280 88 return -1;
adf40b2e
JM
89 }
90
65cc4390
VP
91 if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1)
92 {
93 close (err_pdes[0]);
94 close (err_pdes[1]);
95 err_pdes[0] = err_pdes[1] = -1;
96 }
97
c378eb4e 98 /* Child. */
adf40b2e
JM
99 if (pid == 0)
100 {
e34838f0
DE
101 /* We don't want ^c to kill the connection. */
102#ifdef HAVE_SETSID
103 pid_t sid = setsid ();
104 if (sid == -1)
105 signal (SIGINT, SIG_IGN);
106#else
107 signal (SIGINT, SIG_IGN);
108#endif
109
c378eb4e 110 /* Re-wire pdes[1] to stdin/stdout. */
daf3f280
JM
111 close (pdes[0]);
112 if (pdes[1] != STDOUT_FILENO)
113 {
114 dup2 (pdes[1], STDOUT_FILENO);
115 close (pdes[1]);
116 }
117 dup2 (STDOUT_FILENO, STDIN_FILENO);
65cc4390
VP
118
119 if (err_pdes[0] != -1)
120 {
121 close (err_pdes[0]);
122 dup2 (err_pdes[1], STDERR_FILENO);
123 close (err_pdes[1]);
124 }
adf40b2e 125#if 0
c378eb4e 126 /* close any stray FD's - FIXME - how? */
adf40b2e
JM
127 /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
128 from previous popen() calls that remain open in the
c378eb4e 129 parent process are closed in the new child process. */
adf40b2e 130 for (old = pidlist; old; old = old->next)
c378eb4e 131 close (fileno (old->fp)); /* Don't allow a flush. */
adf40b2e 132#endif
36662fde 133 execl ("/bin/sh", "sh", "-c", name, (char *) 0);
daf3f280
JM
134 _exit (127);
135 }
136
c378eb4e 137 /* Parent. */
daf3f280 138 close (pdes[1]);
ff9f22f1
DE
139 if (err_pdes[1] != -1)
140 close (err_pdes[1]);
adf40b2e
JM
141 /* :end chunk */
142 state = XMALLOC (struct pipe_state);
143 state->pid = pid;
daf3f280 144 scb->fd = pdes[0];
65cc4390 145 scb->error_fd = err_pdes[0];
adf40b2e 146 scb->state = state;
daf3f280 147
daf3f280
JM
148 /* If we don't do this, GDB simply exits when the remote side dies. */
149 signal (SIGPIPE, SIG_IGN);
150 return 0;
151#endif
152}
153
daf3f280 154static void
819cc324 155pipe_close (struct serial *scb)
daf3f280 156{
adf40b2e 157 struct pipe_state *state = scb->state;
433759f7 158
58f07bae
PA
159 close (scb->fd);
160 scb->fd = -1;
161
adf40b2e
JM
162 if (state != NULL)
163 {
0b6cb71e
DE
164 int wait_result, status;
165
166 /* Don't kill the task right away, give it a chance to shut down cleanly.
167 But don't wait forever though. */
168#define PIPE_CLOSE_TIMEOUT 5
169
0a4f61e3
DJ
170 /* Assume the program will exit after SIGTERM. Might be
171 useful to print any remaining stderr output from
172 scb->error_fd while waiting. */
0b6cb71e
DE
173#define SIGTERM_TIMEOUT INT_MAX
174
175 wait_result = -1;
176#ifdef HAVE_WAITPID
177 wait_result = wait_to_die_with_timeout (state->pid, &status,
178 PIPE_CLOSE_TIMEOUT);
0a4f61e3 179#endif
0b6cb71e
DE
180 if (wait_result == -1)
181 {
182 kill (state->pid, SIGTERM);
183#ifdef HAVE_WAITPID
184 wait_to_die_with_timeout (state->pid, &status, SIGTERM_TIMEOUT);
185#endif
186 }
187
ff9f22f1
DE
188 if (scb->error_fd != -1)
189 close (scb->error_fd);
190 scb->error_fd = -1;
b8c9b27d 191 xfree (state);
adf40b2e 192 scb->state = NULL;
adf40b2e 193 }
daf3f280
JM
194}
195
58f07bae
PA
196int
197gdb_pipe (int pdes[2])
198{
199#if !HAVE_SOCKETPAIR
200 errno = ENOSYS;
201 return -1;
202#else
203
204 if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
205 return -1;
206
207 /* If we don't do this, GDB simply exits when the remote side
208 dies. */
209 signal (SIGPIPE, SIG_IGN);
210 return 0;
211#endif
212}
213
daf3f280 214void
c2c6d25f 215_initialize_ser_pipe (void)
daf3f280 216{
c2c6d25f 217 struct serial_ops *ops = XMALLOC (struct serial_ops);
433759f7 218
2fdbdd39 219 memset (ops, 0, sizeof (struct serial_ops));
c2c6d25f
JM
220 ops->name = "pipe";
221 ops->next = 0;
222 ops->open = pipe_open;
223 ops->close = pipe_close;
b4505029 224 ops->readchar = ser_base_readchar;
dd5da072
MM
225 ops->write = ser_base_write;
226 ops->flush_output = ser_base_flush_output;
227 ops->flush_input = ser_base_flush_input;
228 ops->send_break = ser_base_send_break;
229 ops->go_raw = ser_base_raw;
230 ops->get_tty_state = ser_base_get_tty_state;
1e182ce8 231 ops->copy_tty_state = ser_base_copy_tty_state;
dd5da072
MM
232 ops->set_tty_state = ser_base_set_tty_state;
233 ops->print_tty_state = ser_base_print_tty_state;
234 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
235 ops->setbaudrate = ser_base_setbaudrate;
236 ops->setstopbits = ser_base_setstopbits;
237 ops->drain_output = ser_base_drain_output;
238 ops->async = ser_base_async;
b4505029
MM
239 ops->read_prim = ser_unix_read_prim;
240 ops->write_prim = ser_unix_write_prim;
c2c6d25f 241 serial_add_interface (ops);
daf3f280 242}
This page took 1.221999 seconds and 4 git commands to generate.