Perform deep unix magic in order to identify if we are running in a SOUP_0_4 SOUP_0_5
authorAlex Graveley <alex@ximian.com>
Tue, 28 Aug 2001 17:58:05 +0000 (17:58 +0000)
committerAlex Graveley <orph@src.gnome.org>
Tue, 28 Aug 2001 17:58:05 +0000 (17:58 +0000)
2001-08-28  Alex Graveley  <alex@ximian.com>

* src/soup-core/soup-socket.c (soup_address_new): Perform deep
unix magic in order to identify if we are running in a
debugger. This is needed because gdb causes segfaults in child
processes that load shlibs due to breakpoints being left over in
the new unwatched process. Now, gethostbyname() loads shared libs
to do name resolution on many unixes, which would cause soup to be
hard to use and otherwise suck when run inside a debugger. So now
everything works perfectly both inside and outside of gdb.
(soup_address_new_cb): Resolve the hostname syncronously if we are
inside a debugger.

ChangeLog
libsoup/soup-socket.c

index 612d4ad..b3079f6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2001-08-28  Alex Graveley  <alex@ximian.com>
 
+       * src/soup-core/soup-socket.c (soup_address_new): Perform deep
+       unix magic in order to identify if we are running in a
+       debugger. This is needed because gdb causes segfaults in child
+       processes that load shlibs due to breakpoints being left over in
+       the new unwatched process. Now, gethostbyname() loads shared libs
+       to do name resolution on many unixes, which would cause soup to be
+       hard to use and otherwise suck when run inside a debugger. So now
+       everything works perfectly both inside and outside of gdb.
+       (soup_address_new_cb): Resolve the hostname syncronously if we are
+       inside a debugger.
+
+2001-08-28  Alex Graveley  <alex@ximian.com>
+
        * src/soup-core/soup-context.c (soup_try_existing_connections):
        Remove mega FIXME.
 
index 9a0bf52..040f04f 100644 (file)
@@ -41,6 +41,7 @@
 #include <net/if.h>
 #include <netinet/in.h>
 #include <sys/ioctl.h>
+#include <sys/ptrace.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/utsname.h>
@@ -513,37 +514,55 @@ soup_address_new_cb (GIOChannel* iochannel,
                     gpointer data)
 {
        SoupAddressState* state = (SoupAddressState*) data;
-       int rv;
-       char* buf;
-       int length;
        struct sockaddr_in* sa_in;
        GSList *cb_list, *iter;
        SoupAddressNewFn cb_func;
        gpointer cb_data;       
 
-       if (!(condition & G_IO_IN)) goto ERROR;
+       if (!(condition & G_IO_IN)) {
+               int ret;
 
-       buf = &state->buffer [state->len];
-       length = sizeof (state->buffer) - state->len;
+               g_source_remove (state->watch);
+               close (state->fd);
+               waitpid (state->pid, &ret, 0);
 
-       rv = read (state->fd, buf, length);
-       if (rv < 0) goto ERROR;
+               if (WIFSIGNALED (ret) || WEXITSTATUS (ret) != 1) goto ERROR;
+
+               /* 
+                * Exit status of one means we are inside a debugger.
+                * Resolve the name synchronously.
+                */
+               sa_in = (struct sockaddr_in*) &state->ia.sa;
+
+               if (!soup_gethostbyname (state->ia.name, sa_in, NULL))
+                       g_warning ("Problem resolving host name");
+       } else {
+               int rv;
+               char* buf;
+               int length;
 
-       state->len += rv;
+               buf = &state->buffer [state->len];
+               length = sizeof (state->buffer) - state->len;
 
-       /* Return true if there's more to read */
-       if ((state->len - 1) != state->buffer [0]) return TRUE;
+               rv = read (state->fd, buf, length);
+               if (rv < 0) goto ERROR;
 
-       if (state->len < 2) goto ERROR;
+               state->len += rv;
 
-       /* Success. Copy resolved address. */
-       sa_in = (struct sockaddr_in*) &state->ia.sa;
-       memcpy (&sa_in->sin_addr, &state->buffer [1], (state->len - 1));
+               /* Return true if there's more to read */
+               if ((state->len - 1) != state->buffer [0]) return TRUE;
 
-       /* Cleanup state */
-       g_source_remove (state->watch);
-       close (state->fd);
-       waitpid (state->pid, NULL, WNOHANG);
+               if (state->len < 2) goto ERROR;
+
+               /* Success. Copy resolved address. */
+               sa_in = (struct sockaddr_in*) &state->ia.sa;
+               memcpy (&sa_in->sin_addr, &state->buffer [1], (state->len - 1));
+
+               /* Cleanup state */
+               g_source_remove (state->watch);
+               close (state->fd);
+               waitpid (state->pid, NULL, WNOHANG);
+       }
 
        /* Get state data before realloc */
        cb_list = iter = state->cb_list;
@@ -753,7 +772,34 @@ soup_address_new (const gchar* name,
        case 0:
                close (pipes [0]);
 
-               /* Try to get the host by name (ie, DNS) */
+               signal (SIGCHLD, SIG_IGN);
+
+               if (ptrace (PTRACE_ATTACH, getppid (), NULL, NULL) == -1) {
+                       /* 
+                        * Attach failed; it's probably already being
+                        * debugged. 
+                        */
+                       if (errno != EPERM)
+                               g_warning ("ptrace: Unexpected error: %s",
+                                          strerror(errno));
+
+                       _exit (1);
+               }
+               
+               /* 
+                * We just SIGSTOPped it; we need to CONT it now. 
+                */
+               waitpid (getppid (), NULL, 0);
+
+               if (ptrace (PTRACE_DETACH, getppid (), NULL, NULL) == -1)
+                       g_warning ("ptrace: Detach failed: %s", 
+                                  strerror(errno));
+
+               kill (getppid(), SIGCONT);
+
+               /* 
+                * Try to get the host by name (ie, DNS) 
+                */
                if (soup_gethostbyname (name, &sa, NULL)) {
                        guchar size = 4;        /* FIX for IPv6 */