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