diff options
author | Daniel Stenberg <daniel@haxx.se> | 2001-11-07 14:13:29 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2001-11-07 14:13:29 +0000 |
commit | fe3a78ab1997f650dd6e76a7a0ba51b72546221e (patch) | |
tree | 66ec727b4544f297e672592c57b12b7d14e49bc7 /lib/transfer.c | |
parent | 1a984ea84771a85df08f6a97e7cbac3ce379743e (diff) |
we use signal() to ignore signals only as long as we have to, and we now
restore the previous (if any) signal handler properly on return.
Diffstat (limited to 'lib/transfer.c')
-rw-r--r-- | lib/transfer.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/lib/transfer.c b/lib/transfer.c index 2d1c90f6a..163b2cb84 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -900,6 +900,10 @@ CURLcode Curl_perform(struct SessionHandle *data) struct connectdata *conn=NULL; bool port=TRUE; /* allow data->set.use_port to set port to use */ char *newurl = NULL; /* possibly a new URL to follow to! */ +#ifdef HAVE_SIGNAL + /* storage for the previous signal handler */ + void (*prev_signal)(int sig); +#endif if(!data->change.url) /* we can't do anything wihout URL */ @@ -916,10 +920,23 @@ CURLcode Curl_perform(struct SessionHandle *data) data->state.this_is_a_follow = FALSE; /* reset this */ data->state.errorbuf = FALSE; /* no error has occurred */ - Curl_initinfo(data); /* reset session-specific information "variables" */ +#if defined(HAVE_SIGNAL) && defined(SIGPIPE) + /************************************************************* + * Tell signal handler to ignore SIGPIPE + *************************************************************/ + prev_signal = signal(SIGPIPE, SIG_IGN); +#endif + Curl_initinfo(data); /* reset session-specific information "variables" */ Curl_pgrsStartNow(data); + /* + * It is important that there is NO 'return' from this function any any + * other place than falling down the bottom! This is because we have cleanup + * stuff that must be done before we get back, and that is only performed + * after this do-while loop. + */ + do { Curl_pgrsTime(data, TIMER_STARTSINGLE); res = Curl_connect(data, &conn, port); @@ -1035,8 +1052,10 @@ CURLcode Curl_perform(struct SessionHandle *data) point to read-only data */ char *url_clone=strdup(data->change.url); - if(!url_clone) - return CURLE_OUT_OF_MEMORY; + if(!url_clone) { + res = CURLE_OUT_OF_MEMORY; + break; /* skip out of this loop NOW */ + } /* protsep points to the start of the host name */ protsep=strstr(url_clone, "//"); @@ -1070,8 +1089,10 @@ CURLcode Curl_perform(struct SessionHandle *data) 1 + /* possible slash */ strlen(newurl) + 1/* zero byte */); - if(!newest) - return CURLE_OUT_OF_MEMORY; + if(!newest) { + res = CURLE_OUT_OF_MEMORY; + break; /* go go go out from this loop */ + } sprintf(newest, "%s%s%s", url_clone, ('/' == newurl[0])?"":"/", newurl); free(newurl); @@ -1159,6 +1180,11 @@ CURLcode Curl_perform(struct SessionHandle *data) if(newurl) free(newurl); +#if defined(HAVE_SIGNAL) && defined(SIGPIPE) + /* restore the signal handler for SIGPIPE before we get back */ + signal(SIGPIPE, prev_signal); +#endif + return res; } |