31int connect_with_timeout(
const int socket,
const struct sockaddr* addr, socklen_t addrlen,
const unsigned int timeout_ms)
35 int socket_flags_before;
36 if ((socket_flags_before = fcntl(socket, F_GETFL, 0) < 0)) {
39 if (fcntl(socket, F_SETFL, socket_flags_before | O_NONBLOCK) < 0) {
43 if (connect(socket, addr, addrlen) < 0) {
44 if ((errno != EWOULDBLOCK) && (errno != EINPROGRESS)) {
49 if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) {
53 const timespec deadline = {.tv_sec = now.tv_sec,
54 .tv_nsec = now.tv_nsec + timeout_ms * 1000000l};
56 if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) {
61 const int ms_until_deadline =
static_cast<int>((deadline.tv_sec - now.tv_sec) * 1000l + (deadline.tv_nsec - now.tv_nsec) / 1000000l);
62 if (ms_until_deadline < 0) {
66 pollfd connectionPool[] = {{.fd = socket, .events = POLLOUT}};
67 connection = poll(connectionPool, 1, ms_until_deadline);
71 socklen_t
len =
sizeof(error);
72 if (getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &
len) == 0) {
79 }
while (connection == -1 && errno == EINTR);
80 if (connection == 0) {
88 if (fcntl(socket, F_SETFL, socket_flags_before) < 0) {
97 this->mOut =
new std::ofstream(mFileName, std::ios::out | std::ios::binary);
99 if (this->mToSocket) {
101 sockaddr_in serverAddress;
102 serverAddress.sin_family = AF_INET;
103 serverAddress.sin_port = htons(this->mPort);
106 static auto server = gethostbyname(this->mHostName.c_str());
107 if (server ==
nullptr) {
108 LOGF(info,
"Error no such host %s", this->mHostName.c_str());
112 bcopy((
char*)server->h_addr,
113 (
char*)&serverAddress.sin_addr.s_addr,
117 this->mClientSocket = socket(AF_INET, SOCK_STREAM, 0);
118 if (this->mClientSocket == -1) {
119 LOGF(info,
"Error creating socket");
124 sizeof(serverAddress), this->mTimeout) == -1) {
125 LOGF(info,
"Error connecting to %s:%d", this->mHostName.c_str(), this->mPort);
127 this->mClientSocket = -1;
131 char buf[256] =
"SEND:";
132 strncpy(
buf + 6, this->mFileName.c_str(),
sizeof(
buf) - 7);
133 strncpy(
buf +
sizeof(
buf) - 6,
"ALICE", 6);
134 auto real = send(this->mClientSocket,
buf,
sizeof(
buf), 0);
135 if (real !=
sizeof(
buf)) {
140 this->mClientSocket = -1;
141 LOGF(info,
"Error sending file name to %s:%d", this->mHostName.c_str(), this->mPort);
164 if (this->mToFile && this->mOut) {
167 if (this->mToSocket && this->mClientSocket != -1) {
168 LOGF(info,
"Location::write() socket %s ++++++++++++++++++++++",
fileName());
170 auto real = send(this->mClientSocket,
buf,
size, 0);
176 this->mClientSocket = -1;
177 LOGF(info,
"Error sending data to %s:%d", this->mHostName.c_str(), this->mPort);