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 | |
| 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')
| -rw-r--r-- | lib/transfer.c | 36 | ||||
| -rw-r--r-- | lib/url.c | 32 | 
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;  } @@ -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! */ | 
