mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-14 14:12:31 +00:00
* Remove stale lock files if it is held by the same hostname and the
pid is not running. * Added rak::timer::from_seconds(uint32_t) and converted all uses to this to avoid overflows etc. * For each cycle through the tracker list without any successfull connections, increase the timeout by 20 seconds. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@635 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+63
-11
@@ -37,8 +37,11 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -47,6 +50,31 @@
|
||||
|
||||
namespace utils {
|
||||
|
||||
struct lockfile_valid_char {
|
||||
bool operator () (char c) {
|
||||
return !std::isgraph(c);
|
||||
}
|
||||
};
|
||||
|
||||
struct lockfile_valid_hostname {
|
||||
bool operator () (char c) {
|
||||
return !std::isgraph(c) || c == ':';
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
Lockfile::is_stale() {
|
||||
process_type process = locked_by();
|
||||
|
||||
char buf[256];
|
||||
|
||||
if (process.second <= 0 ||
|
||||
::gethostname(buf, 255) != 0 || buf != process.first)
|
||||
return false;
|
||||
|
||||
return ::kill(process.second, 0) != 0 && errno != EPERM;
|
||||
}
|
||||
|
||||
bool
|
||||
Lockfile::try_lock() {
|
||||
if (m_path.empty()) {
|
||||
@@ -54,6 +82,9 @@ Lockfile::try_lock() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_stale())
|
||||
::unlink(m_path.c_str());
|
||||
|
||||
// Just do a simple locking for now that isn't safe for network
|
||||
// devices.
|
||||
int fd = ::open(m_path.c_str(), O_RDWR | O_CREAT | O_EXCL, 0444);
|
||||
@@ -85,25 +116,46 @@ Lockfile::unlock() {
|
||||
return ::unlink(m_path.c_str()) != -1;
|
||||
}
|
||||
|
||||
struct lockfile_valid_char {
|
||||
bool operator () (char c) {
|
||||
return !std::isgraph(c);
|
||||
}
|
||||
};
|
||||
|
||||
std::string
|
||||
Lockfile::process_type
|
||||
Lockfile::locked_by() const {
|
||||
int fd = ::open(m_path.c_str(), O_RDONLY);
|
||||
|
||||
if (fd < 0)
|
||||
return "<error>";
|
||||
return process_type(std::string(), 0);
|
||||
|
||||
char buf[256];
|
||||
int pos = read(fd, buf, 255);
|
||||
char first[256];
|
||||
char* last = first + std::max(read(fd, first, 255), 0);
|
||||
|
||||
*last = '\0';
|
||||
::close(fd);
|
||||
|
||||
return std::string(buf, std::find_if(buf, buf + std::max(pos, 0), lockfile_valid_char()));
|
||||
char* endHostname = std::find_if(first, last, lockfile_valid_hostname());
|
||||
char* beginPid = endHostname;
|
||||
char* endPid;
|
||||
|
||||
long long int pid;
|
||||
|
||||
if (beginPid + 2 >= last ||
|
||||
*(beginPid++) != ':' ||
|
||||
*(beginPid++) != '+' ||
|
||||
(pid = strtoll(beginPid, &endPid, 10)) == 0 ||
|
||||
endPid == NULL)
|
||||
return process_type(std::string(), 0);
|
||||
|
||||
return process_type(std::string(first, endHostname), pid);
|
||||
}
|
||||
|
||||
std::string
|
||||
Lockfile::locked_by_as_string() const {
|
||||
process_type p = locked_by();
|
||||
|
||||
if (p.first.empty())
|
||||
return "<error>";
|
||||
|
||||
std::stringstream str;
|
||||
str << p.first << ":+" << p.second;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user