gdbstub: Rework configuration via command line and monitor (Jan Kiszka)

Introduce a more canonical gdbstub configuration (system emulation only)
via the new switch '-gdb dev'. Keep '-s' as shorthand for
'-gdb tcp::1234'. Use the same syntax also for the corresponding monitor
command 'gdbserver'. Its default remains to listen on TCP port 1234.

Changes in v4:
 - Rebased over new command line switches meta file

Changes in v3:
 - Fix documentation

Changes in v2:
 - Support for pipe-based like to gdb (target remote | qemu -gdb stdio)
 - Properly update the qemu-doc

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6992 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/gdbstub.c b/gdbstub.c
index 518c939..316f5e8 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2337,27 +2337,40 @@
     return len;
 }
 
-int gdbserver_start(const char *port)
+#ifndef _WIN32
+static void gdb_sigterm_handler(int signal)
+{
+    if (vm_running)
+        vm_stop(EXCP_INTERRUPT);
+}
+#endif
+
+int gdbserver_start(const char *device)
 {
     GDBState *s;
-    char gdbstub_port_name[128];
-    int port_num;
-    char *p;
+    char gdbstub_device_name[128];
     CharDriverState *chr = NULL;
     CharDriverState *mon_chr;
 
-    if (!port || !*port)
-      return -1;
-    if (strcmp(port, "none") != 0) {
-        port_num = strtol(port, &p, 10);
-        if (*p == 0) {
-            /* A numeric value is interpreted as a port number.  */
-            snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
-                     "tcp::%d,nowait,nodelay,server", port_num);
-            port = gdbstub_port_name;
+    if (!device)
+        return -1;
+    if (strcmp(device, "none") != 0) {
+        if (strstart(device, "tcp:", NULL)) {
+            /* enforce required TCP attributes */
+            snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
+                     "%s,nowait,nodelay,server", device);
+            device = gdbstub_device_name;
         }
+#ifndef _WIN32
+        else if (strcmp(device, "stdio") == 0) {
+            struct sigaction act;
 
-        chr = qemu_chr_open("gdb", port, NULL);
+            memset(&act, 0, sizeof(act));
+            act.sa_handler = gdb_sigterm_handler;
+            sigaction(SIGINT, &act, NULL);
+        }
+#endif
+        chr = qemu_chr_open("gdb", device, NULL);
         if (!chr)
             return -1;