Blob Blame History Raw
 CHANGES      |    3 ++
 lib/hostip.c |   66 +++++++++++++++++++++++++++++----------------------------
 2 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/CHANGES b/CHANGES
index 05c1e36..1f299ed 100644
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,9 @@ Daniel Stenberg (19 Apr 2010)
 - -J/--remote-header-name didn't strip trailing carriage returns or linefeeds
   properly, so they could be used in the file name.
 
+Kamil Dudka (4 Apr 2010)
+- Eliminated a race condition in Curl_resolv_timeout().
+
 Daniel Stenberg (22 Mar 2010)
 - Thomas Lopatic fixed the alarm()-based DNS timeout:
 
diff --git a/lib/hostip.c b/lib/hostip.c
index 94f7b4c..0cf626b 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -573,50 +573,52 @@ int Curl_resolv_timeout(struct connectdata *conn,
   else
     timeout = timeoutms;
 
-  if(timeout && timeout < 1000)
+  if(!timeout)
+    /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
+    return Curl_resolv(conn, hostname, port, entry);
+
+  if(timeout < 1000)
     /* The alarm() function only provides integer second resolution, so if
        we want to wait less than one second we must bail out already now. */
     return CURLRESOLV_TIMEDOUT;
 
-  if (timeout > 0) {
-    /*************************************************************
-     * Set signal handler to catch SIGALRM
-     * Store the old value to be able to set it back later!
-     *************************************************************/
+  /*************************************************************
+   * 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;
+  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;
+  /* 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);
+  /* now set the new struct */
+  sigaction(SIGALRM, &sigact, NULL);
 #else /* HAVE_SIGACTION */
-    /* no sigaction(), revert to the much lamer signal() */
+  /* no sigaction(), revert to the much lamer signal() */
 #ifdef HAVE_SIGNAL
-    keep_sigact = signal(SIGALRM, alarmfunc);
+  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) (timeout/1000L));
-
-    /* This allows us to time-out from the name resolver, as the timeout
-       will generate a signal and we will siglongjmp() from that here.
-       This technique has problems (see alarmfunc).
-       This should be the last thing we do before calling Curl_resolv(),
-       as otherwise we'd have to worry about variables that get modified
-       before we invoke Curl_resolv() (and thus use "volatile"). */
-    if(sigsetjmp(curl_jmpenv, 1)) {
-      /* this is coming from a siglongjmp() after an alarm signal */
-      failf(data, "name lookup timed out");
-      rc = CURLRESOLV_ERROR;
-      goto clean_up;
-    }
+  /* alarm() makes a signal get sent when the timeout fires off, and that
+     will abort system calls */
+  prev_alarm = alarm((unsigned int) (timeout/1000L));
+
+  /* This allows us to time-out from the name resolver, as the timeout
+     will generate a signal and we will siglongjmp() from that here.
+     This technique has problems (see alarmfunc).
+     This should be the last thing we do before calling Curl_resolv(),
+     as otherwise we'd have to worry about variables that get modified
+     before we invoke Curl_resolv() (and thus use "volatile"). */
+  if(sigsetjmp(curl_jmpenv, 1)) {
+    /* this is coming from a siglongjmp() after an alarm signal */
+    failf(data, "name lookup timed out");
+    rc = CURLRESOLV_ERROR;
+    goto clean_up;
   }
 
 #else