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