1 /* Serial interface for a pipe to a separate program 2 Copyright (C) 1999-2023 Free Software Foundation, Inc. 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 10 the Free Software Foundation; either version 3 of the License, or 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 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include "defs.h" 22 #include "serial.h" 23 #include "ser-base.h" 24 #include "ser-unix.h" 25 26 #include "gdb_vfork.h" 27 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 #include "gdbsupport/gdb_sys_time.h" 31 #include <fcntl.h> 32 #include "gdbsupport/filestuff.h" 33 #include "gdbsupport/pathstuff.h" 34 35 #include <signal.h> 36 37 static int pipe_open (struct serial *scb, const char *name); 38 static void pipe_close (struct serial *scb); 39 40 struct pipe_state 41 { 42 int pid; 43 }; 44 45 /* Open up a raw pipe. */ 46 47 static int 48 pipe_open (struct serial *scb, const char *name) 49 { 50 #if !HAVE_SOCKETPAIR 51 return -1; 52 #else 53 struct pipe_state *state; 54 /* This chunk: */ 55 /* Copyright (c) 1988, 1993 56 * The Regents of the University of California. All rights reserved. 57 * 58 * This code is derived from software written by Ken Arnold and 59 * published in UNIX Review, Vol. 6, No. 8. 60 */ 61 int pdes[2]; 62 int err_pdes[2]; 63 int pid; 64 65 if (*name == '|') 66 { 67 name++; 68 name = skip_spaces (name); 69 } 70 71 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0) 72 return -1; 73 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0) 74 { 75 close (pdes[0]); 76 close (pdes[1]); 77 return -1; 78 } 79 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. */ 84 pid = vfork (); 85 86 /* Error. */ 87 if (pid == -1) 88 { 89 close (pdes[0]); 90 close (pdes[1]); 91 close (err_pdes[0]); 92 close (err_pdes[1]); 93 return -1; 94 } 95 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 103 /* Child. */ 104 if (pid == 0) 105 { 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 115 /* Re-wire pdes[1] to stdin/stdout. */ 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); 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 } 130 131 close_most_fds (); 132 133 const char *shellfile = get_shell (); 134 execl (shellfile, shellfile, "-c", name, (char *) 0); 135 _exit (127); 136 } 137 138 /* Parent. */ 139 close (pdes[1]); 140 if (err_pdes[1] != -1) 141 close (err_pdes[1]); 142 /* :end chunk */ 143 state = XNEW (struct pipe_state); 144 state->pid = pid; 145 scb->fd = pdes[0]; 146 scb->error_fd = err_pdes[0]; 147 scb->state = state; 148 149 /* If we don't do this, GDB simply exits when the remote side dies. */ 150 signal (SIGPIPE, SIG_IGN); 151 return 0; 152 #endif 153 } 154 155 static void 156 pipe_close (struct serial *scb) 157 { 158 struct pipe_state *state = (struct pipe_state *) scb->state; 159 160 close (scb->fd); 161 scb->fd = -1; 162 163 if (state != NULL) 164 { 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 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. */ 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); 180 #endif 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 189 if (scb->error_fd != -1) 190 close (scb->error_fd); 191 scb->error_fd = -1; 192 xfree (state); 193 scb->state = NULL; 194 } 195 } 196 197 int 198 gdb_pipe (int pdes[2]) 199 { 200 #if !HAVE_SOCKETPAIR 201 errno = ENOSYS; 202 return -1; 203 #else 204 205 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0) 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 215 static 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, 231 ser_base_setbaudrate, 232 ser_base_setstopbits, 233 ser_base_setparity, 234 ser_base_drain_output, 235 ser_base_async, 236 ser_unix_read_prim, 237 ser_unix_write_prim 238 }; 239 240 void _initialize_ser_pipe (); 241 void 242 _initialize_ser_pipe () 243 { 244 serial_add_interface (&pipe_ops); 245 } 246