Teach file(DOWNLOAD|UPLOAD) to timeout after inactivity

Add option INACTIVITY_TIMEOUT to terminate the operation if there is no
progress for more than a given amount of time.
This commit is contained in:
Brad King 2011-06-01 09:55:42 -04:00
parent 8af1eaf499
commit faa7ec6e18
2 changed files with 51 additions and 4 deletions

View File

@ -2614,6 +2614,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
++i; ++i;
long timeout = 0; long timeout = 0;
long inactivity_timeout = 0;
std::string verboseLog; std::string verboseLog;
std::string statusVar; std::string statusVar;
std::string expectedMD5sum; std::string expectedMD5sum;
@ -2634,6 +2635,19 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false; 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") else if(*i == "LOG")
{ {
++i; ++i;
@ -2770,6 +2784,13 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
check_curl_result(res, "DOWNLOAD cannot set timeout: "); 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 // Need the progress helper's scope to last through the duration of
// the curl_easy_perform call... so this object is declared at function // the curl_easy_perform call... so this object is declared at function
// scope intentionally, rather than inside the "if(showProgress)" // scope intentionally, rather than inside the "if(showProgress)"
@ -2883,6 +2904,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
++i; ++i;
long timeout = 0; long timeout = 0;
long inactivity_timeout = 0;
std::string logVar; std::string logVar;
std::string statusVar; std::string statusVar;
bool showProgress = false; bool showProgress = false;
@ -2902,6 +2924,19 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
return false; 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") else if(*i == "LOG")
{ {
++i; ++i;
@ -3003,6 +3038,13 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
check_curl_result(res, "UPLOAD cannot set timeout: "); 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 // Need the progress helper's scope to last through the duration of
// the curl_easy_perform call... so this object is declared at function // the curl_easy_perform call... so this object is declared at function
// scope intentionally, rather than inside the "if(showProgress)" // scope intentionally, rather than inside the "if(showProgress)"

View File

@ -80,10 +80,11 @@ public:
" file(RELATIVE_PATH variable directory file)\n" " file(RELATIVE_PATH variable directory file)\n"
" file(TO_CMAKE_PATH path result)\n" " file(TO_CMAKE_PATH path result)\n"
" file(TO_NATIVE_PATH path result)\n" " file(TO_NATIVE_PATH path result)\n"
" file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log]\n" " file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]\n"
" [EXPECTED_MD5 sum] [SHOW_PROGRESS])\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n"
" file(UPLOAD filename url [TIMEOUT timeout] [STATUS status]\n" " [EXPECTED_MD5 sum])\n"
" [LOG log] [SHOW_PROGRESS])\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 " "WRITE will write a message into a file called 'filename'. It "
"overwrites the file if it already exists, and creates the file " "overwrites the file if it already exists, and creates the file "
"if it does not exist.\n" "if it does not exist.\n"
@ -161,6 +162,8 @@ public:
"numeric error means no error in the operation. " "numeric error means no error in the operation. "
"If TIMEOUT time is specified, the operation will " "If TIMEOUT time is specified, the operation will "
"timeout after time seconds, time should be specified as an integer. " "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 " "If EXPECTED_MD5 sum is specified, the operation will verify that the "
"downloaded file's actual md5 sum matches the expected value. If it " "downloaded file's actual md5 sum matches the expected value. If it "
"does not match, the operation fails with an error. " "does not match, the operation fails with an error. "
@ -176,6 +179,8 @@ public:
"numeric error means no error in the operation. " "numeric error means no error in the operation. "
"If TIMEOUT time is specified, the operation will " "If TIMEOUT time is specified, the operation will "
"timeout after time seconds, time should be specified as an integer. " "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 " "If SHOW_PROGRESS is specified, progress information will be printed "
"as status messages until the operation is complete." "as status messages until the operation is complete."
"\n" "\n"