diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index d28de0851..9a3de9ba9 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2614,6 +2614,7 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) ++i; long timeout = 0; + long inactivity_timeout = 0; std::string verboseLog; std::string statusVar; std::string expectedMD5sum; @@ -2634,6 +2635,19 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) return false; } } + else if(*i == "INACTIVITY_TIMEOUT") + { + ++i; + if(i != args.end()) + { + inactivity_timeout = atol(i->c_str()); + } + else + { + this->SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT."); + return false; + } + } else if(*i == "LOG") { ++i; @@ -2770,6 +2784,13 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) check_curl_result(res, "DOWNLOAD cannot set timeout: "); } + if(inactivity_timeout > 0) + { + // Give up if there is no progress for a long time. + ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1); + ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout); + } + // Need the progress helper's scope to last through the duration of // the curl_easy_perform call... so this object is declared at function // scope intentionally, rather than inside the "if(showProgress)" @@ -2883,6 +2904,7 @@ cmFileCommand::HandleUploadCommand(std::vector const& args) ++i; long timeout = 0; + long inactivity_timeout = 0; std::string logVar; std::string statusVar; bool showProgress = false; @@ -2902,6 +2924,19 @@ cmFileCommand::HandleUploadCommand(std::vector const& args) return false; } } + else if(*i == "INACTIVITY_TIMEOUT") + { + ++i; + if(i != args.end()) + { + inactivity_timeout = atol(i->c_str()); + } + else + { + this->SetError("UPLOAD missing time for INACTIVITY_TIMEOUT."); + return false; + } + } else if(*i == "LOG") { ++i; @@ -3003,6 +3038,13 @@ cmFileCommand::HandleUploadCommand(std::vector const& args) check_curl_result(res, "UPLOAD cannot set timeout: "); } + if(inactivity_timeout > 0) + { + // Give up if there is no progress for a long time. + ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1); + ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout); + } + // Need the progress helper's scope to last through the duration of // the curl_easy_perform call... so this object is declared at function // scope intentionally, rather than inside the "if(showProgress)" diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 1b6dbbfb1..162890abf 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -80,10 +80,11 @@ public: " file(RELATIVE_PATH variable directory file)\n" " file(TO_CMAKE_PATH path result)\n" " file(TO_NATIVE_PATH path result)\n" - " file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log]\n" - " [EXPECTED_MD5 sum] [SHOW_PROGRESS])\n" - " file(UPLOAD filename url [TIMEOUT timeout] [STATUS status]\n" - " [LOG log] [SHOW_PROGRESS])\n" + " file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]\n" + " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n" + " [EXPECTED_MD5 sum])\n" + " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n" + " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n" "WRITE will write a message into a file called 'filename'. It " "overwrites the file if it already exists, and creates the file " "if it does not exist.\n" @@ -161,6 +162,8 @@ public: "numeric error means no error in the operation. " "If TIMEOUT time is specified, the operation will " "timeout after time seconds, time should be specified as an integer. " + "The INACTIVITY_TIMEOUT specifies an integer number of seconds of " + "inactivity after which the operation should terminate. " "If EXPECTED_MD5 sum is specified, the operation will verify that the " "downloaded file's actual md5 sum matches the expected value. If it " "does not match, the operation fails with an error. " @@ -176,6 +179,8 @@ public: "numeric error means no error in the operation. " "If TIMEOUT time is specified, the operation will " "timeout after time seconds, time should be specified as an integer. " + "The INACTIVITY_TIMEOUT specifies an integer number of seconds of " + "inactivity after which the operation should terminate. " "If SHOW_PROGRESS is specified, progress information will be printed " "as status messages until the operation is complete." "\n"