Commit ab27b354 authored by Dominik Charousset's avatar Dominik Charousset

used fd_util functions for file handle manipulations

parent 6118ec7a
......@@ -34,6 +34,7 @@
#include <iostream>
#include "cppa/exception.hpp"
#include "cppa/util/io_stream.hpp"
#include "cppa/detail/fd_util.hpp"
#include "cppa/detail/ipv4_acceptor.hpp"
#include "cppa/detail/ipv4_io_stream.hpp"
......@@ -50,6 +51,8 @@
namespace cppa { namespace detail {
using namespace fd_util;
namespace {
struct socket_guard {
......@@ -71,14 +74,6 @@ struct socket_guard {
};
int rd_flags(native_socket_type fd) {
auto flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
throw network_error("unable to read socket flags");
}
return flags;
}
bool accept_impl(util::io_stream_ptr_pair& result, native_socket_type fd, bool nonblocking) {
sockaddr addr;
socklen_t addrlen;
......@@ -90,13 +85,8 @@ bool accept_impl(util::io_stream_ptr_pair& result, native_socket_type fd, bool n
// ok, try again
return false;
}
char* cstr = strerror(errno);
std::string errmsg = cstr;
free(cstr);
throw std::ios_base::failure(std::move(errmsg));
throw_io_failure("accept failed");
}
int flags = 1;
setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(int));
util::io_stream_ptr ptr(ipv4_io_stream::from_native_socket(sfd));
result.first = ptr;
result.second = ptr;
......@@ -115,7 +105,7 @@ std::unique_ptr<util::acceptor> ipv4_acceptor::create(std::uint16_t port) {
if (sockfd == invalid_socket) {
throw network_error("could not create server socket");
}
// sguard closes the socket in case of an exception
// sguard closes the socket in case of exception
socket_guard sguard(sockfd);
memset((char*) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
......@@ -127,14 +117,11 @@ std::unique_ptr<util::acceptor> ipv4_acceptor::create(std::uint16_t port) {
if (listen(sockfd, 10) != 0) {
throw network_error("listen() failed");
}
int flags = fcntl(sockfd, F_GETFL, 0);
if (flags == -1) {
throw network_error("unable to get socket flags");
}
bool nonblocking = (flags & O_NONBLOCK) != 0;
// default mode is nonblocking
nonblocking(sockfd, true);
// ok, no exceptions
sguard.release();
std::unique_ptr<ipv4_acceptor> result(new ipv4_acceptor(sockfd, nonblocking));
std::unique_ptr<ipv4_acceptor> result(new ipv4_acceptor(sockfd, true));
return std::move(result);
}
......@@ -148,10 +135,7 @@ native_socket_type ipv4_acceptor::acceptor_file_handle() const {
util::io_stream_ptr_pair ipv4_acceptor::accept_connection() {
if (m_is_nonblocking) {
auto flags = rd_flags(m_fd);
if (fcntl(m_fd, F_SETFL, flags & (~(O_NONBLOCK))) < 0) {
throw network_error("unable to set socket to nonblock");
}
nonblocking(m_fd, false);
m_is_nonblocking = false;
}
util::io_stream_ptr_pair result;
......@@ -161,10 +145,7 @@ util::io_stream_ptr_pair ipv4_acceptor::accept_connection() {
option<util::io_stream_ptr_pair> ipv4_acceptor::try_accept_connection() {
if (!m_is_nonblocking) {
auto flags = rd_flags(m_fd);
if (fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) < 0) {
throw network_error("unable to set socket to nonblock");
}
nonblocking(m_fd, true);
m_is_nonblocking = true;
}
util::io_stream_ptr_pair result;
......
......@@ -34,6 +34,7 @@
#include <iostream>
#include "cppa/exception.hpp"
#include "cppa/detail/fd_util.hpp"
#include "cppa/detail/ipv4_io_stream.hpp"
#ifdef CPPA_WINDOWS
......@@ -49,41 +50,7 @@
namespace cppa { namespace detail {
namespace {
template<typename T>
void handle_syscall_result(T result, bool is_recv_result) {
if (result < 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
char* cstr = strerror(errno);
std::string errmsg = cstr;
errmsg += " [errno = ";
errmsg += std::to_string(errno);
errmsg += "]";
throw std::ios_base::failure(std::move(errmsg));
}
}
else if (result == 0 && is_recv_result) {
throw std::ios_base::failure("cannot read from closed socket");
}
}
int rd_flags(native_socket_type fd) {
auto flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
throw network_error("unable to read socket flags");
}
return flags;
}
void set_nonblocking(native_socket_type fd) {
auto flags = rd_flags(fd);
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
throw network_error("unable to set socket to nonblock");
}
}
} // namespace <anonymous>
using namespace fd_util;
ipv4_io_stream::ipv4_io_stream(native_socket_type fd) : m_fd(fd) { }
......@@ -100,7 +67,7 @@ void ipv4_io_stream::read(void* vbuf, size_t len) {
size_t rd = 0;
while (rd < len) {
auto recv_result = ::recv(m_fd, buf + rd, len - rd, 0);
handle_syscall_result(recv_result, true);
handle_read_result(recv_result, true);
if (recv_result > 0) {
rd += static_cast<size_t>(recv_result);
}
......@@ -117,7 +84,7 @@ void ipv4_io_stream::read(void* vbuf, size_t len) {
size_t ipv4_io_stream::read_some(void* buf, size_t len) {
auto recv_result = ::recv(m_fd, buf, len, 0);
handle_syscall_result(recv_result, true);
handle_read_result(recv_result, true);
return (recv_result > 0) ? static_cast<size_t>(recv_result) : 0;
}
......@@ -126,7 +93,7 @@ void ipv4_io_stream::write(const void* vbuf, size_t len) {
size_t written = 0;
while (written < len) {
auto send_result = ::send(m_fd, buf + written, len - written, 0);
handle_syscall_result(send_result, false);
handle_write_result(send_result, true);
if (send_result > 0) {
written += static_cast<size_t>(send_result);
}
......@@ -144,22 +111,22 @@ void ipv4_io_stream::write(const void* vbuf, size_t len) {
size_t ipv4_io_stream::write_some(const void* buf, size_t len) {
auto send_result = ::send(m_fd, buf, len, 0);
handle_syscall_result(send_result, false);
handle_write_result(send_result, true);
return static_cast<size_t>(send_result);
}
util::io_stream_ptr ipv4_io_stream::from_native_socket(native_socket_type fd) {
set_nonblocking(fd);
tcp_nodelay(fd, true);
nonblocking(fd, true);
return new ipv4_io_stream(fd);
}
util::io_stream_ptr ipv4_io_stream::connect_to(const char* host,
std::uint16_t port) {
native_socket_type sockfd;
struct sockaddr_in serv_addr;
struct hostent* server;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == invalid_socket) {
native_socket_type fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == invalid_socket) {
throw network_error("socket creation failed");
}
server = gethostbyname(host);
......@@ -172,13 +139,12 @@ util::io_stream_ptr ipv4_io_stream::connect_to(const char* host,
serv_addr.sin_family = AF_INET;
memmove(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
serv_addr.sin_port = htons(port);
if (connect(sockfd, (const sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) {
if (connect(fd, (const sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) {
throw network_error("could not connect to host");
}
int flags = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(int));
set_nonblocking(sockfd);
return new ipv4_io_stream(sockfd);
tcp_nodelay(fd, true);
nonblocking(fd, true);
return new ipv4_io_stream(fd);
}
} } // namespace cppa::detail
......@@ -315,7 +315,7 @@ class middleman {
}
inline void add_channel_ptr(network_channel_ptr ptr) {
m_new_channels.push_back(std::move(ptr));
m_new_channels.push_back(move(ptr));
}
inline void add_peer(const process_information& pinf, peer_connection_ptr cptr) {
......@@ -687,7 +687,7 @@ void middleman::operator()(int pipe_fd, middleman_queue& queue) {
if (FD_ISSET(channel->read_handle(), &rdset)) {
bool erase_channel = false;
try { erase_channel = !channel->continue_reading(); }
catch (std::exception& e) {
catch (exception& e) {
DEBUG(demangle(typeid(e).name()) << ": " << e.what());
erase_channel = true;
}
......@@ -704,7 +704,7 @@ void middleman::operator()(int pipe_fd, middleman_queue& queue) {
if (FD_ISSET(peer->write_handle(), &wrset)) {
bool erase_channel = false;
try { erase_channel = !peer->continue_writing(); }
catch (std::exception& e) {
catch (exception& e) {
DEBUG(demangle(typeid(e).name()) << ": " << e.what());
erase_channel = true;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment