]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ser-pipe.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / ser-pipe.c
CommitLineData
daf3f280 1/* Serial interface for a pipe to a separate program
d01e8234 2 Copyright (C) 1999-2025 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 20
daf3f280 21#include "serial.h"
3eb25fda 22#include "ser-base.h"
c2c6d25f
JM
23#include "ser-unix.h"
24
74c1b268
AC
25#include "gdb_vfork.h"
26
daf3f280 27#include <sys/types.h>
daf3f280 28#include <sys/socket.h>
268a13a5 29#include "gdbsupport/gdb_sys_time.h"
daf3f280 30#include <fcntl.h>
268a13a5 31#include "gdbsupport/filestuff.h"
906e2b76 32#include "gdbsupport/pathstuff.h"
daf3f280 33
042be3a9 34#include <signal.h>
daf3f280 35
819cc324 36static void pipe_close (struct serial *scb);
adf40b2e 37
adf40b2e
JM
38struct pipe_state
39 {
40 int pid;
41 };
42
c378eb4e 43/* Open up a raw pipe. */
daf3f280 44
a2e0acea 45static void
819cc324 46pipe_open (struct serial *scb, const char *name)
daf3f280 47{
2acceee2 48#if !HAVE_SOCKETPAIR
daf3f280
JM
49 return -1;
50#else
adf40b2e 51 struct pipe_state *state;
daf3f280 52 /* This chunk: */
daf3f280
JM
53 /* Copyright (c) 1988, 1993
54 * The Regents of the University of California. All rights reserved.
55 *
56 * This code is derived from software written by Ken Arnold and
57 * published in UNIX Review, Vol. 6, No. 8.
58 */
59 int pdes[2];
65cc4390 60 int err_pdes[2];
daf3f280 61 int pid;
433759f7 62
cced7cac
AB
63 if (*name == '|')
64 {
65 name++;
66 name = skip_spaces (name);
67 }
68
614c279d 69 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
a2e0acea 70 perror_with_name (_("could not open socket pair"));
614c279d 71 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
ff9f22f1 72 {
a2e0acea 73 int save = errno;
ff9f22f1
DE
74 close (pdes[0]);
75 close (pdes[1]);
a2e0acea 76 perror_with_name (_("could not open socket pair"), save);
ff9f22f1 77 }
daf3f280 78
7700434b
KB
79 /* Create the child process to run the command in. Note that the
80 apparent call to vfork() below *might* actually be a call to
81 fork() due to the fact that autoconf will ``#define vfork fork''
82 on certain platforms. */
adf40b2e
JM
83 pid = vfork ();
84
c378eb4e 85 /* Error. */
adf40b2e 86 if (pid == -1)
daf3f280 87 {
a2e0acea 88 int save = errno;
daf3f280
JM
89 close (pdes[0]);
90 close (pdes[1]);
65cc4390
VP
91 close (err_pdes[0]);
92 close (err_pdes[1]);
a2e0acea 93 perror_with_name (_("could not vfork"), save);
adf40b2e
JM
94 }
95
65cc4390
VP
96 if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1)
97 {
98 close (err_pdes[0]);
99 close (err_pdes[1]);
100 err_pdes[0] = err_pdes[1] = -1;
101 }
102
c378eb4e 103 /* Child. */
adf40b2e
JM
104 if (pid == 0)
105 {
e34838f0
DE
106 /* We don't want ^c to kill the connection. */
107#ifdef HAVE_SETSID
108 pid_t sid = setsid ();
109 if (sid == -1)
110 signal (SIGINT, SIG_IGN);
111#else
112 signal (SIGINT, SIG_IGN);
113#endif
114
c378eb4e 115 /* Re-wire pdes[1] to stdin/stdout. */
daf3f280
JM
116 close (pdes[0]);
117 if (pdes[1] != STDOUT_FILENO)
118 {
119 dup2 (pdes[1], STDOUT_FILENO);
120 close (pdes[1]);
121 }
122 dup2 (STDOUT_FILENO, STDIN_FILENO);
65cc4390
VP
123
124 if (err_pdes[0] != -1)
125 {
126 close (err_pdes[0]);
127 dup2 (err_pdes[1], STDERR_FILENO);
128 close (err_pdes[1]);
129 }
614c279d
TT
130
131 close_most_fds ();
906e2b76
SDJ
132
133 const char *shellfile = get_shell ();
134 execl (shellfile, shellfile, "-c", name, (char *) 0);
daf3f280
JM
135 _exit (127);
136 }
137
c378eb4e 138 /* Parent. */
daf3f280 139 close (pdes[1]);
ff9f22f1
DE
140 if (err_pdes[1] != -1)
141 close (err_pdes[1]);
adf40b2e 142 /* :end chunk */
70ba0933 143 state = XNEW (struct pipe_state);
adf40b2e 144 state->pid = pid;
daf3f280 145 scb->fd = pdes[0];
65cc4390 146 scb->error_fd = err_pdes[0];
adf40b2e 147 scb->state = state;
daf3f280 148
daf3f280
JM
149 /* If we don't do this, GDB simply exits when the remote side dies. */
150 signal (SIGPIPE, SIG_IGN);
daf3f280
JM
151#endif
152}
153
daf3f280 154static void
819cc324 155pipe_close (struct serial *scb)
daf3f280 156{
19ba03f4 157 struct pipe_state *state = (struct pipe_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
614c279d 204 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
58f07bae
PA
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
12e8c7d7
TT
214static const struct serial_ops pipe_ops =
215{
216 "pipe",
217 pipe_open,
218 pipe_close,
219 NULL,
220 ser_base_readchar,
221 ser_base_write,
222 ser_base_flush_output,
223 ser_base_flush_input,
224 ser_base_send_break,
225 ser_base_raw,
226 ser_base_get_tty_state,
227 ser_base_copy_tty_state,
228 ser_base_set_tty_state,
229 ser_base_print_tty_state,
12e8c7d7
TT
230 ser_base_setbaudrate,
231 ser_base_setstopbits,
236af5e3 232 ser_base_setparity,
12e8c7d7
TT
233 ser_base_drain_output,
234 ser_base_async,
235 ser_unix_read_prim,
236 ser_unix_write_prim
237};
238
5fe70629 239INIT_GDB_FILE (ser_pipe)
daf3f280 240{
12e8c7d7 241 serial_add_interface (&pipe_ops);
daf3f280 242}