changeset 6992:980449b7e05c

[project @ 2007-10-09 23:22:04 by jwe]
author jwe
date Tue, 09 Oct 2007 23:22:04 +0000
parents f20010b5dcf0
children 62c6ef95b98c
files src/ChangeLog src/DLD-FUNCTIONS/urlwrite.cc
diffstat 2 files changed, 44 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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  <jwe@octave.org>
+
+	* 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  <dbateman@free.fr>
 
 	* 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  <jwe@octave.org>
 
--- 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;
 }