aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--lib/transfer.c36
-rw-r--r--lib/url.c32
2 files changed, 53 insertions, 15 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;
}
diff --git a/lib/url.c b/lib/url.c
index 31e1459ca..079e9575a 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -143,13 +143,23 @@ RETSIGTYPE alarmfunc(int signal)
}
#endif
+
+/*
+ * This is the internal function curl_easy_cleanup() calls. This should
+ * cleanup and free all resources associated with this sessionhandle.
+ *
+ * NOTE: if we ever add something that attempts to write to a socket or
+ * similar here, we must ignore SIGPIPE first. It is currently only done
+ * when curl_easy_perform() is invoked.
+ */
+
CURLcode Curl_close(struct SessionHandle *data)
{
/* Loop through all open connections and kill them one by one */
while(-1 != ConnectionKillOne(data));
#ifdef USE_SSLEAY
- /* Close down all open info open SSL and sessions */
+ /* Close down all open SSL info and sessions */
Curl_SSL_Close_All(data);
#endif
@@ -258,13 +268,6 @@ CURLcode Curl_open(struct SessionHandle **curl)
*curl = data;
- /*************************************************************
- * Tell signal handler to ignore SIGPIPE
- *************************************************************/
-#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
- (void) signal(SIGPIPE, SIG_IGN);
-#endif
-
return CURLE_OK;
}
@@ -1141,7 +1144,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
{
char *tmp;
char *buf;
- CURLcode result;
+ CURLcode result=CURLE_OK;
char resumerange[40]="";
struct connectdata *conn;
struct connectdata *conn_temp;
@@ -1154,6 +1157,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
#ifdef HAVE_SIGACTION
struct sigaction keep_sigact; /* store the old struct here */
bool keep_copysig; /* did copy it? */
+#else
+#ifdef HAVE_SIGNAL
+ void *keep_sigact; /* store the old handler here */
+#endif
#endif
/*************************************************************
@@ -1941,7 +1948,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
#else
/* no sigaction(), revert to the much lamer signal() */
#ifdef HAVE_SIGNAL
- signal(SIGALRM, alarmfunc);
+ keep_sigact = signal(SIGALRM, alarmfunc);
#endif
#endif
@@ -2006,6 +2013,11 @@ static CURLcode CreateConnection(struct SessionHandle *data,
and clean */
sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
}
+#else
+#ifdef HAVE_SIGNAL
+ /* restore the previous SIGALRM handler */
+ signal(SIGALRM, keep_sigact);
+#endif
#endif
/* switch back the alarm() to either zero or to what it was before minus
the time we spent until now! */