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