From b89bc8a6cb3b93997647ceefc5b17bf05f20a0d0 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 1 Dec 2011 22:53:30 +0900 Subject: 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. --- src/WatchProcessCommand.cc | 132 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/WatchProcessCommand.cc (limited to 'src/WatchProcessCommand.cc') diff --git a/src/WatchProcessCommand.cc b/src/WatchProcessCommand.cc new file mode 100644 index 00000000..b68c5ef7 --- /dev/null +++ b/src/WatchProcessCommand.cc @@ -0,0 +1,132 @@ +/* */ +/* + * Copyright 2011 Emmanuel Engelhart + * + * 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 +#import +#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 -- cgit