summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Graveley <alex@ximian.com>2001-08-28 17:58:05 +0000
committerAlex Graveley <orph@src.gnome.org>2001-08-28 17:58:05 +0000
commit7409fe9fc46bd46552dab894d64a7aa421d9ddff (patch)
tree1fa4b2e7b0ae926cdb7a17b4d38a1f8338195ed3
parentc46a94e182e66630081eddf5bb2eafa63d257936 (diff)
downloadlibsoup-soup-0-4.tar.gz
Perform deep unix magic in order to identify if we are running in aSOUP_0_5SOUP_0_4soup-0-4
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.
-rw-r--r--ChangeLog13
-rw-r--r--libsoup/soup-socket.c86
2 files changed, 79 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 612d4ad3..b3079f64 100644
--- 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.
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 9a0bf522..040f04f8 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -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 */