aboutsummaryrefslogtreecommitdiff
path: root/lib/transfer.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2001-11-07 14:13:29 +0000
committerDaniel Stenberg <daniel@haxx.se>2001-11-07 14:13:29 +0000
commitfe3a78ab1997f650dd6e76a7a0ba51b72546221e (patch)
tree66ec727b4544f297e672592c57b12b7d14e49bc7 /lib/transfer.c
parent1a984ea84771a85df08f6a97e7cbac3ce379743e (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.c36
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;
}