Don't bother to install a SIGALRM handler unless alarm() is available.
authorDan Fandrich <dan@coneharvesters.com>
Fri, 19 Sep 2008 00:43:51 +0000 (00:43 +0000)
committerDan Fandrich <dan@coneharvesters.com>
Fri, 19 Sep 2008 00:43:51 +0000 (00:43 +0000)
Also, leave the existing SIGALRM handler alone if the timeout is too small
to handle.

CHANGES
lib/url.c

diff --git a/CHANGES b/CHANGES
index ec561bf..7e8a5ac 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,11 @@
 
                                   Changelog
 
+Daniel Fandrich (18 Sep 2008)
+- Don't bother to install a SIGALRM handler unless alarm() is available.
+  Also, leave the existing SIGALRM handler alone if the timeout is too small
+  to handle.
+
 Daniel Fandrich (17 Sep 2008)
 - Removed reference to curl-ca-bundle.crt in the host verification failure
   error message.
index 15c5cc7..cd5c983 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -185,6 +185,11 @@ static void flush_cookies(struct SessionHandle *data, int cleanup);
 /* not for WIN32 builds */
 
 #ifdef SIGALRM
+/*
+ * This signal handler jumps back into the main libcurl code and continues
+ * execution.  This effectively causes the remainder of the application to run
+ * within a signal handler which is nonportable and could lead to problems.
+ */
 static
 RETSIGTYPE alarmfunc(int sig)
 {
@@ -3796,8 +3801,8 @@ static CURLcode resolve_server(struct SessionHandle *data,
                                bool *async)
 {
   CURLcode result=CURLE_OK;
-#ifndef USE_ARES
-#ifdef SIGALRM
+
+#if defined(HAVE_ALARM) && defined(SIGALRM) && !defined(USE_ARES)
 #ifdef HAVE_SIGACTION
   struct sigaction keep_sigact;   /* store the old struct here */
   bool keep_copysig=FALSE;        /* did copy it? */
@@ -3806,45 +3811,16 @@ static CURLcode resolve_server(struct SessionHandle *data,
   void (*keep_sigact)(int);       /* store the old handler here */
 #endif /* HAVE_SIGNAL */
 #endif /* HAVE_SIGACTION */
-#endif /* SIGALRM */
-#endif /* USE_ARES */
 
-#if defined(HAVE_ALARM) && !defined(USE_ARES)
   unsigned int prev_alarm=0;
-#endif
 
-#ifndef USE_ARES
   /*************************************************************
    * Set timeout if that is being used, and we're not using an asynchronous
    * name resolve.
    *************************************************************/
   if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
-    /*************************************************************
-     * Set signal handler to catch SIGALRM
-     * Store the old value to be able to set it back later!
-     *************************************************************/
-
-#ifdef SIGALRM
-#ifdef HAVE_ALARM
-    long shortest;
-#endif
 #ifdef HAVE_SIGACTION
     struct sigaction sigact;
-    sigaction(SIGALRM, NULL, &sigact);
-    keep_sigact = sigact;
-    keep_copysig = TRUE; /* yes, we have a copy */
-    sigact.sa_handler = alarmfunc;
-#ifdef SA_RESTART
-    /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
-    sigact.sa_flags &= ~SA_RESTART;
-#endif
-    /* now set the new struct */
-    sigaction(SIGALRM, &sigact, NULL);
-#else /* HAVE_SIGACTION */
-    /* no sigaction(), revert to the much lamer signal() */
-#ifdef HAVE_SIGNAL
-    keep_sigact = signal(SIGALRM, alarmfunc);
-#endif
 #endif /* HAVE_SIGACTION */
 
     /* We set the timeout on the name resolving phase first, separately from
@@ -3852,8 +3828,7 @@ static CURLcode resolve_server(struct SessionHandle *data,
      * a signal-based timeout, why it won't work and shouldn't be used in
      * multi-threaded environments. */
 
-#ifdef HAVE_ALARM
-    shortest = data->set.timeout; /* default to this timeout value */
+    long shortest = data->set.timeout; /* default to this timeout value */
     if(shortest && data->set.connecttimeout &&
        (data->set.connecttimeout < shortest))
       /* if both are set, pick the shortest */
@@ -3867,16 +3842,36 @@ static CURLcode resolve_server(struct SessionHandle *data,
          we want to wait less than one second we must bail out already now. */
       return CURLE_OPERATION_TIMEDOUT;
 
+    /*************************************************************
+     * Set signal handler to catch SIGALRM
+     * Store the old value to be able to set it back later!
+     *************************************************************/
+#ifdef HAVE_SIGACTION
+    sigaction(SIGALRM, NULL, &sigact);
+    keep_sigact = sigact;
+    keep_copysig = TRUE; /* yes, we have a copy */
+    sigact.sa_handler = alarmfunc;
+#ifdef SA_RESTART
+    /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
+    sigact.sa_flags &= ~SA_RESTART;
+#endif
+    /* now set the new struct */
+    sigaction(SIGALRM, &sigact, NULL);
+#else /* HAVE_SIGACTION */
+    /* no sigaction(), revert to the much lamer signal() */
+#ifdef HAVE_SIGNAL
+    keep_sigact = signal(SIGALRM, alarmfunc);
+#endif
+#endif /* HAVE_SIGACTION */
+
     /* alarm() makes a signal get sent when the timeout fires off, and that
        will abort system calls */
     prev_alarm = alarm((unsigned int) (shortest ? shortest/1000L : shortest));
     /* We can expect the conn->created time to be "now", as that was just
        recently set in the beginning of this function and nothing slow
        has been done since then until now. */
-#endif
-#endif /* SIGALRM */
   }
-#endif /* USE_ARES */
+#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */
 
   /*************************************************************
    * Resolve the name of the server or proxy
@@ -3975,7 +3970,7 @@ static CURLcode resolve_server(struct SessionHandle *data,
     else
       alarm(0); /* just shut it off */
   }
-#endif
+#endif /* HAVE_ALARM && SIGALRM && !USE_ARES */
   return result;
 }