mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-12 13:12:32 +00:00
Remove obsolete SocketFd class.
This commit is contained in:
+51
-43
@@ -1,6 +1,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <unistd.h>
|
||||
#include <sys/un.h>
|
||||
#include <torrent/connection_manager.h>
|
||||
#include <torrent/torrent.h>
|
||||
@@ -12,7 +13,6 @@
|
||||
#include "control.h"
|
||||
#include "globals.h"
|
||||
#include "rpc/scgi_task.h"
|
||||
#include "utils/socket_fd.h"
|
||||
|
||||
// TODO: Figure out why moving this to the top causes a build error.
|
||||
#include "rpc/scgi.h"
|
||||
@@ -20,30 +20,26 @@
|
||||
namespace rpc {
|
||||
|
||||
SCgi::~SCgi() {
|
||||
if (!get_fd().is_valid())
|
||||
return;
|
||||
|
||||
for (SCgiTask* itr = m_task, *last = m_task + max_tasks; itr != last; ++itr)
|
||||
if (itr->is_open())
|
||||
itr->close();
|
||||
|
||||
deactivate();
|
||||
torrent::connection_manager()->dec_socket_count();
|
||||
|
||||
get_fd().close();
|
||||
get_fd().clear();
|
||||
|
||||
if (!m_path.empty())
|
||||
::unlink(m_path.c_str());
|
||||
assert(!is_open() && "SCgi::~SCgi() called while open");
|
||||
}
|
||||
|
||||
void
|
||||
SCgi::open_port(void* sa, unsigned int length, bool dontRoute) {
|
||||
if (!get_fd().open_stream() ||
|
||||
(dontRoute && !get_fd().set_dont_route(true)))
|
||||
SCgi::open_port(sockaddr* sa, unsigned int length, bool dont_route) {
|
||||
int fd = torrent::fd_open_family(torrent::fd_flag_stream | torrent::fd_flag_nonblock | torrent::fd_flag_reuse_address,
|
||||
reinterpret_cast<sockaddr*>(sa)->sa_family);
|
||||
|
||||
if (fd == -1)
|
||||
throw torrent::resource_error("Could not open socket for listening: " + std::string(std::strerror(errno)));
|
||||
|
||||
open(sa, length);
|
||||
if (dont_route && !torrent::fd_set_dont_route(fd, true)) {
|
||||
torrent::fd_close(fd);
|
||||
throw torrent::resource_error("Could not set socket option IP_DONTROUTE: " + std::string(std::strerror(errno)));
|
||||
}
|
||||
|
||||
set_file_descriptor(fd);
|
||||
open(reinterpret_cast<sockaddr*>(sa), length);
|
||||
|
||||
torrent::connection_manager()->inc_socket_count();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -51,45 +47,42 @@ SCgi::open_named(const std::string& filename) {
|
||||
if (filename.empty() || filename.size() > 4096)
|
||||
throw torrent::resource_error("Invalid filename length.");
|
||||
|
||||
auto buffer = std::make_unique<char[]>(sizeof(sockaddr_un) + filename.size());
|
||||
auto buffer = std::make_unique<char[]>(sizeof(sockaddr_un) + filename.size() + 1);
|
||||
|
||||
sockaddr_un* sa = reinterpret_cast<sockaddr_un*>(buffer.get());
|
||||
|
||||
#ifdef __sun__
|
||||
sa->sun_family = AF_UNIX;
|
||||
#else
|
||||
sa->sun_family = AF_LOCAL;
|
||||
#endif
|
||||
|
||||
std::memcpy(sa->sun_path, filename.c_str(), filename.size() + 1);
|
||||
|
||||
if (!get_fd().open_local())
|
||||
throw torrent::resource_error("Could not open socket for listening.");
|
||||
int fd = torrent::fd_open_local(torrent::fd_flag_stream | torrent::fd_flag_nonblock | torrent::fd_flag_reuse_address);
|
||||
|
||||
if (fd == -1)
|
||||
throw torrent::resource_error("Could not open socket for listening: " + std::string(std::strerror(errno)));
|
||||
|
||||
set_file_descriptor(fd);
|
||||
open(reinterpret_cast<sockaddr*>(sa), offsetof(struct sockaddr_un, sun_path) + filename.size() + 1);
|
||||
|
||||
torrent::connection_manager()->inc_socket_count();
|
||||
|
||||
open(sa, offsetof(struct sockaddr_un, sun_path) + filename.size() + 1);
|
||||
m_path = filename;
|
||||
}
|
||||
|
||||
void
|
||||
SCgi::open(void* sa, unsigned int length) {
|
||||
SCgi::open(sockaddr* sa, unsigned int length) {
|
||||
try {
|
||||
if (!get_fd().set_nonblock() ||
|
||||
!get_fd().set_reuse_address(true) ||
|
||||
!get_fd().bind_sa(reinterpret_cast<sockaddr*>(sa), length) ||
|
||||
!get_fd().listen(max_tasks))
|
||||
if (::bind(file_descriptor(), sa, length) == -1)
|
||||
throw torrent::resource_error("Could not bind socket for listening: " + std::string(std::strerror(errno)));
|
||||
|
||||
if (!torrent::fd_listen(file_descriptor(), max_tasks))
|
||||
throw torrent::resource_error("Could not prepare socket for listening: " + std::string(std::strerror(errno)));
|
||||
|
||||
torrent::connection_manager()->inc_socket_count();
|
||||
|
||||
} catch (torrent::resource_error& e) {
|
||||
get_fd().close();
|
||||
get_fd().clear();
|
||||
torrent::fd_close(file_descriptor());
|
||||
set_file_descriptor(-1);
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Verify this is run in correct thread, also only ever call poll methods from thread_self.
|
||||
|
||||
void
|
||||
SCgi::activate() {
|
||||
assert(torrent::this_thread::thread() == scgi_thread::thread());
|
||||
@@ -100,16 +93,31 @@ SCgi::activate() {
|
||||
}
|
||||
|
||||
void
|
||||
SCgi::deactivate() {
|
||||
SCgi::stop() {
|
||||
assert(torrent::this_thread::thread() == scgi_thread::thread());
|
||||
|
||||
if (!is_open())
|
||||
return;
|
||||
|
||||
for (SCgiTask* itr = m_task, *last = m_task + max_tasks; itr != last; ++itr)
|
||||
if (itr->is_open())
|
||||
itr->close();
|
||||
|
||||
torrent::this_thread::poll()->remove_and_close(this);
|
||||
|
||||
torrent::fd_close(file_descriptor());
|
||||
set_file_descriptor(-1);
|
||||
|
||||
torrent::connection_manager()->dec_socket_count();
|
||||
|
||||
if (!m_path.empty())
|
||||
::unlink(m_path.c_str());
|
||||
}
|
||||
|
||||
void
|
||||
SCgi::event_read() {
|
||||
while (true) {
|
||||
int fd = torrent::fd_accept(get_fd().get_fd());
|
||||
int fd = torrent::fd_accept(file_descriptor());
|
||||
|
||||
if (fd == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
|
||||
+4
-10
@@ -5,11 +5,6 @@
|
||||
#include <torrent/event.h>
|
||||
|
||||
#include "rpc/scgi_task.h"
|
||||
#include "utils/socket_fd.h"
|
||||
|
||||
namespace utils {
|
||||
class SocketFd;
|
||||
}
|
||||
|
||||
namespace rpc {
|
||||
|
||||
@@ -21,11 +16,12 @@ public:
|
||||
|
||||
const char* type_name() const override { return "scgi"; }
|
||||
|
||||
void open_port(void* sa, unsigned int length, bool dontRoute);
|
||||
void open_port(sockaddr* sa, unsigned int length, bool dont_route);
|
||||
void open_named(const std::string& filename);
|
||||
|
||||
void activate();
|
||||
void deactivate();
|
||||
|
||||
void stop();
|
||||
|
||||
const std::string& path() const { return m_path; }
|
||||
|
||||
@@ -36,10 +32,8 @@ public:
|
||||
void event_write() override;
|
||||
void event_error() override;
|
||||
|
||||
utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); }
|
||||
|
||||
private:
|
||||
void open(void* sa, unsigned int length);
|
||||
void open(sockaddr* sa, unsigned int length);
|
||||
|
||||
std::string m_path;
|
||||
int m_logFd{-1};
|
||||
|
||||
+33
-37
@@ -3,11 +3,13 @@
|
||||
#include "rpc/scgi_task.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/net/fd.h>
|
||||
#include <torrent/net/poll.h>
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/thread.h>
|
||||
@@ -16,7 +18,6 @@
|
||||
#include "globals.h"
|
||||
#include "scgi.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
#include "utils/socket_fd.h"
|
||||
|
||||
namespace rpc {
|
||||
|
||||
@@ -24,10 +25,12 @@ void
|
||||
SCgiTask::open(SCgi* parent, int fd) {
|
||||
m_parent = parent;
|
||||
m_fileDesc = fd;
|
||||
m_buffer = new char[default_buffer_size + 1];
|
||||
|
||||
m_buffer.reset(new char[default_buffer_size + 1]);
|
||||
|
||||
m_buffer_size = default_buffer_size;
|
||||
m_position = m_buffer;
|
||||
m_body = NULL;
|
||||
m_position = m_buffer.get();
|
||||
m_body = nullptr;
|
||||
|
||||
torrent::this_thread::poll()->open(this);
|
||||
torrent::this_thread::poll()->insert_read(this);
|
||||
@@ -36,7 +39,7 @@ SCgiTask::open(SCgi* parent, int fd) {
|
||||
|
||||
void
|
||||
SCgiTask::close() {
|
||||
if (!get_fd().is_valid())
|
||||
if (!is_open())
|
||||
return;
|
||||
|
||||
torrent::main_thread::thread()->cancel_callback_and_wait(this);
|
||||
@@ -44,18 +47,17 @@ SCgiTask::close() {
|
||||
|
||||
torrent::this_thread::poll()->remove_and_close(this);
|
||||
|
||||
get_fd().close();
|
||||
get_fd().clear();
|
||||
torrent::fd_close(file_descriptor());
|
||||
set_file_descriptor(-1);
|
||||
|
||||
auto lock = std::lock_guard<std::mutex>(m_result_mutex);
|
||||
|
||||
delete[] m_buffer;
|
||||
m_buffer = NULL;
|
||||
m_buffer = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
SCgiTask::event_read() {
|
||||
int bytes = ::recv(m_fileDesc, m_position, m_buffer_size - (m_position - m_buffer), 0);
|
||||
int bytes = ::recv(m_fileDesc, m_position, m_buffer_size - (m_position - m_buffer.get()), 0);
|
||||
|
||||
if (bytes <= 0) {
|
||||
if (bytes == 0 || !(errno == EAGAIN || errno == EINTR))
|
||||
@@ -73,14 +75,14 @@ SCgiTask::event_read() {
|
||||
// receive all the data we need the first time.
|
||||
char* current;
|
||||
|
||||
int header_size = strtol(m_buffer, ¤t, 0);
|
||||
int header_size = strtol(m_buffer.get(), ¤t, 0);
|
||||
|
||||
if (current == m_position)
|
||||
return;
|
||||
|
||||
// If the request doesn't start with an integer or if it didn't
|
||||
// end in ':', then close the connection.
|
||||
if (current == m_buffer || *current != ':' || header_size < 17 || header_size > max_header_size)
|
||||
if (current == m_buffer.get() || *current != ':' || header_size < 17 || header_size > max_header_size)
|
||||
goto event_read_failed;
|
||||
|
||||
if (std::distance(++current, m_position) < header_size + 1)
|
||||
@@ -135,7 +137,7 @@ SCgiTask::event_read() {
|
||||
goto event_read_failed;
|
||||
|
||||
m_body = current + 1;
|
||||
header_size = std::distance(m_buffer, m_body);
|
||||
header_size = std::distance(m_buffer.get(), m_body);
|
||||
|
||||
if (!detect_content_type(content_type))
|
||||
goto event_read_failed;
|
||||
@@ -146,19 +148,19 @@ SCgiTask::event_read() {
|
||||
} else if ((unsigned int)content_length <= default_buffer_size) {
|
||||
m_buffer_size = content_length;
|
||||
|
||||
std::memmove(m_buffer, m_body, std::distance(m_body, m_position));
|
||||
m_position = m_buffer + std::distance(m_body, m_position);
|
||||
m_body = m_buffer;
|
||||
std::memmove(m_buffer.get(), m_body, std::distance(m_body, m_position));
|
||||
m_position = m_buffer.get() + std::distance(m_body, m_position);
|
||||
m_body = m_buffer.get();
|
||||
|
||||
} else {
|
||||
realloc_buffer((m_buffer_size = content_length) + 1, m_body, std::distance(m_body, m_position));
|
||||
|
||||
m_position = m_buffer + std::distance(m_body, m_position);
|
||||
m_body = m_buffer;
|
||||
m_position = m_buffer.get() + std::distance(m_body, m_position);
|
||||
m_body = m_buffer.get();
|
||||
}
|
||||
}
|
||||
|
||||
if ((unsigned int)std::distance(m_buffer, m_position) != m_buffer_size)
|
||||
if ((unsigned int)std::distance(m_buffer.get(), m_position) != m_buffer_size)
|
||||
return;
|
||||
|
||||
torrent::this_thread::poll()->remove_read(this);
|
||||
@@ -168,13 +170,13 @@ SCgiTask::event_read() {
|
||||
|
||||
// Clean up logging, this is just plain ugly...
|
||||
// write(m_logFd, "\n---\n", sizeof("\n---\n"));
|
||||
result = write(m_parent->log_fd(), m_buffer, m_buffer_size);
|
||||
result = write(m_parent->log_fd(), "\n---\n", sizeof("\n---\n"));
|
||||
result = ::write(m_parent->log_fd(), m_buffer.get(), m_buffer_size);
|
||||
result = ::write(m_parent->log_fd(), "\n---\n", sizeof("\n---\n"));
|
||||
}
|
||||
|
||||
lt_log_print_dump(torrent::LOG_RPC_DUMP, m_body, m_buffer_size - std::distance(m_buffer, m_body), "scgi", "RPC read.", 0);
|
||||
lt_log_print_dump(torrent::LOG_RPC_DUMP, m_body, m_buffer_size - std::distance(m_buffer.get(), m_body), "scgi", "RPC read.", 0);
|
||||
|
||||
receive_call(m_body, m_buffer_size - std::distance(m_buffer, m_body));
|
||||
receive_call(m_body, m_buffer_size - std::distance(m_buffer.get(), m_body));
|
||||
return;
|
||||
|
||||
event_read_failed:
|
||||
@@ -184,13 +186,7 @@ event_read_failed:
|
||||
|
||||
void
|
||||
SCgiTask::event_write() {
|
||||
// Apple and Solaris do not support MSG_NOSIGNAL,
|
||||
// so disable this fix until we find a better solution
|
||||
#if defined(__APPLE__) || defined(__sun__)
|
||||
int bytes = ::send(m_fileDesc, m_position, m_buffer_size, 0);
|
||||
#else
|
||||
int bytes = ::send(m_fileDesc, m_position, m_buffer_size, MSG_NOSIGNAL);
|
||||
#endif
|
||||
|
||||
if (bytes == -1) {
|
||||
if (!(errno == EAGAIN || errno == EINTR))
|
||||
@@ -248,11 +244,11 @@ SCgiTask::detect_content_type(const std::string& content_type) {
|
||||
// If bufferSize is zero then memcpy won't do anything.
|
||||
void
|
||||
SCgiTask::realloc_buffer(uint32_t size, const char* buffer, uint32_t bufferSize) {
|
||||
char* tmp = new char[size];
|
||||
auto tmp = new char[size];
|
||||
|
||||
std::memcpy(tmp, buffer, bufferSize);
|
||||
::free(m_buffer);
|
||||
m_buffer = tmp;
|
||||
|
||||
m_buffer.reset(tmp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -317,20 +313,20 @@ SCgiTask::receive_write(const char* buffer, uint32_t length) {
|
||||
: "Status: 200 OK\r\nContent-Type: text/xml\r\nContent-Length: %i\r\n\r\n";
|
||||
|
||||
// Who ever bothers to check the return value?
|
||||
int headerSize = snprintf(m_buffer, m_buffer_size, header, length);
|
||||
int headerSize = snprintf(m_buffer.get(), m_buffer_size, header, length);
|
||||
|
||||
m_position = m_buffer;
|
||||
m_position = m_buffer.get();
|
||||
m_buffer_size = length + headerSize;
|
||||
|
||||
std::memcpy(m_buffer + headerSize, buffer, length);
|
||||
std::memcpy(m_buffer.get() + headerSize, buffer, length);
|
||||
|
||||
if (m_parent->log_fd() >= 0) {
|
||||
[[maybe_unused]] int result;
|
||||
result = write(m_parent->log_fd(), m_buffer, m_buffer_size);
|
||||
result = write(m_parent->log_fd(), m_buffer.get(), m_buffer_size);
|
||||
result = write(m_parent->log_fd(), "\n---\n", sizeof("\n---\n"));
|
||||
}
|
||||
|
||||
lt_log_print_dump(torrent::LOG_RPC_DUMP, m_buffer, m_buffer_size, "scgi", "RPC write.", 0);
|
||||
lt_log_print_dump(torrent::LOG_RPC_DUMP, m_buffer.get(), m_buffer_size, "scgi", "RPC write.", 0);
|
||||
}
|
||||
|
||||
} // namespace rpc
|
||||
|
||||
+4
-10
@@ -5,10 +5,6 @@
|
||||
#include <mutex>
|
||||
#include <torrent/event.h>
|
||||
|
||||
namespace utils {
|
||||
class SocketFd;
|
||||
}
|
||||
|
||||
namespace rpc {
|
||||
|
||||
class SCgi;
|
||||
@@ -37,8 +33,6 @@ public:
|
||||
void event_write() override;
|
||||
void event_error() override;
|
||||
|
||||
utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); }
|
||||
|
||||
private:
|
||||
bool detect_content_type(const std::string& content_type);
|
||||
void realloc_buffer(uint32_t size, const char* buffer, uint32_t bufferSize);
|
||||
@@ -46,13 +40,13 @@ private:
|
||||
void receive_call(const char* buffer, uint32_t length);
|
||||
void receive_write(const char* buffer, uint32_t length);
|
||||
|
||||
SCgi* m_parent;
|
||||
SCgi* m_parent{};
|
||||
|
||||
std::mutex m_result_mutex;
|
||||
|
||||
char* m_buffer{nullptr};
|
||||
char* m_position{nullptr};
|
||||
char* m_body{nullptr};
|
||||
std::unique_ptr<char[]> m_buffer;
|
||||
char* m_position{};
|
||||
char* m_body{};
|
||||
|
||||
unsigned int m_buffer_size{0};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user