Browse Source

2008-02-21 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	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
Tatsuhiro Tsujikawa 17 years ago
parent
commit
c4aaea3ca2
6 changed files with 91 additions and 21 deletions
  1. 9 0
      ChangeLog
  2. 6 3
      src/MultiUrlRequestInfo.cc
  3. 4 1
      src/MultiUrlRequestInfo.h
  4. 30 0
      src/RequestGroupMan.cc
  5. 22 0
      src/RequestGroupMan.h
  6. 20 17
      src/main.cc

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+2008-02-21  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	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  <tujikawa at rednoah dot com>
 
 	IPv6 support for SocketCore class.

+ 6 - 3
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

+ 4 - 1
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<MultiUrlRequestInfo> MultiUrlRequestInfoHandle;

+ 30 - 0
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<SharedHandle<DownloadResult> >::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:

+ 22 - 0
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<RequestGroupMan> RequestGroupManHandle;

+ 20 - 17
src/main.cc

@@ -117,7 +117,7 @@ RequestGroupHandle createRequestGroup(const Option* op, const std::deque<std::st
 extern Option* option_processing(int argc, char* const argv[]);
 
 #ifdef ENABLE_BITTORRENT
-void downloadBitTorrent(Option* op, const std::deque<std::string>& uri)
+int32_t downloadBitTorrent(Option* op, const std::deque<std::string>& uri)
 {
   std::deque<std::string> nargs;
   if(op->get(PREF_PARAMETERIZED_URI) == V_TRUE) {
@@ -141,22 +141,22 @@ void downloadBitTorrent(Option* op, const std::deque<std::string>& 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<std::string>& uris)
+int32_t downloadUri(Option* op, const std::deque<std::string>& uris)
 {
   std::deque<std::string> nargs;
   if(op->get(PREF_PARAMETERIZED_URI) == V_TRUE) {
@@ -220,7 +220,7 @@ void downloadUri(Option* op, const std::deque<std::string>& 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();