summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Context.cc15
-rw-r--r--src/KeepRunningCommand.cc3
-rw-r--r--src/MultiUrlRequestInfo.cc69
-rw-r--r--src/MultiUrlRequestInfo.h9
-rw-r--r--src/aria2api.cc25
-rw-r--r--src/includes/aria2/aria2.h33
6 files changed, 98 insertions, 56 deletions
diff --git a/src/Context.cc b/src/Context.cc
index 81022e24..ad6b1af1 100644
--- a/src/Context.cc
+++ b/src/Context.cc
@@ -34,7 +34,6 @@
/* copyright --> */
#include "Context.h"
-#include <signal.h>
#include <unistd.h>
#include <getopt.h>
@@ -223,20 +222,6 @@ Context::Context(bool standalone,
std::string iface = op->get(PREF_INTERFACE);
SocketCore::bindAddress(iface);
}
- sigset_t mask;
-#ifdef HAVE_SIGACTION
- sigemptyset(&mask);
-#else // !HAVE_SIGACTION
- mask = 0;
-#endif // !HAVE_SIGACTION
-#ifdef SIGPIPE
- util::setGlobalSignalHandler(SIGPIPE, &mask, SIG_IGN, 0);
-#endif
-#ifdef SIGCHLD
- // Avoid to create zombie process when forked child processes are
- // died.
- util::setGlobalSignalHandler(SIGCHLD, &mask, SIG_IGN, 0);
-#endif // SIGCHILD
std::vector<SharedHandle<RequestGroup> > requestGroups;
SharedHandle<UriListParser> uriListParser;
#ifdef ENABLE_BITTORRENT
diff --git a/src/KeepRunningCommand.cc b/src/KeepRunningCommand.cc
index f917d5e1..995f3027 100644
--- a/src/KeepRunningCommand.cc
+++ b/src/KeepRunningCommand.cc
@@ -49,8 +49,7 @@ KeepRunningCommand::~KeepRunningCommand() {}
bool KeepRunningCommand::execute()
{
- if(!e_->getRequestGroupMan()->getKeepRunning() ||
- e_->isHaltRequested()) {
+ if(e_->isHaltRequested()) {
return true;
}
e_->addCommand(this);
diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc
index 5746b748..7d16e33e 100644
--- a/src/MultiUrlRequestInfo.cc
+++ b/src/MultiUrlRequestInfo.cc
@@ -112,8 +112,9 @@ MultiUrlRequestInfo::MultiUrlRequestInfo
: option_(op),
statCalc_(statCalc),
summaryOut_(summaryOut),
- uriListParser_(uriListParser)
+ uriListParser_(uriListParser),
// TODO init mask_
+ useSignalHandler_(true)
{
requestGroups_.swap(requestGroups);
}
@@ -238,27 +239,15 @@ int MultiUrlRequestInfo::prepare()
if(uriListParser_) {
e_->getRequestGroupMan()->setUriListParser(uriListParser_);
}
-#ifdef HAVE_SIGACTION
- sigemptyset(&mask_);
- sigaddset(&mask_, SIGINT);
- sigaddset(&mask_, SIGTERM);
-#ifdef SIGHUP
- sigaddset(&mask_, SIGHUP);
-#endif // SIGHUP
-#else // !HAVE_SIGACTION
- mask_ = 0;
-#endif // !HAVE_SIGACTION
-
-#ifdef SIGHUP
- util::setGlobalSignalHandler(SIGHUP, &mask_, handler, 0);
-#endif // SIGHUP
- util::setGlobalSignalHandler(SIGINT, &mask_, handler, 0);
- util::setGlobalSignalHandler(SIGTERM, &mask_, handler, 0);
-
+ if(useSignalHandler_) {
+ setupSignalHandlers();
+ }
e_->getRequestGroupMan()->getNetStat().downloadStart();
} catch(RecoverableException& e) {
SingletonHolder<Notifier>::clear();
- resetSignalHandlers();
+ if(useSignalHandler_) {
+ resetSignalHandlers();
+ }
return -1;
}
return 0;
@@ -319,10 +308,43 @@ error_code::Value MultiUrlRequestInfo::execute()
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
}
error_code::Value returnValue = getResult();
- resetSignalHandlers();
+ if(useSignalHandler_) {
+ resetSignalHandlers();
+ }
return returnValue;
}
+void MultiUrlRequestInfo::setupSignalHandlers()
+{
+#ifdef HAVE_SIGACTION
+ sigemptyset(&mask_);
+#else // !HAVE_SIGACTION
+ mask_ = 0;
+#endif // !HAVE_SIGACTION
+#ifdef SIGPIPE
+ util::setGlobalSignalHandler(SIGPIPE, &mask_, SIG_IGN, 0);
+#endif // SIGPIPE
+#ifdef SIGCHLD
+ // Avoid to create zombie process when forked child processes are
+ // died.
+ util::setGlobalSignalHandler(SIGCHLD, &mask_, SIG_IGN, 0);
+#endif // SIGCHILD
+
+#ifdef HAVE_SIGACTION
+ sigaddset(&mask_, SIGINT);
+ sigaddset(&mask_, SIGTERM);
+# ifdef SIGHUP
+ sigaddset(&mask_, SIGHUP);
+# endif // SIGHUP
+#endif // HAVE_SIGACTION
+
+#ifdef SIGHUP
+ util::setGlobalSignalHandler(SIGHUP, &mask_, handler, 0);
+#endif // SIGHUP
+ util::setGlobalSignalHandler(SIGINT, &mask_, handler, 0);
+ util::setGlobalSignalHandler(SIGTERM, &mask_, handler, 0);
+}
+
void MultiUrlRequestInfo::resetSignalHandlers()
{
#ifdef HAVE_SIGACTION
@@ -333,6 +355,13 @@ void MultiUrlRequestInfo::resetSignalHandlers()
#endif // SIGHUP
util::setGlobalSignalHandler(SIGINT, &mask_, SIG_DFL, 0);
util::setGlobalSignalHandler(SIGTERM, &mask_, SIG_DFL, 0);
+
+#ifdef SIGCHLD
+ util::setGlobalSignalHandler(SIGCHLD, &mask_, SIG_DFL, 0);
+#endif // SIGCHILD
+#ifdef SIGPIPE
+ util::setGlobalSignalHandler(SIGPIPE, &mask_, SIG_DFL, 0);
+#endif // SIGPIPE
}
const SharedHandle<DownloadEngine>&
diff --git a/src/MultiUrlRequestInfo.h b/src/MultiUrlRequestInfo.h
index 1d0176dd..6a324af0 100644
--- a/src/MultiUrlRequestInfo.h
+++ b/src/MultiUrlRequestInfo.h
@@ -70,7 +70,10 @@ private:
sigset_t mask_;
+ bool useSignalHandler_;
+
void printMessageForContinue();
+ void setupSignalHandlers();
void resetSignalHandlers();
public:
/*
@@ -105,6 +108,12 @@ public:
error_code::Value getResult();
const SharedHandle<DownloadEngine>& getDownloadEngine() const;
+
+ // Signal handlers are not prepared if false is given.
+ void setUseSignalHandler(bool useSignalHandler)
+ {
+ useSignalHandler_ = useSignalHandler;
+ }
};
} // namespace aria2
diff --git a/src/aria2api.cc b/src/aria2api.cc
index dcf5a007..30f0b02e 100644
--- a/src/aria2api.cc
+++ b/src/aria2api.cc
@@ -68,6 +68,11 @@ Session::Session(const KeyVals& options)
Session::~Session()
{}
+SessionConfig::SessionConfig()
+ : keepRunning(false),
+ useSignalHandler(true)
+{}
+
namespace {
Platform* platform = 0;
} // namespace
@@ -91,7 +96,7 @@ int libraryDeinit()
return 0;
}
-Session* sessionNew(const KeyVals& options)
+Session* sessionNew(const KeyVals& options, const SessionConfig& config)
{
int rv;
Session* session;
@@ -101,6 +106,9 @@ Session* sessionNew(const KeyVals& options)
return 0;
}
if(session->context->reqinfo) {
+ if(!config.useSignalHandler) {
+ session->context->reqinfo->setUseSignalHandler(false);
+ }
rv = session->context->reqinfo->prepare();
if(rv != 0) {
delete session;
@@ -108,9 +116,11 @@ Session* sessionNew(const KeyVals& options)
}
const SharedHandle<DownloadEngine>& e =
session->context->reqinfo->getDownloadEngine();
- // Add command to make aria2 keep event polling if
- // sessionConfigSetKeepRunning is set to true.
- e->addCommand(new KeepRunningCommand(e->newCUID(), e.get()));
+ if(config.keepRunning) {
+ e->getRequestGroupMan()->setKeepRunning(true);
+ // Add command to make aria2 keep event polling
+ e->addCommand(new KeepRunningCommand(e->newCUID(), e.get()));
+ }
} else {
delete session;
session = 0;
@@ -125,13 +135,6 @@ int sessionFinal(Session* session)
return rv;
}
-int sessionConfigSetKeepRunning(Session* session, bool flag)
-{
- session->context->reqinfo->getDownloadEngine()->getRequestGroupMan()
- ->setKeepRunning(flag);
- return 0;
-}
-
int run(Session* session, RUN_MODE mode)
{
const SharedHandle<DownloadEngine>& e =
diff --git a/src/includes/aria2/aria2.h b/src/includes/aria2/aria2.h
index 30284e55..add04f47 100644
--- a/src/includes/aria2/aria2.h
+++ b/src/includes/aria2/aria2.h
@@ -74,6 +74,30 @@ typedef uint64_t A2Gid;
// type of Key/Value pairs
typedef std::vector<std::pair<std::string, std::string> > KeyVals;
+struct SessionConfig {
+ // The constructor fills default values for all members.
+ SessionConfig();
+ // If the |keepRunning| member is true, run(session, RUN_ONCE) will
+ // return 1 even if there are no download to perform. The behavior
+ // is very similar to RPC server, except that this option does not
+ // enable RPC functionality. To stop aria2, use shutdown() function.
+ // The default value is false.
+ bool keepRunning;
+ // If the |useSignalHandler| is true, the library setups following
+ // signal handlers in sessionNew(). These signal handlers are
+ // removed in sessionFinal(). The default value is true. If the
+ // application sets this member to false, it must handle these
+ // signals and ensure that run() is repeatedly called until it
+ // returns 0 and sessionFinal() is called after that. Failing these
+ // steps will lead to not saving .aria2 control file and no session
+ // serialization.
+ //
+ // SIGPIPE, SIGCHLD: ignored
+ // SIGHUP, SIGTERM: handled like shutdown(session, true) is called.
+ // SIGINT: handled like shutdown(session, false) is called.
+ bool useSignalHandler;
+};
+
// Creates new Session object using the |options| as additional
// parameters. The |options| is treated as if they are specified in
// command-line to aria2c(1). This function returns the pointer to the
@@ -81,7 +105,7 @@ typedef std::vector<std::pair<std::string, std::string> > KeyVals;
//
// Please note that only one Session object can be created per
// process.
-Session* sessionNew(const KeyVals& options);
+Session* sessionNew(const KeyVals& options, const SessionConfig& config);
// Performs post-download action, including saving sessions etc and
// destroys the |session| object, releasing the allocated resources
@@ -94,13 +118,6 @@ enum RUN_MODE {
RUN_ONCE
};
-// If the |flag| is true, run(session, RUN_ONCE) will return 1 even if
-// there are no download to perform. The behavior is very similar to
-// RPC server, except that this option does not enable RPC
-// functionality. To stop aria2, use shutdown() function. This
-// function returns 0 if it succeeds, or -1.
-int sessionConfigSetKeepRunning(Session* session, bool flag);
-
// Performs event polling and actions for them. If the |mode| is
// RUN_DEFAULT, this function returns when no downloads are left to be
// processed. In this case, this function returns 0.