Remove support for old Cygwin 1.5 versions.
[deliverable/binutils-gdb.git] / gdb / ser-pipe.c
index 5fa897f2d909e958771af31dd726e9badc290be0..9bf0d04f306758d977d5ed353dbd7b3ccb25dfd2 100644 (file)
@@ -1,5 +1,6 @@
 /* Serial interface for a pipe to a separate program
-   Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
 
    Contributed by Cygnus Solutions.
 
@@ -30,6 +31,7 @@
 #include <sys/time.h>
 #include <fcntl.h>
 #include "gdb_string.h"
+#include "gdb_wait.h"
 
 #include <signal.h>
 
@@ -43,7 +45,7 @@ struct pipe_state
     int pid;
   };
 
-/* Open up a raw pipe */
+/* Open up a raw pipe */
 
 static int
 pipe_open (struct serial *scb, const char *name)
@@ -62,10 +64,15 @@ pipe_open (struct serial *scb, const char *name)
   int pdes[2];
   int err_pdes[2];
   int pid;
+
   if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
     return -1;
   if (socketpair (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
-    return -1;
+    {
+      close (pdes[0]);
+      close (pdes[1]);
+      return -1;
+    }
 
   /* Create the child process to run the command in.  Note that the
      apparent call to vfork() below *might* actually be a call to
@@ -73,7 +80,7 @@ pipe_open (struct serial *scb, const char *name)
      on certain platforms.  */
   pid = vfork ();
   
-  /* Error. */
+  /* Error.  */
   if (pid == -1)
     {
       close (pdes[0]);
@@ -90,10 +97,19 @@ pipe_open (struct serial *scb, const char *name)
       err_pdes[0] = err_pdes[1] = -1;
     }
 
-  /* Child. */
+  /* Child.  */
   if (pid == 0)
     {
-      /* re-wire pdes[1] to stdin/stdout */
+      /* We don't want ^c to kill the connection.  */
+#ifdef HAVE_SETSID
+      pid_t sid = setsid ();
+      if (sid == -1)
+       signal (SIGINT, SIG_IGN);
+#else
+      signal (SIGINT, SIG_IGN);
+#endif
+
+      /* Re-wire pdes[1] to stdin/stdout.  */
       close (pdes[0]);
       if (pdes[1] != STDOUT_FILENO)
        {
@@ -109,19 +125,21 @@ pipe_open (struct serial *scb, const char *name)
          close (err_pdes[1]);
        }
 #if 0
-      /* close any stray FD's - FIXME - how? */
+      /* close any stray FD's - FIXME - how?  */
       /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
          from previous popen() calls that remain open in the 
-         parent process are closed in the new child process. */
+         parent process are closed in the new child process.  */
       for (old = pidlist; old; old = old->next)
-       close (fileno (old->fp));       /* don't allow a flush */
+       close (fileno (old->fp));       /* Don't allow a flush.  */
 #endif
       execl ("/bin/sh", "sh", "-c", name, (char *) 0);
       _exit (127);
     }
 
-  /* Parent. */
+  /* Parent.  */
   close (pdes[1]);
+  if (err_pdes[1] != -1)
+    close (err_pdes[1]);
   /* :end chunk */
   state = XMALLOC (struct pipe_state);
   state->pid = pid;
@@ -139,24 +157,51 @@ static void
 pipe_close (struct serial *scb)
 {
   struct pipe_state *state = scb->state;
+
+  close (scb->fd);
+  scb->fd = -1;
+
   if (state != NULL)
     {
-      int pid = state->pid;
-      close (scb->fd);
-      scb->fd = -1;
+      int status;
+      kill (state->pid, SIGTERM);
+#ifdef HAVE_WAITPID
+      /* Assume the program will exit after SIGTERM.  Might be
+        useful to print any remaining stderr output from
+        scb->error_fd while waiting.  */
+      waitpid (state->pid, &status, 0);
+#endif
+      if (scb->error_fd != -1)
+       close (scb->error_fd);
+      scb->error_fd = -1;
       xfree (state);
       scb->state = NULL;
-      kill (pid, SIGTERM);
-      /* Might be useful to check that the child does die. */
     }
 }
 
-static struct serial_ops pipe_ops;
+int
+gdb_pipe (int pdes[2])
+{
+#if !HAVE_SOCKETPAIR
+  errno = ENOSYS;
+  return -1;
+#else
+
+  if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
+    return -1;
+
+  /* If we don't do this, GDB simply exits when the remote side
+     dies.  */
+  signal (SIGPIPE, SIG_IGN);
+  return 0;
+#endif
+}
 
 void
 _initialize_ser_pipe (void)
 {
   struct serial_ops *ops = XMALLOC (struct serial_ops);
+
   memset (ops, 0, sizeof (struct serial_ops));
   ops->name = "pipe";
   ops->next = 0;
@@ -169,6 +214,7 @@ _initialize_ser_pipe (void)
   ops->send_break = ser_base_send_break;
   ops->go_raw = ser_base_raw;
   ops->get_tty_state = ser_base_get_tty_state;
+  ops->copy_tty_state = ser_base_copy_tty_state;
   ops->set_tty_state = ser_base_set_tty_state;
   ops->print_tty_state = ser_base_print_tty_state;
   ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
This page took 0.025985 seconds and 4 git commands to generate.