]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/gdbserver/server.c
gdb/
[thirdparty/binutils-gdb.git] / gdb / gdbserver / server.c
index b674ed0070ffcba1984bdf1d5d0c05bef0ec96e4..81fde5b7f73e8f1b3f9c1d0fac31f5e21ca87942 100644 (file)
 
 #include "server.h"
 
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+
 int cont_thread;
 int general_thread;
 int step_thread;
@@ -31,14 +35,27 @@ int server_waiting;
 
 jmp_buf toplevel;
 
+/* The PID of the originally created or attached inferior.  Used to
+   send signals to the process when GDB sends us an asynchronous interrupt
+   (user hitting Control-C in the client), and to wait for the child to exit
+   when no longer debugging it.  */
+
+int signal_pid;
+
 static unsigned char
 start_inferior (char *argv[], char *statusptr)
 {
-  /* FIXME Check error? Or turn to void.  */
-  create_inferior (argv[0], argv);
+  signal (SIGTTOU, SIG_DFL);
+  signal (SIGTTIN, SIG_DFL);
+
+  signal_pid = create_inferior (argv[0], argv);
 
   fprintf (stderr, "Process %s created; pid = %d\n", argv[0],
-          all_threads.head->id);
+          signal_pid);
+
+  signal (SIGTTOU, SIG_IGN);
+  signal (SIGTTIN, SIG_IGN);
+  tcsetpgrp (fileno (stderr), signal_pid);
 
   /* Wait till we are at 1st instruction in program, return signal number.  */
   return mywait (statusptr, 0);
@@ -49,9 +66,15 @@ attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
 {
   /* myattach should return -1 if attaching is unsupported,
      0 if it succeeded, and call error() otherwise.  */
+
   if (myattach (pid) != 0)
     return -1;
 
+  /* FIXME - It may be that we should get the SIGNAL_PID from the
+     attach function, so that it can be the main thread instead of
+     whichever we were told to attach to.  */
+  signal_pid = pid;
+
   *sigptr = mywait (statusptr, 0);
 
   return 0;
@@ -194,6 +217,28 @@ main (int argc, char *argv[])
            case 'd':
              remote_debug = !remote_debug;
              break;
+           case 'D':
+             fprintf (stderr, "Detaching from inferior\n");
+             detach_inferior ();
+             write_ok (own_buf);
+             putpkt (own_buf);
+             remote_close ();            
+
+             /* If we are attached, then we can exit.  Otherwise, we need to
+                hang around doing nothing, until the child is gone.  */
+             if (!attached)
+               {
+                 int status, ret;
+
+                 do {
+                   ret = waitpid (signal_pid, &status, 0);
+                   if (WIFEXITED (status) || WIFSIGNALED (status))
+                     break;
+                 } while (ret != -1 || errno != ECHILD);
+               }
+
+             exit (0);
+
            case '!':
              if (attached == 0)
                {