# HG changeset patch # User jwe # Date 1191972124 0 # Node ID 980449b7e05c63498001f5359aa35270417fe060 # Parent f20010b5dcf0dbc90008381e5e6f546dae157679 [project @ 2007-10-09 23:22:04 by jwe] diff -r f20010b5dcf0 -r 980449b7e05c src/ChangeLog --- a/src/ChangeLog Tue Oct 09 21:22:57 2007 +0000 +++ b/src/ChangeLog Tue Oct 09 23:22:04 2007 +0000 @@ -1,9 +1,15 @@ +2007-10-09 John W. Eaton + + * DLD-FUNCTIONS/urlwrite.cc (urlget_cleanup): New function. + (urlget): Protect call to curl_easy_perform with + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE and + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE. + 2007-10-09 David Bateman * input.cc (accept_line): Drop this function and remove automatic insertion of closing quotes as the transpose operator confuses it. (initialize_command_input): Remove accept_line from here as well. - 2007-10-09 John W. Eaton diff -r f20010b5dcf0 -r 980449b7e05c src/DLD-FUNCTIONS/urlwrite.cc --- a/src/DLD-FUNCTIONS/urlwrite.cc Tue Oct 09 21:22:57 2007 +0000 +++ b/src/DLD-FUNCTIONS/urlwrite.cc Tue Oct 09 23:22:04 2007 +0000 @@ -90,6 +90,13 @@ // curl front-end +static void +urlget_cleanup (CURL *curl) +{ + curl_easy_cleanup (curl); + curl_global_cleanup (); +} + static CURLcode urlget (const std::string& url, const std::string& method, const Cell& param, std::ostream& stream) @@ -130,19 +137,44 @@ // Follow redirects. curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt (curl, CURLOPT_NOPROGRESS, false); + curl_easy_setopt (curl, CURLOPT_NOPROGRESS, true); curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, url.c_str ()); curl_easy_setopt (curl, CURLOPT_FAILONERROR, true); // Switch on full protocol/debug output // curl_easy_setopt(curl, CURLOPT_VERBOSE, true); - CURLcode res = curl_easy_perform (curl); + CURLcode res = CURLE_OK; + + // To understand the following, see the definitions of these macros + // in libcruft/misc/quit.h. The idea is that we call sigsetjmp here + // then the signal handler calls siglongjmp to get back here + // immediately. Then we perform some cleanup and throw an interrupt + // exception which will get us back to the top level, cleaning up + // any local C++ objects on the stack as we go. + + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_1; + + // We were interrupted (this code is inside a block that is only + // called when siglongjmp is called from a signal handler). - // Always cleanup. - curl_easy_cleanup (curl); + // Is there a better error code to use? Maybe it doesn't matter + // because we are about to throw an execption. + + res = CURLE_ABORTED_BY_CALLBACK; + urlget_cleanup (curl); + octave_throw_interrupt_exception (); + + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE_2; - curl_global_cleanup (); + res = curl_easy_perform (curl); + + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + // If we are not interuppted, we will end up here, so we still need + // to clean up. + + urlget_cleanup (curl); return res; }