aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lopatic <lopatic@yahoo-inc.com>2010-03-22 21:57:48 +0100
committerDaniel Stenberg <daniel@haxx.se>2010-03-22 21:57:48 +0100
commit6657f12fff9e7b14e56da3790f0a271989c8b6a2 (patch)
treea212aaf8da554ad0f991d5d0458af315d938dd6d
parent3cd5b1cfb078cd7e96d7cd490740d955b7905caf (diff)
fix the alarm()-based DNS timeout
Looking at the code of Curl_resolv_timeout() in hostip.c, I think that in case of a timeout, the signal handler for SIGALRM never gets removed. I think that in my case it gets executed at some point later on when execution has long left Curl_resolv_timeout() or even the cURL library. The code that is jumped to with siglongjmp() simply sets the error message to "name lookup timed out" and then returns with CURLRESOLV_ERROR. I guess that instead of simply returning without cleaning up, the code should have a goto that jumps to the spot right after the call to Curl_resolv().
-rw-r--r--lib/hostip.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/lib/hostip.c b/lib/hostip.c
index 4acf1217e..68ceedc6d 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -571,15 +571,6 @@ int Curl_resolv_timeout(struct connectdata *conn,
return CURLRESOLV_TIMEDOUT;
if (timeout > 0) {
- /* 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). */
- if(sigsetjmp(curl_jmpenv, 1)) {
- /* this is coming from a siglongjmp() after an alarm signal */
- failf(data, "name lookup timed out");
- return CURLRESOLV_ERROR;
- }
-
/*************************************************************
* Set signal handler to catch SIGALRM
* Store the old value to be able to set it back later!
@@ -605,6 +596,19 @@ int Curl_resolv_timeout(struct connectdata *conn,
/* 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
@@ -621,6 +625,8 @@ int Curl_resolv_timeout(struct connectdata *conn,
*/
rc = Curl_resolv(conn, hostname, port, entry);
+clean_up:
+
#ifdef USE_ALARM_TIMEOUT
if (timeout > 0) {