Added --stop-with-process=PID option.

This feature stops application when process PID is not running.  This
is useful if aria2 process is forked from a parent process. The parent
process can fork aria2 with its own pid and when parent process exits
for some reason, aria2 can detect it and shutdown itself.

The code which detects whether or not given process PID is running is
contributed by Emmanuel Engelhart.
pull/4/head
Tatsuhiro Tsujikawa 2011-12-01 22:53:30 +09:00
parent ce3b3fc88e
commit b89bc8a6cb
8 changed files with 221 additions and 1 deletions

View File

@ -52,6 +52,7 @@
#include "AutoSaveCommand.h"
#include "HaveEraseCommand.h"
#include "TimedHaltCommand.h"
#include "WatchProcessCommand.h"
#include "DownloadResult.h"
#include "ServerStatMan.h"
#include "a2io.h"
@ -163,6 +164,10 @@ DownloadEngineFactory::newDownloadEngine
stopSec));
}
}
if(op->defined(PREF_STOP_WITH_PROCESS)) {
unsigned int pid = op->getAsInt(PREF_STOP_WITH_PROCESS);
e->addRoutineCommand(new WatchProcessCommand(e->newCUID(), e.get(), pid));
}
if(op->getAsBool(PREF_ENABLE_RPC)) {
bool ok = false;
static int families[] = { AF_INET, AF_INET6 };

View File

@ -223,7 +223,8 @@ SRCS = Socket.h\
NullHandle.h\
a2iterator.h\
paramed_string.cc paramed_string.h\
rpc_helper.cc rpc_helper.h
rpc_helper.cc rpc_helper.h\
WatchProcessCommand.cc WatchProcessCommand.h
if MINGW_BUILD
SRCS += WinConsoleFile.cc WinConsoleFile.h

View File

@ -673,6 +673,15 @@ OptionHandlerFactory::createOptionHandlers()
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new NumberOptionHandler
(PREF_STOP_WITH_PROCESS,
TEXT_STOP_WITH_PROCESS,
NO_DEFAULT_VALUE,
0));
op->addTag(TAG_ADVANCED);
handlers.push_back(op);
}
{
SharedHandle<OptionHandler> op(new NumberOptionHandler
(PREF_SUMMARY_INTERVAL,

132
src/WatchProcessCommand.cc Normal file
View File

@ -0,0 +1,132 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2011 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "WatchProcessCommand.h"
#include "DownloadEngine.h"
#include "RequestGroupMan.h"
#include "LogFactory.h"
#include "Logger.h"
#include "fmt.h"
#ifdef __APPLE__
#import <sys/types.h>
#import <sys/sysctl.h>
#define MIBSIZE 4
#endif
namespace aria2 {
WatchProcessCommand::WatchProcessCommand
(cuid_t cuid,
DownloadEngine* e,
unsigned int pid,
bool forceHalt)
: TimeBasedCommand(cuid, e, 1, true),
pid_(pid),
forceHalt_(forceHalt)
{}
void WatchProcessCommand::preProcess()
{
if(getDownloadEngine()->getRequestGroupMan()->downloadFinished() ||
getDownloadEngine()->isHaltRequested()) {
enableExit();
}
}
void WatchProcessCommand::process()
{
// Check process pid_ is running. If it is not running, shutdown
// aria2.
A2_LOG_DEBUG(fmt("Checking proess %u", pid_));
bool waiting = true;
#ifdef _WIN32
HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid_);
DWORD ret = WaitForSingleObject(process, 0);
CloseHandle(process);
if (ret != WAIT_TIMEOUT) {
waiting = false;
}
#elif __APPLE__
int mib[MIBSIZE];
struct kinfo_proc kp;
size_t len = sizeof(kp);
mib[0]=CTL_KERN;
mib[1]=KERN_PROC;
mib[2]=KERN_PROC_PID;
mib[3]=pid_;
int ret = sysctl(mib, MIBSIZE, &kp, &len, NULL, 0);
if (ret == -1 || len <= 0) {
waiting = false;
}
#else
if (access(fmt("/proc/%u", pid_).c_str(), F_OK) == -1) {
waiting = false;
}
#endif
if(!waiting) {
A2_LOG_INFO
(fmt("CUID#%lld - Process %u is not running. Commencing shutdown.",
getCuid(), pid_));
if(forceHalt_) {
getDownloadEngine()->requestForceHalt();
} else {
getDownloadEngine()->requestHalt();
}
enableExit();
}
}
} // namespace aria2

62
src/WatchProcessCommand.h Normal file
View File

@ -0,0 +1,62 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2011 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_WATCH_PROCESS_COMMAND_H
#define D_WATCH_PROCESS_COMMAND_H
#include "TimeBasedCommand.h"
namespace aria2 {
class DownloadEngine;
class WatchProcessCommand:public TimeBasedCommand {
public:
WatchProcessCommand
(cuid_t cuid,
DownloadEngine* e,
unsigned int pid,
bool forceHalt = false);
virtual void preProcess();
virtual void process();
private:
unsigned int pid_;
bool forceHalt_;
};
} // namespace aria2
#endif // D_WATCH_PROCESS_COMMAND_H

View File

@ -321,6 +321,8 @@ const Pref* PREF_DOWNLOAD_RESULT = makePref("download-result");
const Pref* PREF_HASH_CHECK_ONLY = makePref("hash-check-only");
// values: hashType=digest
const Pref* PREF_CHECKSUM = makePref("checksum");
// value: pid
const Pref* PREF_STOP_WITH_PROCESS = makePref("stop-with-process");
/**
* FTP related preferences

View File

@ -276,6 +276,8 @@ extern const Pref* PREF_FTP_PASV;
extern const Pref* PREF_FTP_REUSE_CONNECTION;
// values: hashType=digest
extern const Pref* PREF_CHECKSUM;
// value: pid
extern const Pref* PREF_STOP_WITH_PROCESS;
/**
* HTTP related preferences

View File

@ -852,3 +852,10 @@
" option will be ignored in BitTorrent downloads.\n" \
" It will be also ignored if Metalink file\n" \
" contains piece hashes.")
#define TEXT_STOP_WITH_PROCESS \
_(" --stop-with-process=PID Stop application when process PID is not running.\n" \
" This is useful if aria2 process is forked from a\n" \
" parent process. The parent process can fork aria2\n" \
" with its own pid and when parent process exits\n" \
" for some reason, aria2 can detect it and shutdown\n" \
" itself.")