replace XZALLOC with XCNEW
[deliverable/binutils-gdb.git] / gdb / ser-pipe.c
CommitLineData
daf3f280 1/* Serial interface for a pipe to a separate program
ecd75fc8 2 Copyright (C) 1999-2014 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>
0e9f083f 32#include <string.h>
614c279d 33#include "filestuff.h"
daf3f280 34
042be3a9 35#include <signal.h>
daf3f280 36
819cc324
AC
37static int pipe_open (struct serial *scb, const char *name);
38static void pipe_close (struct serial *scb);
adf40b2e 39
c2c6d25f 40extern void _initialize_ser_pipe (void);
adf40b2e
JM
41
42struct pipe_state
43 {
44 int pid;
45 };
46
c378eb4e 47/* Open up a raw pipe. */
daf3f280
JM
48
49static int
819cc324 50pipe_open (struct serial *scb, const char *name)
daf3f280 51{
2acceee2 52#if !HAVE_SOCKETPAIR
daf3f280
JM
53 return -1;
54#else
adf40b2e 55 struct pipe_state *state;
daf3f280 56 /* This chunk: */
daf3f280
JM
57 /* Copyright (c) 1988, 1993
58 * The Regents of the University of California. All rights reserved.
59 *
60 * This code is derived from software written by Ken Arnold and
61 * published in UNIX Review, Vol. 6, No. 8.
62 */
63 int pdes[2];
65cc4390 64 int err_pdes[2];
daf3f280 65 int pid;
433759f7 66
614c279d 67 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
daf3f280 68 return -1;
614c279d 69 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
ff9f22f1
DE
70 {
71 close (pdes[0]);
72 close (pdes[1]);
73 return -1;
74 }
daf3f280 75
7700434b
KB
76 /* Create the child process to run the command in. Note that the
77 apparent call to vfork() below *might* actually be a call to
78 fork() due to the fact that autoconf will ``#define vfork fork''
79 on certain platforms. */
adf40b2e
JM
80 pid = vfork ();
81
c378eb4e 82 /* Error. */
adf40b2e 83 if (pid == -1)
daf3f280 84 {
daf3f280
JM
85 close (pdes[0]);
86 close (pdes[1]);
65cc4390
VP
87 close (err_pdes[0]);
88 close (err_pdes[1]);
daf3f280 89 return -1;
adf40b2e
JM
90 }
91
65cc4390
VP
92 if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1)
93 {
94 close (err_pdes[0]);
95 close (err_pdes[1]);
96 err_pdes[0] = err_pdes[1] = -1;
97 }
98
c378eb4e 99 /* Child. */
adf40b2e
JM
100 if (pid == 0)
101 {
e34838f0
DE
102 /* We don't want ^c to kill the connection. */
103#ifdef HAVE_SETSID
104 pid_t sid = setsid ();
105 if (sid == -1)
106 signal (SIGINT, SIG_IGN);
107#else
108 signal (SIGINT, SIG_IGN);
109#endif
110
c378eb4e 111 /* Re-wire pdes[1] to stdin/stdout. */
daf3f280
JM
112 close (pdes[0]);
113 if (pdes[1] != STDOUT_FILENO)
114 {
115 dup2 (pdes[1], STDOUT_FILENO);
116 close (pdes[1]);
117 }
118 dup2 (STDOUT_FILENO, STDIN_FILENO);
65cc4390
VP
119
120 if (err_pdes[0] != -1)
121 {
122 close (err_pdes[0]);
123 dup2 (err_pdes[1], STDERR_FILENO);
124 close (err_pdes[1]);
125 }
614c279d
TT
126
127 close_most_fds ();
36662fde 128 execl ("/bin/sh", "sh", "-c", name, (char *) 0);
daf3f280
JM
129 _exit (127);
130 }
131
c378eb4e 132 /* Parent. */
daf3f280 133 close (pdes[1]);
ff9f22f1
DE
134 if (err_pdes[1] != -1)
135 close (err_pdes[1]);
adf40b2e
JM
136 /* :end chunk */
137 state = XMALLOC (struct pipe_state);
138 state->pid = pid;
daf3f280 139 scb->fd = pdes[0];
65cc4390 140 scb->error_fd = err_pdes[0];
adf40b2e 141 scb->state = state;
daf3f280 142
daf3f280
JM
143 /* If we don't do this, GDB simply exits when the remote side dies. */
144 signal (SIGPIPE, SIG_IGN);
145 return 0;
146#endif
147}
148
daf3f280 149static void
819cc324 150pipe_close (struct serial *scb)
daf3f280 151{
adf40b2e 152 struct pipe_state *state = scb->state;
433759f7 153
58f07bae
PA
154 close (scb->fd);
155 scb->fd = -1;
156
adf40b2e
JM
157 if (state != NULL)
158 {
0b6cb71e
DE
159 int wait_result, status;
160
161 /* Don't kill the task right away, give it a chance to shut down cleanly.
162 But don't wait forever though. */
163#define PIPE_CLOSE_TIMEOUT 5
164
0a4f61e3
DJ
165 /* Assume the program will exit after SIGTERM. Might be
166 useful to print any remaining stderr output from
167 scb->error_fd while waiting. */
0b6cb71e
DE
168#define SIGTERM_TIMEOUT INT_MAX
169
170 wait_result = -1;
171#ifdef HAVE_WAITPID
172 wait_result = wait_to_die_with_timeout (state->pid, &status,
173 PIPE_CLOSE_TIMEOUT);
0a4f61e3 174#endif
0b6cb71e
DE
175 if (wait_result == -1)
176 {
177 kill (state->pid, SIGTERM);
178#ifdef HAVE_WAITPID
179 wait_to_die_with_timeout (state->pid, &status, SIGTERM_TIMEOUT);
180#endif
181 }
182
ff9f22f1
DE
183 if (scb->error_fd != -1)
184 close (scb->error_fd);
185 scb->error_fd = -1;
b8c9b27d 186 xfree (state);
adf40b2e 187 scb->state = NULL;
adf40b2e 188 }
daf3f280
JM
189}
190
58f07bae
PA
191int
192gdb_pipe (int pdes[2])
193{
194#if !HAVE_SOCKETPAIR
195 errno = ENOSYS;
196 return -1;
197#else
198
614c279d 199 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
58f07bae
PA
200 return -1;
201
202 /* If we don't do this, GDB simply exits when the remote side
203 dies. */
204 signal (SIGPIPE, SIG_IGN);
205 return 0;
206#endif
207}
208
12e8c7d7
TT
209static const struct serial_ops pipe_ops =
210{
211 "pipe",
212 pipe_open,
213 pipe_close,
214 NULL,
215 ser_base_readchar,
216 ser_base_write,
217 ser_base_flush_output,
218 ser_base_flush_input,
219 ser_base_send_break,
220 ser_base_raw,
221 ser_base_get_tty_state,
222 ser_base_copy_tty_state,
223 ser_base_set_tty_state,
224 ser_base_print_tty_state,
225 ser_base_noflush_set_tty_state,
226 ser_base_setbaudrate,
227 ser_base_setstopbits,
228 ser_base_drain_output,
229 ser_base_async,
230 ser_unix_read_prim,
231 ser_unix_write_prim
232};
233
daf3f280 234void
c2c6d25f 235_initialize_ser_pipe (void)
daf3f280 236{
12e8c7d7 237 serial_add_interface (&pipe_ops);
daf3f280 238}
This page took 2.05171 seconds and 4 git commands to generate.