summaryrefslogtreecommitdiff
path: root/libsoup/soup-socket.c
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 /libsoup/soup-socket.c
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.
Diffstat (limited to 'libsoup/soup-socket.c')
-rw-r--r--libsoup/soup-socket.c86
1 files changed, 66 insertions, 20 deletions
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 */