gdb/ser-pipe.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* Serial interface for a pipe to a separate program
  2.    Copyright (C) 1999-2015 Free Software Foundation, Inc.

  3.    Contributed by Cygnus Solutions.

  4.    This file is part of GDB.

  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 3 of the License, or
  8.    (at your option) any later version.

  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.

  13.    You should have received a copy of the GNU General Public License
  14.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  15. #include "defs.h"
  16. #include "serial.h"
  17. #include "ser-base.h"
  18. #include "ser-unix.h"

  19. #include "gdb_vfork.h"

  20. #include <sys/types.h>
  21. #include <sys/socket.h>
  22. #include <sys/time.h>
  23. #include <fcntl.h>
  24. #include "filestuff.h"

  25. #include <signal.h>

  26. static int pipe_open (struct serial *scb, const char *name);
  27. static void pipe_close (struct serial *scb);

  28. extern void _initialize_ser_pipe (void);

  29. struct pipe_state
  30.   {
  31.     int pid;
  32.   };

  33. /* Open up a raw pipe.  */

  34. static int
  35. pipe_open (struct serial *scb, const char *name)
  36. {
  37. #if !HAVE_SOCKETPAIR
  38.   return -1;
  39. #else
  40.   struct pipe_state *state;
  41.   /* This chunk: */
  42.   /* Copyright (c) 1988, 1993
  43.    *      The Regents of the University of California.  All rights reserved.
  44.    *
  45.    * This code is derived from software written by Ken Arnold and
  46.    * published in UNIX Review, Vol. 6, No. 8.
  47.    */
  48.   int pdes[2];
  49.   int err_pdes[2];
  50.   int pid;

  51.   if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
  52.     return -1;
  53.   if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
  54.     {
  55.       close (pdes[0]);
  56.       close (pdes[1]);
  57.       return -1;
  58.     }

  59.   /* Create the child process to run the command in.  Note that the
  60.      apparent call to vfork() below *might* actually be a call to
  61.      fork() due to the fact that autoconf will ``#define vfork fork''
  62.      on certain platforms.  */
  63.   pid = vfork ();

  64.   /* Error.  */
  65.   if (pid == -1)
  66.     {
  67.       close (pdes[0]);
  68.       close (pdes[1]);
  69.       close (err_pdes[0]);
  70.       close (err_pdes[1]);
  71.       return -1;
  72.     }

  73.   if (fcntl (err_pdes[0], F_SETFL, O_NONBLOCK) == -1)
  74.     {
  75.       close (err_pdes[0]);
  76.       close (err_pdes[1]);
  77.       err_pdes[0] = err_pdes[1] = -1;
  78.     }

  79.   /* Child.  */
  80.   if (pid == 0)
  81.     {
  82.       /* We don't want ^c to kill the connection.  */
  83. #ifdef HAVE_SETSID
  84.       pid_t sid = setsid ();
  85.       if (sid == -1)
  86.         signal (SIGINT, SIG_IGN);
  87. #else
  88.       signal (SIGINT, SIG_IGN);
  89. #endif

  90.       /* Re-wire pdes[1] to stdin/stdout.  */
  91.       close (pdes[0]);
  92.       if (pdes[1] != STDOUT_FILENO)
  93.         {
  94.           dup2 (pdes[1], STDOUT_FILENO);
  95.           close (pdes[1]);
  96.         }
  97.       dup2 (STDOUT_FILENO, STDIN_FILENO);

  98.       if (err_pdes[0] != -1)
  99.         {
  100.           close (err_pdes[0]);
  101.           dup2 (err_pdes[1], STDERR_FILENO);
  102.           close (err_pdes[1]);
  103.         }

  104.       close_most_fds ();
  105.       execl ("/bin/sh", "sh", "-c", name, (char *) 0);
  106.       _exit (127);
  107.     }

  108.   /* Parent.  */
  109.   close (pdes[1]);
  110.   if (err_pdes[1] != -1)
  111.     close (err_pdes[1]);
  112.   /* :end chunk */
  113.   state = XNEW (struct pipe_state);
  114.   state->pid = pid;
  115.   scb->fd = pdes[0];
  116.   scb->error_fd = err_pdes[0];
  117.   scb->state = state;

  118.   /* If we don't do this, GDB simply exits when the remote side dies.  */
  119.   signal (SIGPIPE, SIG_IGN);
  120.   return 0;
  121. #endif
  122. }

  123. static void
  124. pipe_close (struct serial *scb)
  125. {
  126.   struct pipe_state *state = scb->state;

  127.   close (scb->fd);
  128.   scb->fd = -1;

  129.   if (state != NULL)
  130.     {
  131.       int wait_result, status;

  132.       /* Don't kill the task right away, give it a chance to shut down cleanly.
  133.          But don't wait forever though.  */
  134. #define PIPE_CLOSE_TIMEOUT 5

  135.       /* Assume the program will exit after SIGTERM.  Might be
  136.          useful to print any remaining stderr output from
  137.          scb->error_fd while waiting.  */
  138. #define SIGTERM_TIMEOUT INT_MAX

  139.       wait_result = -1;
  140. #ifdef HAVE_WAITPID
  141.       wait_result = wait_to_die_with_timeout (state->pid, &status,
  142.                                               PIPE_CLOSE_TIMEOUT);
  143. #endif
  144.       if (wait_result == -1)
  145.         {
  146.           kill (state->pid, SIGTERM);
  147. #ifdef HAVE_WAITPID
  148.           wait_to_die_with_timeout (state->pid, &status, SIGTERM_TIMEOUT);
  149. #endif
  150.         }

  151.       if (scb->error_fd != -1)
  152.         close (scb->error_fd);
  153.       scb->error_fd = -1;
  154.       xfree (state);
  155.       scb->state = NULL;
  156.     }
  157. }

  158. int
  159. gdb_pipe (int pdes[2])
  160. {
  161. #if !HAVE_SOCKETPAIR
  162.   errno = ENOSYS;
  163.   return -1;
  164. #else

  165.   if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
  166.     return -1;

  167.   /* If we don't do this, GDB simply exits when the remote side
  168.      dies.  */
  169.   signal (SIGPIPE, SIG_IGN);
  170.   return 0;
  171. #endif
  172. }

  173. static const struct serial_ops pipe_ops =
  174. {
  175.   "pipe",
  176.   pipe_open,
  177.   pipe_close,
  178.   NULL,
  179.   ser_base_readchar,
  180.   ser_base_write,
  181.   ser_base_flush_output,
  182.   ser_base_flush_input,
  183.   ser_base_send_break,
  184.   ser_base_raw,
  185.   ser_base_get_tty_state,
  186.   ser_base_copy_tty_state,
  187.   ser_base_set_tty_state,
  188.   ser_base_print_tty_state,
  189.   ser_base_noflush_set_tty_state,
  190.   ser_base_setbaudrate,
  191.   ser_base_setstopbits,
  192.   ser_base_drain_output,
  193.   ser_base_async,
  194.   ser_unix_read_prim,
  195.   ser_unix_write_prim
  196. };

  197. void
  198. _initialize_ser_pipe (void)
  199. {
  200.   serial_add_interface (&pipe_ops);
  201. }