mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-10 20:22:31 +00:00
* Add support for any number of custom download values identified by string keys.
d.set_custom=key,value d.get_custom=key (returns "" if not set) d.get_custom_throw=key (returns error if not set) * With this patch, rtorrent will detect and complain about .torrent files with broken bencode representation (e.g. where the order of dictionary keys is not lexicographic). * Choose a different poll type using the RTORRENT_POLL env. variable (if it's implemented), probably only useful as RTORRENT_POLL=select. * Add the commands execute_capture and execute_capture_nothrow that work like their other counterparts but return the OUTPUT (stdout) of the given command. Note that the output is not modified in any way, in particular a trailing newline is NOT removed. To work around this, have the command write its output without it e.g. using echo -n. Also note that with execute_capture_nothrow there is no way to check if the command failed. Example usage: d.set_custom4=$execute_capture=handler.sh * When logging peer communication errors, show IP and peer ID to help debugging. All patches above by Josef Drexler. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1088 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+49
-7
@@ -36,6 +36,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <rak/error_number.h>
|
||||
@@ -51,7 +52,7 @@ namespace rpc {
|
||||
// Close m_logFd.
|
||||
|
||||
int
|
||||
ExecFile::execute(const char* file, char* const* argv) {
|
||||
ExecFile::execute(const char* file, char* const* argv, int flags) {
|
||||
// Write the execued command and its parameters to the log fd.
|
||||
if (m_logFd != -1) {
|
||||
for (char* const* itr = argv; *itr != NULL; itr++) {
|
||||
@@ -66,20 +67,38 @@ ExecFile::execute(const char* file, char* const* argv) {
|
||||
write(m_logFd, "\n---\n", sizeof("\n---\n"));
|
||||
}
|
||||
|
||||
int pipeFd[2];
|
||||
|
||||
if ((flags & flag_capture) && pipe(pipeFd))
|
||||
throw torrent::input_error("ExecFile::execute(...) Pipe creation failed.");
|
||||
|
||||
pid_t childPid = fork();
|
||||
|
||||
if (childPid == -1)
|
||||
throw torrent::input_error("ExecFile::execute(...) Fork failed.");
|
||||
|
||||
if (childPid == 0) {
|
||||
::close(0);
|
||||
::close(1);
|
||||
::close(2);
|
||||
int devNull = open("/dev/null", O_RDWR);
|
||||
if (devNull != -1)
|
||||
dup2(devNull, 0);
|
||||
else
|
||||
::close(0);
|
||||
|
||||
if (m_logFd != -1) {
|
||||
if (flags & flag_capture)
|
||||
dup2(pipeFd[1], 1);
|
||||
else if (m_logFd != -1)
|
||||
dup2(m_logFd, 1);
|
||||
else if (devNull != -1)
|
||||
dup2(devNull, 1);
|
||||
else
|
||||
::close(1);
|
||||
|
||||
if (m_logFd != -1)
|
||||
dup2(m_logFd, 2);
|
||||
}
|
||||
else if (devNull != -1)
|
||||
dup2(devNull, 2);
|
||||
else
|
||||
::close(2);
|
||||
|
||||
// Close all fd's.
|
||||
for (int i = 3, last = sysconf(_SC_OPEN_MAX); i != last; i++)
|
||||
@@ -90,6 +109,26 @@ ExecFile::execute(const char* file, char* const* argv) {
|
||||
_exit(result);
|
||||
|
||||
} else {
|
||||
if (flags & flag_capture) {
|
||||
m_capture = std::string();
|
||||
::close(pipeFd[1]);
|
||||
|
||||
char buffer[4096];
|
||||
ssize_t length;
|
||||
|
||||
do {
|
||||
length = read(pipeFd[0], buffer, sizeof(buffer));
|
||||
|
||||
if (length > 0)
|
||||
m_capture += std::string(buffer, length);
|
||||
} while (length > 0);
|
||||
|
||||
if (m_logFd != -1) {
|
||||
write(m_logFd, "Captured output:\n", sizeof("Captured output:\n"));
|
||||
write(m_logFd, m_capture.data(), m_capture.length());
|
||||
}
|
||||
}
|
||||
|
||||
int status;
|
||||
int wpid = waitpid(childPid, &status, 0);
|
||||
|
||||
@@ -143,11 +182,14 @@ ExecFile::execute_object(const torrent::Object& rawArgs, int flags) {
|
||||
|
||||
*argsCurrent = NULL;
|
||||
|
||||
int status = execute(argsBuffer[0], argsBuffer);
|
||||
int status = execute(argsBuffer[0], argsBuffer, flags);
|
||||
|
||||
if ((flags & flag_throw) && status != 0)
|
||||
throw torrent::input_error("Bad return code.");
|
||||
|
||||
if (flags & flag_capture)
|
||||
return m_capture;
|
||||
|
||||
return torrent::Object((int64_t)status);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user