GDB (API)
|
00001 /* Serial interface for a pipe to a separate program 00002 Copyright (C) 1999-2013 Free Software Foundation, Inc. 00003 00004 Contributed by Cygnus Solutions. 00005 00006 This file is part of GDB. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00020 00021 #include "defs.h" 00022 #include "serial.h" 00023 #include "ser-base.h" 00024 #include "ser-unix.h" 00025 00026 #include "gdb_vfork.h" 00027 00028 #include <sys/types.h> 00029 #include <sys/socket.h> 00030 #include <sys/time.h> 00031 #include <fcntl.h> 00032 #include "gdb_string.h" 00033 #include "filestuff.h" 00034 00035 #include <signal.h> 00036 00037 static int pipe_open (struct serial *scb, const char *name); 00038 static void pipe_close (struct serial *scb); 00039 00040 extern void _initialize_ser_pipe (void); 00041 00042 struct pipe_state 00043 { 00044 int pid; 00045 }; 00046 00047 /* Open up a raw pipe. */ 00048 00049 static int 00050 pipe_open (struct serial *scb, const char *name) 00051 { 00052 #if !HAVE_SOCKETPAIR 00053 return -1; 00054 #else 00055 struct pipe_state *state; 00056 /* This chunk: */ 00057 /* Copyright (c) 1988, 1993 00058 * The Regents of the University of California. All rights reserved. 00059 * 00060 * This code is derived from software written by Ken Arnold and 00061 * published in UNIX Review, Vol. 6, No. 8. 00062 */ 00063 int pdes[2]; 00064 int err_pdes[2]; 00065 int pid; 00066 00067 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0) 00068 return -1; 00069 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0) 00070 { 00071 close (pdes[0]); 00072 close (pdes[1]); 00073 return -1; 00074 } 00075 00076 /* Create the child process to run the command in. Note that the 00077 apparent call to vfork() below *might* actually be a call to 00078 fork() due to the fact that autoconf will ``#define vfork fork'' 00079 on certain platforms. */ 00080 pid = vfork (); 00081 00082 /* Error. */ 00083 if (pid == -1) 00084 { 00085 close (pdes[0]); 00086 close (pdes[1]); 00087 close (err_pdes[0]); 00088 close (err_pdes[1]); 00089 return -1; 00090 } 00091 00092 if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1) 00093 { 00094 close (err_pdes[0]); 00095 close (err_pdes[1]); 00096 err_pdes[0] = err_pdes[1] = -1; 00097 } 00098 00099 /* Child. */ 00100 if (pid == 0) 00101 { 00102 /* We don't want ^c to kill the connection. */ 00103 #ifdef HAVE_SETSID 00104 pid_t sid = setsid (); 00105 if (sid == -1) 00106 signal (SIGINT, SIG_IGN); 00107 #else 00108 signal (SIGINT, SIG_IGN); 00109 #endif 00110 00111 /* Re-wire pdes[1] to stdin/stdout. */ 00112 close (pdes[0]); 00113 if (pdes[1] != STDOUT_FILENO) 00114 { 00115 dup2 (pdes[1], STDOUT_FILENO); 00116 close (pdes[1]); 00117 } 00118 dup2 (STDOUT_FILENO, STDIN_FILENO); 00119 00120 if (err_pdes[0] != -1) 00121 { 00122 close (err_pdes[0]); 00123 dup2 (err_pdes[1], STDERR_FILENO); 00124 close (err_pdes[1]); 00125 } 00126 00127 close_most_fds (); 00128 execl ("/bin/sh", "sh", "-c", name, (char *) 0); 00129 _exit (127); 00130 } 00131 00132 /* Parent. */ 00133 close (pdes[1]); 00134 if (err_pdes[1] != -1) 00135 close (err_pdes[1]); 00136 /* :end chunk */ 00137 state = XMALLOC (struct pipe_state); 00138 state->pid = pid; 00139 scb->fd = pdes[0]; 00140 scb->error_fd = err_pdes[0]; 00141 scb->state = state; 00142 00143 /* If we don't do this, GDB simply exits when the remote side dies. */ 00144 signal (SIGPIPE, SIG_IGN); 00145 return 0; 00146 #endif 00147 } 00148 00149 static void 00150 pipe_close (struct serial *scb) 00151 { 00152 struct pipe_state *state = scb->state; 00153 00154 close (scb->fd); 00155 scb->fd = -1; 00156 00157 if (state != NULL) 00158 { 00159 int wait_result, status; 00160 00161 /* Don't kill the task right away, give it a chance to shut down cleanly. 00162 But don't wait forever though. */ 00163 #define PIPE_CLOSE_TIMEOUT 5 00164 00165 /* Assume the program will exit after SIGTERM. Might be 00166 useful to print any remaining stderr output from 00167 scb->error_fd while waiting. */ 00168 #define SIGTERM_TIMEOUT INT_MAX 00169 00170 wait_result = -1; 00171 #ifdef HAVE_WAITPID 00172 wait_result = wait_to_die_with_timeout (state->pid, &status, 00173 PIPE_CLOSE_TIMEOUT); 00174 #endif 00175 if (wait_result == -1) 00176 { 00177 kill (state->pid, SIGTERM); 00178 #ifdef HAVE_WAITPID 00179 wait_to_die_with_timeout (state->pid, &status, SIGTERM_TIMEOUT); 00180 #endif 00181 } 00182 00183 if (scb->error_fd != -1) 00184 close (scb->error_fd); 00185 scb->error_fd = -1; 00186 xfree (state); 00187 scb->state = NULL; 00188 } 00189 } 00190 00191 int 00192 gdb_pipe (int pdes[2]) 00193 { 00194 #if !HAVE_SOCKETPAIR 00195 errno = ENOSYS; 00196 return -1; 00197 #else 00198 00199 if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0) 00200 return -1; 00201 00202 /* If we don't do this, GDB simply exits when the remote side 00203 dies. */ 00204 signal (SIGPIPE, SIG_IGN); 00205 return 0; 00206 #endif 00207 } 00208 00209 void 00210 _initialize_ser_pipe (void) 00211 { 00212 struct serial_ops *ops = XMALLOC (struct serial_ops); 00213 00214 memset (ops, 0, sizeof (struct serial_ops)); 00215 ops->name = "pipe"; 00216 ops->next = 0; 00217 ops->open = pipe_open; 00218 ops->close = pipe_close; 00219 ops->readchar = ser_base_readchar; 00220 ops->write = ser_base_write; 00221 ops->flush_output = ser_base_flush_output; 00222 ops->flush_input = ser_base_flush_input; 00223 ops->send_break = ser_base_send_break; 00224 ops->go_raw = ser_base_raw; 00225 ops->get_tty_state = ser_base_get_tty_state; 00226 ops->copy_tty_state = ser_base_copy_tty_state; 00227 ops->set_tty_state = ser_base_set_tty_state; 00228 ops->print_tty_state = ser_base_print_tty_state; 00229 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; 00230 ops->setbaudrate = ser_base_setbaudrate; 00231 ops->setstopbits = ser_base_setstopbits; 00232 ops->drain_output = ser_base_drain_output; 00233 ops->async = ser_base_async; 00234 ops->read_prim = ser_unix_read_prim; 00235 ops->write_prim = ser_unix_write_prim; 00236 serial_add_interface (ops); 00237 }