mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-12 13:12:32 +00:00
* Don't show ETA on finished and stopped torrents.
* Added percentage completed to active unfinished torrents. * Re-enabled different seeding and leeching priorities. * Make a temporary container in AvailableList::insert(AddressList*) when doing std::set_differernce. AvailableList's std::vector would resize and cause invalidated iterators to be used. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@630 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+56
-19
@@ -139,6 +139,21 @@
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>^O</term>
|
||||
<listitem><para>
|
||||
Change the destination directory of the download. The
|
||||
torrent must be closed.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>+ | -</term>
|
||||
<listitem><para>
|
||||
Change the priority of the download.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>backspace</term>
|
||||
<listitem><para>
|
||||
@@ -155,6 +170,13 @@
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>^P</term>
|
||||
<listitem><para>
|
||||
Call commands or change settings.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</refsect2>
|
||||
@@ -424,6 +446,11 @@ seconds, starting from <emphasis>start</emphasis>. An
|
||||
<emphasis>start</emphasis> of zero calls it immediately. Currently
|
||||
<emphasis>command</emphasis> is forwarded to the option handler.
|
||||
|
||||
<emphasis>start</emphasis> and <emphasis>interval</emphasis> may
|
||||
optionally use a time format, <emphasis>dd:hh:mm:ss</emphasis>. F.ex to
|
||||
start a task every day at <emphasis>18:00</emphasis>, use
|
||||
<emphasis>18:00:00</emphasis>.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -455,9 +482,8 @@ to the filename provided.
|
||||
<term>remove_untied =</term>
|
||||
<listitem><para>
|
||||
|
||||
Stop or remove the torrents that are tied to filenames that has been
|
||||
deleted, the association is then cleared. Don't use
|
||||
<emphasis>remove_untied</emphasis> as it crashes the client.
|
||||
Stop or remove the torrents that are tied to filenames that have been
|
||||
deleted, the association is then cleared.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
@@ -530,23 +556,34 @@ deleted, the association is then cleared. Don't use
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<!-- <varlistentry> -->
|
||||
<!-- <term>throttle_interval = <replaceable>ms</replaceable></term> -->
|
||||
<!-- <listitem><para> -->
|
||||
<!-- Interval between throttle ticks in milli-seconds, must be -->
|
||||
<!-- between <emphasis>1-5000</emphasis> and defaults to -->
|
||||
<!-- <emphasis>1000</emphasis>. Shorter intervals will cause less -->
|
||||
<!-- bandwidth usage spikes while requiring more CPU resources. -->
|
||||
<!-- </para></listitem> -->
|
||||
<!-- </varlistentry> -->
|
||||
<varlistentry>
|
||||
<term>working_directory = <replaceable>directory</replaceable></term>
|
||||
<listitem><para>
|
||||
|
||||
<!-- <varlistentry> -->
|
||||
<!-- <term>tracker_dump = <replaceable>yes | no</replaceable></term> -->
|
||||
<!-- <listitem><para> -->
|
||||
<!-- Dump data received from trackers to the files -->
|
||||
<!-- "./tracker_dump.*". -->
|
||||
<!-- </para></listitem> -->
|
||||
<!-- </varlistentry> -->
|
||||
Changes the working directory of the process using
|
||||
<emphasis>chdir</emphasis>.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>session_on_completion = <replaceable>yes</replaceable></term>
|
||||
<listitem><para>
|
||||
|
||||
Controls whetever the session torrent is updated when a torrent
|
||||
finishes. By default on.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>session_lock = <replaceable>yes</replaceable></term>
|
||||
<listitem><para>
|
||||
|
||||
Controls whetever a lock file is created in the session directory.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
|
||||
+1
-2
@@ -53,6 +53,7 @@
|
||||
|
||||
Control::Control() :
|
||||
m_shutdownReceived(false),
|
||||
m_shutdownQuick(false),
|
||||
|
||||
m_ui(new ui::Root()),
|
||||
m_core(new core::Manager()),
|
||||
@@ -92,8 +93,6 @@ Control::initialize() {
|
||||
display::Window::slot_unschedule(rak::make_mem_fun(m_display, &display::Manager::unschedule));
|
||||
display::Window::slot_adjust(rak::make_mem_fun(m_display, &display::Manager::adjust_layout));
|
||||
|
||||
// m_core->get_poll_manager()->signal_interrupted().connect(sigc::mem_fun(*m_inputStdin, &input::InputEvent::event_read));
|
||||
// m_core->get_poll_manager()->signal_interrupted().connect(sigc::ptr_fun(display::Canvas::do_update));
|
||||
m_core->get_poll_manager()->get_http_stack()->set_user_agent(std::string(PACKAGE "/" VERSION "/") + torrent::version());
|
||||
|
||||
m_core->initialize_second();
|
||||
|
||||
@@ -152,9 +152,7 @@ CurlGet::perform(CURLMsg* msg) {
|
||||
else
|
||||
m_signalFailed.emit(curl_easy_strerror(msg->data.result));
|
||||
|
||||
if (m_handle != NULL)
|
||||
throw std::logic_error("CurlGet::perform finished but the object wasn't closed.");
|
||||
|
||||
// Do nothing below after emitting the signals.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-6
@@ -97,14 +97,14 @@ Download::~Download() {
|
||||
|
||||
void
|
||||
Download::start() {
|
||||
if (is_done()) {
|
||||
if (is_done())
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_seed").as_string()));
|
||||
torrent::download_set_priority(m_download, 2);
|
||||
} else {
|
||||
else
|
||||
m_download.set_connection_type(string_to_connection_type(m_variables.get("connection_leech").as_string()));
|
||||
torrent::download_set_priority(m_download, 4);
|
||||
}
|
||||
|
||||
// Update the priority to ensure it has the correct
|
||||
// seeding/unfinished modifiers.
|
||||
set_priority(priority());
|
||||
m_download.start();
|
||||
}
|
||||
|
||||
@@ -128,7 +128,12 @@ Download::set_priority(uint32_t p) {
|
||||
if (p >= 4)
|
||||
throw torrent::input_error("Priority out of range.");
|
||||
|
||||
torrent::download_set_priority(m_download, p * p);
|
||||
// Seeding torrents get half the priority of unfinished torrents.
|
||||
if (!is_done())
|
||||
torrent::download_set_priority(m_download, p * p * 2);
|
||||
else
|
||||
torrent::download_set_priority(m_download, p * p);
|
||||
|
||||
get_bencode().get_key("rtorrent").insert_key("priority", (int64_t)p);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "globals.h"
|
||||
#include "manager.h"
|
||||
|
||||
#include "download.h"
|
||||
#include "download_factory.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -47,6 +47,16 @@
|
||||
|
||||
namespace core {
|
||||
|
||||
struct download_list_call {
|
||||
download_list_call(Download* d) : m_download(d) {}
|
||||
|
||||
void operator () (const DownloadList::SlotMap::value_type& s) {
|
||||
s.second(m_download);
|
||||
}
|
||||
|
||||
Download* m_download;
|
||||
};
|
||||
|
||||
DownloadList::iterator
|
||||
DownloadList::insert(std::istream* str) {
|
||||
torrent::Download d = torrent::download_add(str);
|
||||
@@ -54,14 +64,14 @@ DownloadList::insert(std::istream* str) {
|
||||
iterator itr = Base::insert(end(), new Download(d));
|
||||
(*itr)->get_download().signal_download_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::finished), *itr));
|
||||
|
||||
m_slotMapInsert.for_each(*itr);
|
||||
std::for_each(m_slotMapInsert.begin(), m_slotMapInsert.end(), download_list_call(*itr));
|
||||
|
||||
return itr;
|
||||
}
|
||||
|
||||
DownloadList::iterator
|
||||
DownloadList::erase(iterator itr) {
|
||||
m_slotMapErase.for_each(*itr);
|
||||
std::for_each(m_slotMapErase.begin(), m_slotMapErase.end(), download_list_call(*itr));
|
||||
|
||||
torrent::download_remove((*itr)->get_download());
|
||||
delete *itr;
|
||||
@@ -74,7 +84,7 @@ DownloadList::open(Download* d) {
|
||||
if (d->get_download().is_open())
|
||||
return;
|
||||
|
||||
m_slotMapOpen.for_each(d);
|
||||
std::for_each(m_slotMapOpen.begin(), m_slotMapOpen.end(), download_list_call(d));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -83,7 +93,7 @@ DownloadList::close(Download* d) {
|
||||
return;
|
||||
|
||||
stop(d);
|
||||
m_slotMapClose.for_each(d);
|
||||
std::for_each(m_slotMapClose.begin(), m_slotMapClose.end(), download_list_call(d));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -93,7 +103,7 @@ DownloadList::start(Download* d) {
|
||||
return;
|
||||
|
||||
open(d);
|
||||
m_slotMapStart.for_each(d);
|
||||
std::for_each(m_slotMapStart.begin(), m_slotMapStart.end(), download_list_call(d));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -101,7 +111,7 @@ DownloadList::stop(Download* d) {
|
||||
if (!d->get_download().is_active())
|
||||
return;
|
||||
|
||||
m_slotMapStop.for_each(d);
|
||||
std::for_each(m_slotMapStop.begin(), m_slotMapStop.end(), download_list_call(d));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -113,7 +123,7 @@ DownloadList::clear() {
|
||||
|
||||
void
|
||||
DownloadList::finished(Download* d) {
|
||||
m_slotMapFinished.for_each(d);
|
||||
std::for_each(m_slotMapFinished.begin(), m_slotMapFinished.end(), download_list_call(d));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-17
@@ -39,8 +39,9 @@
|
||||
|
||||
#include <iosfwd>
|
||||
#include <list>
|
||||
|
||||
#include "download_slot_map.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sigc++/slot.h>
|
||||
|
||||
namespace core {
|
||||
|
||||
@@ -52,7 +53,8 @@ class Download;
|
||||
|
||||
class DownloadList : private std::list<Download*> {
|
||||
public:
|
||||
typedef std::list<Download*> Base;
|
||||
typedef std::list<Download*> Base;
|
||||
typedef std::map<std::string, sigc::slot1<void, Download*> > SlotMap;
|
||||
|
||||
using Base::iterator;
|
||||
using Base::const_iterator;
|
||||
@@ -80,28 +82,28 @@ public:
|
||||
void start(Download* d);
|
||||
void stop(Download* d);
|
||||
|
||||
DownloadSlotMap& slot_map_insert() { return m_slotMapInsert; }
|
||||
DownloadSlotMap& slot_map_erase() { return m_slotMapErase; }
|
||||
DownloadSlotMap& slot_map_open() { return m_slotMapOpen; }
|
||||
DownloadSlotMap& slot_map_close() { return m_slotMapClose; }
|
||||
DownloadSlotMap& slot_map_start() { return m_slotMapStart; }
|
||||
DownloadSlotMap& slot_map_stop() { return m_slotMapStop; }
|
||||
SlotMap& slot_map_insert() { return m_slotMapInsert; }
|
||||
SlotMap& slot_map_erase() { return m_slotMapErase; }
|
||||
SlotMap& slot_map_open() { return m_slotMapOpen; }
|
||||
SlotMap& slot_map_close() { return m_slotMapClose; }
|
||||
SlotMap& slot_map_start() { return m_slotMapStart; }
|
||||
SlotMap& slot_map_stop() { return m_slotMapStop; }
|
||||
|
||||
DownloadSlotMap& slot_map_finished() { return m_slotMapFinished; }
|
||||
SlotMap& slot_map_finished() { return m_slotMapFinished; }
|
||||
|
||||
private:
|
||||
void clear();
|
||||
|
||||
void finished(Download* d);
|
||||
|
||||
DownloadSlotMap m_slotMapInsert;
|
||||
DownloadSlotMap m_slotMapErase;
|
||||
DownloadSlotMap m_slotMapOpen;
|
||||
DownloadSlotMap m_slotMapClose;
|
||||
DownloadSlotMap m_slotMapStart;
|
||||
DownloadSlotMap m_slotMapStop;
|
||||
SlotMap m_slotMapInsert;
|
||||
SlotMap m_slotMapErase;
|
||||
SlotMap m_slotMapOpen;
|
||||
SlotMap m_slotMapClose;
|
||||
SlotMap m_slotMapStart;
|
||||
SlotMap m_slotMapStop;
|
||||
|
||||
DownloadSlotMap m_slotMapFinished;
|
||||
SlotMap m_slotMapFinished;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ DownloadStore::enable(bool lock) {
|
||||
m_lockfile.set_path(std::string());
|
||||
|
||||
if (!m_lockfile.try_lock())
|
||||
throw torrent::input_error("Could not lock session directory: \"" + m_path + "\".");
|
||||
throw torrent::input_error("Could not lock session directory: \"" + m_path + "\", held by \"" + m_lockfile.locked_by() + "\".");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -67,11 +67,6 @@ connect_signal_network_log(Download* d, torrent::Download::SlotString s) {
|
||||
d->get_download().signal_network_log(s);
|
||||
}
|
||||
|
||||
// static void
|
||||
// connect_signal_tracker_log(Download* d, torrent::Download::SlotString s) {
|
||||
// d->get_download().signal_tracker_failed(s);
|
||||
// }
|
||||
|
||||
static void
|
||||
connect_signal_storage_log(Download* d, torrent::Download::SlotString s) {
|
||||
d->get_download().signal_storage_error(s);
|
||||
|
||||
+21
-5
@@ -164,12 +164,20 @@ print_download_info(char* first, char* last, core::Download* d) {
|
||||
(double)d->get_download().bytes_done() / (double)(1 << 20),
|
||||
(double)d->get_download().bytes_total() / (double)(1 << 20));
|
||||
|
||||
first = print_buffer(first, last, " Rate: %5.1f / %5.1f KB Uploaded: %7.1f MB ",
|
||||
first = print_buffer(first, last, " Rate: %5.1f / %5.1f KB Uploaded: %7.1f MB",
|
||||
(double)d->get_download().up_rate()->rate() / (1 << 10),
|
||||
(double)d->get_download().down_rate()->rate() / (1 << 10),
|
||||
(double)d->get_download().up_rate()->total() / (1 << 20));
|
||||
|
||||
first = print_download_time_left(first, last, d);
|
||||
if (d->get_download().is_active() && !d->is_done()) {
|
||||
first = print_buffer(first, last, " ");
|
||||
first = print_download_percentage_done(first, last, d);
|
||||
|
||||
first = print_buffer(first, last, " ");
|
||||
first = print_download_time_left(first, last, d);
|
||||
} else {
|
||||
first = print_buffer(first, last, " ");
|
||||
}
|
||||
|
||||
if (d->priority() != 2)
|
||||
first = print_buffer(first, last, " [%s]", core::Download::priority_to_string(d->priority()));
|
||||
@@ -210,10 +218,9 @@ print_download_status(char* first, char* last, core::Download* d) {
|
||||
|
||||
char*
|
||||
print_download_time_left(char* first, char* last, core::Download* d) {
|
||||
uint32_t rate;
|
||||
uint32_t rate = d->get_download().down_rate()->rate();
|
||||
|
||||
if (!d->get_download().is_active() ||
|
||||
(rate = d->get_download().down_rate()->rate()) < 512)
|
||||
if (rate < 512)
|
||||
return print_buffer(first, last, "--:--:--");
|
||||
|
||||
time_t remaining = (d->get_download().bytes_total() - d->get_download().bytes_done()) / (rate & ~(uint32_t)(512 - 1));
|
||||
@@ -221,6 +228,15 @@ print_download_time_left(char* first, char* last, core::Download* d) {
|
||||
return print_ddhhmm(first, last, remaining);
|
||||
}
|
||||
|
||||
char*
|
||||
print_download_percentage_done(char* first, char* last, core::Download* d) {
|
||||
if (!d->is_open() || d->is_done())
|
||||
//return print_buffer(first, last, "[--%%]");
|
||||
return print_buffer(first, last, " ");
|
||||
else
|
||||
return print_buffer(first, last, "[%2u%%]", (d->get_download().chunks_done() * 100) / d->get_download().chunks_total());
|
||||
}
|
||||
|
||||
char*
|
||||
print_status_info(char* first, char* last) {
|
||||
if (torrent::up_throttle() == 0)
|
||||
|
||||
@@ -66,6 +66,7 @@ char* print_download_title(char* first, char* last, core::Download* d);
|
||||
char* print_download_info(char* first, char* last, core::Download* d);
|
||||
char* print_download_status(char* first, char* last, core::Download* d);
|
||||
char* print_download_time_left(char* first, char* last, core::Download* d);
|
||||
char* print_download_percentage_done(char* first, char* last, core::Download* d);
|
||||
|
||||
char* print_entry_tags(char* first, char* last);
|
||||
char* print_entry_file(char* first, char* last, const torrent::Entry& entry);
|
||||
|
||||
@@ -83,9 +83,10 @@ WindowPeerInfo::redraw() {
|
||||
m_download->variables()->get("connection_current").as_string().c_str(),
|
||||
m_download->variables()->get("connection_seed").as_string().c_str(),
|
||||
m_download->variables()->get("connection_leech").as_string().c_str());
|
||||
m_canvas->print(0, y++, "Priority: %u", torrent::download_priority(m_download->get_download()));
|
||||
|
||||
m_canvas->print(0, y++, "Directory: %s", m_download->variable_string("directory").c_str());
|
||||
m_canvas->print(0, y++, "Tied to file: %s", m_download->variable_string("tied_to_file").c_str());
|
||||
m_canvas->print(0, y++, "Directory: %s", m_download->variable_string("directory").c_str());
|
||||
m_canvas->print(0, y++, "Tied to file: %s", m_download->variable_string("tied_to_file").c_str());
|
||||
|
||||
y++;
|
||||
|
||||
|
||||
-16
@@ -249,22 +249,6 @@ do_panic(int signum) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void
|
||||
receive_tracker_dump(std::istream* s) {
|
||||
std::stringstream filename;
|
||||
filename << "./tracker_dump." << rak::timer::current().seconds();
|
||||
|
||||
std::fstream out(filename.str().c_str(), std::ios::out | std::ios::trunc);
|
||||
|
||||
if (!out.is_open())
|
||||
return;
|
||||
|
||||
s->seekg(0);
|
||||
|
||||
std::copy(std::istream_iterator<char>(*s), std::istream_iterator<char>(),
|
||||
std::ostream_iterator<char>(out));
|
||||
}
|
||||
|
||||
void
|
||||
print_help() {
|
||||
std::cout << "Rakshasa's BitTorrent client version " VERSION "." << std::endl;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/torrent.h>
|
||||
|
||||
#include "core/download.h"
|
||||
#include "core/manager.h"
|
||||
#include "ui/root.h"
|
||||
#include "utils/directory.h"
|
||||
@@ -159,7 +160,7 @@ initialize_option_handler(Control* c) {
|
||||
variables->insert("use_udp_trackers", new utils::VariableAny("yes"));
|
||||
variables->insert("port_random", new utils::VariableAny("yes"));
|
||||
variables->insert("session", new utils::VariableSlotString<>(NULL, rak::mem_fn(&control->core()->download_store(), &core::DownloadStore::set_path)));
|
||||
variables->insert("session_lock", new utils::VariableAny("yes"));
|
||||
variables->insert("session_lock", new utils::VariableAny("no"));
|
||||
variables->insert("session_on_completion", new utils::VariableAny("yes"));
|
||||
|
||||
variables->insert("connection_leech", new utils::VariableAny("leech"));
|
||||
|
||||
@@ -124,7 +124,7 @@ DownloadList::activate() {
|
||||
|
||||
m_control->input()->push_front(m_bindings);
|
||||
|
||||
m_control->core()->download_list().slot_map_erase().insert("0_download_list", sigc::mem_fun(this, &DownloadList::receive_download_erased));
|
||||
m_control->core()->download_list().slot_map_erase()["0_download_list"] = sigc::mem_fun(this, &DownloadList::receive_download_erased);
|
||||
|
||||
activate_display(DISPLAY_DOWNLOAD_LIST);
|
||||
}
|
||||
|
||||
+38
-4
@@ -36,9 +36,12 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "lockfile.h"
|
||||
|
||||
@@ -47,29 +50,60 @@ namespace utils {
|
||||
bool
|
||||
Lockfile::try_lock() {
|
||||
if (m_path.empty()) {
|
||||
m_id = "foo";
|
||||
m_locked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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);
|
||||
int fd = ::open(m_path.c_str(), O_RDWR | O_CREAT | O_EXCL, 0444);
|
||||
|
||||
if (fd == -1)
|
||||
return false;
|
||||
|
||||
m_id = "foo";
|
||||
char buf[256];
|
||||
int pos = ::gethostname(buf, 255);
|
||||
|
||||
if (pos == 0) {
|
||||
::snprintf(buf + std::strlen(buf), 255, ":+%i\n", ::getpid());
|
||||
::write(fd, buf, std::strlen(buf));
|
||||
}
|
||||
|
||||
::close(fd);
|
||||
|
||||
m_locked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Lockfile::unlock() {
|
||||
m_locked = false;
|
||||
|
||||
if (m_path.empty())
|
||||
return true;
|
||||
else
|
||||
return ::unlink(m_path.c_str()) != -1;
|
||||
}
|
||||
|
||||
struct lockfile_valid_char {
|
||||
bool operator () (char c) {
|
||||
return !std::isgraph(c);
|
||||
}
|
||||
};
|
||||
|
||||
std::string
|
||||
Lockfile::locked_by() const {
|
||||
int fd = ::open(m_path.c_str(), O_RDONLY);
|
||||
|
||||
if (fd < 0)
|
||||
return "<error>";
|
||||
|
||||
char buf[256];
|
||||
int pos = read(fd, buf, 255);
|
||||
|
||||
::close(fd);
|
||||
|
||||
return std::string(buf, std::find_if(buf, buf + std::max(pos, 0), lockfile_valid_char()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-2
@@ -34,6 +34,12 @@
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
// A simple, and not guaranteed atomic, lockfile implementation. It
|
||||
// saves the hostname and pid in the lock file, which may be accessed
|
||||
// by Lockfile::locked_by(). If the path is an empty string then no
|
||||
// lockfile will be created when Lockfile::try_lock() is called, still
|
||||
// it will set the locked state of the Lockfile instance.
|
||||
|
||||
#ifndef RTORRENT_UTILS_LOCKFILE_H
|
||||
#define RTORRENT_UTILS_LOCKFILE_H
|
||||
|
||||
@@ -43,8 +49,9 @@ namespace utils {
|
||||
|
||||
class Lockfile {
|
||||
public:
|
||||
Lockfile() : m_locked(false) {}
|
||||
|
||||
bool is_locked() const { return !m_id.empty(); }
|
||||
bool is_locked() const { return m_locked; }
|
||||
|
||||
// If the path is empty no lock file will be created, although
|
||||
// is_locked() will return true.
|
||||
@@ -54,9 +61,11 @@ public:
|
||||
const std::string& path() const { return m_path; }
|
||||
void set_path(const std::string& path) { m_path = path; }
|
||||
|
||||
std::string locked_by() const;
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
std::string m_id;
|
||||
bool m_locked;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user