diff --git a/ChangeLog b/ChangeLog index 56701ee8..18d855d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-02-21 Tatsuhiro Tsujikawa + + Fixed the bug that a return code is always 0. BUG#1897704 + If error occurred during the download or there exist unfinished + downloads, aria2 returns with code 1. + * src/RequestGroupMan.{h, cc} + * src/MultiUrlRequestInfo.{h, cc} + * src/main.cc + 2008-02-20 Tatsuhiro Tsujikawa IPv6 support for SocketCore class. diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc index 9180c551..f31b0730 100644 --- a/src/MultiUrlRequestInfo.cc +++ b/src/MultiUrlRequestInfo.cc @@ -81,13 +81,13 @@ void MultiUrlRequestInfo::printMessageForContinue() << "\n"; } -void MultiUrlRequestInfo::execute() +int32_t MultiUrlRequestInfo::execute() { { DNSCacheHandle dnsCache = new SimpleDNSCache(); DNSCacheSingletonHolder::instance(dnsCache); } - + int32_t returnValue = 0; try { DownloadEngineHandle e = DownloadEngineFactory().newDownloadEngine(_option, _requestGroups); @@ -110,8 +110,10 @@ void MultiUrlRequestInfo::execute() e->_requestGroupMan->showDownloadResults(std::cout); std::cout << std::flush; - if(!e->_requestGroupMan->downloadFinished()) { + RequestGroupMan::DownloadStat s = e->_requestGroupMan->getDownloadStat(); + if(!s.allCompleted()) { printMessageForContinue(); + returnValue = 1; } } catch(RecoverableException *ex) { _logger->error(EX_EXCEPTION_CAUGHT, ex); @@ -119,6 +121,7 @@ void MultiUrlRequestInfo::execute() } Util::setGlobalSignalHandler(SIGINT, SIG_DFL, 0); Util::setGlobalSignalHandler(SIGTERM, SIG_DFL, 0); + return returnValue; } } // namespace aria2 diff --git a/src/MultiUrlRequestInfo.h b/src/MultiUrlRequestInfo.h index 87a429f1..07ed6176 100644 --- a/src/MultiUrlRequestInfo.h +++ b/src/MultiUrlRequestInfo.h @@ -60,7 +60,10 @@ public: virtual ~MultiUrlRequestInfo(); - void execute(); + /** + * Returns 0 if all downloads have completed, otherwise returns 1. + */ + int32_t execute(); }; typedef SharedHandle MultiUrlRequestInfoHandle; diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc index 39dfe852..a21a4f27 100644 --- a/src/RequestGroupMan.cc +++ b/src/RequestGroupMan.cc @@ -219,6 +219,36 @@ void RequestGroupMan::closeFile() } } +RequestGroupMan::DownloadStat RequestGroupMan::getDownloadStat() const +{ + DownloadStat stat; + size_t finished = 0; + size_t error = 0; + size_t inprogress = 0; + for(std::deque >::const_iterator itr = _downloadResults.begin(); + itr != _downloadResults.end(); ++itr) { + if((*itr)->result == DownloadResult::FINISHED) { + ++finished; + } else { + ++error; + } + } + for(RequestGroups::const_iterator itr = _requestGroups.begin(); + itr != _requestGroups.end(); ++itr) { + DownloadResultHandle result = (*itr)->createDownloadResult(); + if(result->result == DownloadResult::FINISHED) { + ++finished; + } else { + ++inprogress; + } + } + stat.setCompleted(finished); + stat.setError(error); + stat.setInProgress(inprogress); + stat.setWaiting(_reservedGroups.size()); + return stat; +} + void RequestGroupMan::showDownloadResults(std::ostream& o) const { // Download Results: diff --git a/src/RequestGroupMan.h b/src/RequestGroupMan.h index a58ca909..c80545a5 100644 --- a/src/RequestGroupMan.h +++ b/src/RequestGroupMan.h @@ -98,6 +98,28 @@ public: bool isSameFileBeingDownloaded(RequestGroup* requestGroup) const; TransferStat calculateStat(); + + class DownloadStat { + private: + size_t _completed; + size_t _error; + size_t _inProgress; + size_t _waiting; + public: + DownloadStat():_completed(0), _error(0), _inProgress(0), _waiting(0) {} + + void setCompleted(size_t c) { _completed = c; } + void setError(size_t c) { _error = c; } + void setInProgress(size_t c) { _inProgress = c; } + void setWaiting(size_t c) { _waiting = c; } + + bool allCompleted() const + { + return _error == 0 && _inProgress == 0 && _waiting == 0; + } + }; + + DownloadStat getDownloadStat() const; }; typedef SharedHandle RequestGroupManHandle; diff --git a/src/main.cc b/src/main.cc index eed8cf49..0afb9b8c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -117,7 +117,7 @@ RequestGroupHandle createRequestGroup(const Option* op, const std::deque& uri) +int32_t downloadBitTorrent(Option* op, const std::deque& uri) { std::deque nargs; if(op->get(PREF_PARAMETERIZED_URI) == V_TRUE) { @@ -141,22 +141,22 @@ void downloadBitTorrent(Option* op, const std::deque& uri) RequestGroups groups; groups.push_back(rg); - MultiUrlRequestInfo(groups, op).execute(); + return MultiUrlRequestInfo(groups, op).execute(); } #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK -void downloadMetalink(Option* op) +int32_t downloadMetalink(Option* op) { RequestGroups groups = Metalink2RequestGroup(op).generate(op->get(PREF_METALINK_FILE)); if(groups.empty()) { throw new FatalException("No files to download."); } - MultiUrlRequestInfo(groups, op).execute(); + return MultiUrlRequestInfo(groups, op).execute(); } #endif // ENABLE_METALINK -void downloadUriList(Option* op, std::istream& in) +int32_t downloadUriList(Option* op, std::istream& in) { UriListParser p; RequestGroups groups; @@ -179,23 +179,23 @@ void downloadUriList(Option* op, std::istream& in) groups.push_back(rg); } } - MultiUrlRequestInfo(groups, op).execute(); + return MultiUrlRequestInfo(groups, op).execute(); } -void downloadUriList(Option* op) +int32_t downloadUriList(Option* op) { if(op->get(PREF_INPUT_FILE) == "-") { - downloadUriList(op, std::cin); + return downloadUriList(op, std::cin); } else { if(!File(op->get(PREF_INPUT_FILE)).isFile()) { throw new FatalException(EX_FILE_OPEN, op->get(PREF_INPUT_FILE).c_str(), "No such file"); } std::ifstream f(op->get(PREF_INPUT_FILE).c_str()); - downloadUriList(op, f); + return downloadUriList(op, f); } } -void downloadUri(Option* op, const std::deque& uris) +int32_t downloadUri(Option* op, const std::deque& uris) { std::deque nargs; if(op->get(PREF_PARAMETERIZED_URI) == V_TRUE) { @@ -220,7 +220,7 @@ void downloadUri(Option* op, const std::deque& uris) RequestGroupHandle rg = createRequestGroup(op, xargs, op->get(PREF_OUT)); groups.push_back(rg); } - MultiUrlRequestInfo(groups, op).execute(); + return MultiUrlRequestInfo(groups, op).execute(); } int main(int argc, char* argv[]) @@ -276,7 +276,7 @@ int main(int argc, char* argv[]) #ifdef SIGPIPE Util::setGlobalSignalHandler(SIGPIPE, SIG_IGN, 0); #endif - + int32_t returnValue = 0; #ifdef ENABLE_BITTORRENT if(op->defined(PREF_TORRENT_FILE)) { if(op->get(PREF_SHOW_FILES) == V_TRUE) { @@ -284,7 +284,7 @@ int main(int argc, char* argv[]) btContext->load(op->get(PREF_TORRENT_FILE)); std::cout << btContext << std::endl; } else { - downloadBitTorrent(op, args); + returnValue = downloadBitTorrent(op, args); } } else @@ -294,20 +294,23 @@ int main(int argc, char* argv[]) if(op->get(PREF_SHOW_FILES) == V_TRUE) { Util::toStream(std::cout, MetalinkEntry::toFileEntry(MetalinkHelper::parseAndQuery(op->get(PREF_METALINK_FILE), op))); } else { - downloadMetalink(op); + returnValue = downloadMetalink(op); } } else #endif // ENABLE_METALINK if(op->defined(PREF_INPUT_FILE)) { - downloadUriList(op); + returnValue = downloadUriList(op); } else { - downloadUri(op, args); + returnValue = downloadUri(op, args); } + if(returnValue == 1) { + exitStatus = EXIT_FAILURE; + } } catch(Exception* ex) { std::cerr << EX_EXCEPTION_CAUGHT << "\n" << *ex << std::endl; delete ex; - exit(EXIT_FAILURE); + exitStatus = EXIT_FAILURE; } delete op; LogFactory::release();