我正在研究一個Unbuntu的C++程序,該程序使用curl_easy_perform下載tar歸檔文件,並將歸檔文件下載到/ tmp中後使用popen執行適當的tar命令行。popen(「tar xvf tarball.tar」)工作在調試但不是發佈版本
當我運行程序的調試版本時,popen(「tar xvf /tmp/example.tar -C/tmp/existingdir」)可以工作,但是當我在發佈版本中運行此命令時,popen調用總是失敗。
這裏是我的代碼,大多數錯誤檢查和無關的東西去掉:
//tl;dr version:
// first I download a tar archive from url using Curl and save it to filelocation,
// then I untar it using pOpen.
// pOpen always works in debug, never in release builds
////
Status ExpandTarBall(const MyString& FileName)
{
//extract the tar ball into a previously created temporary directory, tempDirPath
MyString args = "tar xvf /tmp/ + FileName + " -C " + tempDirPath;
cout << "running:" << args << endl;
// args example:
// tar xvf /tmp/UserIdXXxCtnAl/examplepackage -C /tmp/UserIdXXxCtnAl
//
Status result = ER_OPEN_FAILED;
FILE* fp = popen(args.c_str(), "re"); //<========== always works in debug builds, fails with 0 returned in release builds! :(
if (fp)
{
result = pclose(fp) == 0 ? ER_OK : ER_INVALID_DATA;
}
return result;
}
//Note: MyString is an std::string class with some local extensions
Status SslDownloader::DownloadFile(MyString url, MyString fileLocation, bool sslVerify) {
CURL* curl = NULL;
CurlInitHelper helper(curl);
cout << "downloading from " << url.c_str() << " to " << fileLocation.c_str() << endl;
if (!curl) {
return ER_SSL_INIT;
}
FILE* fp = fopen(fileLocation.c_str(), "wb");
if(NULL == fp) {
return ER_OPEN_FAILED;
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_USERAGENT, AJPM_USER_AGENT);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
if (sslVerify) {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
curl_easy_setopt(curl, CURLOPT_CAINFO, AJPM_CERT_STORE_LOCATION);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
} else {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
}
CURLcode res = curl_easy_perform(curl);
if (0 != fclose(fp)) {
return ER_WRITE_ERROR;
}
if (res != CURLE_OK) {
return res == ER_SSL_CONNECT;
}
cout << "SSL download of " << fileLocation.c_str() << " succeeded\n"; // works every time
return ExpandTarBall(const MyString& FileName);
}
我缺少什麼簡單的事情?
什麼意思* debug *或* release *模式,是否有一些編譯標誌? – gipi 2014-09-01 21:11:23
你應該檢查你正在裝配你的'tar'命令行的那一行。 – user2719058 2014-09-01 23:25:08