Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: tools/android/forwarder2/socket.cc

Issue 11269036: Support HTTP test-server based net unit tests on Android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Clang build + sync Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/android/forwarder2/socket.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/android/forwarder2/socket.h" 5 #include "tools/android/forwarder2/socket.h"
6 6
7 #include <arpa/inet.h> 7 #include <arpa/inet.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <netinet/in.h> 10 #include <netinet/in.h>
11 #include <stdio.h> 11 #include <stdio.h>
12 #include <string.h> 12 #include <string.h>
13 #include <sys/socket.h> 13 #include <sys/socket.h>
14 #include <sys/types.h> 14 #include <sys/types.h>
15 15
16 #include "base/eintr_wrapper.h" 16 #include "base/eintr_wrapper.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/safe_strerror_posix.h" 18 #include "base/safe_strerror_posix.h"
19 #include "tools/android/common/net.h" 19 #include "tools/android/common/net.h"
20 20 #include "tools/android/forwarder2/common.h"
21 // This is used in Close and Shutdown.
22 // Preserving errno for Close() is important because the function is very often
23 // used in cleanup code, after an error occurred, and it is very easy to pass an
24 // invalid file descriptor to close() in this context, or more rarely, a
25 // spurious signal might make close() return -1 + setting errno to EINTR,
26 // masking the real reason for the original error. This leads to very unpleasant
27 // debugging sessions.
28 #define PRESERVE_ERRNO_HANDLE_EINTR(Func) \
29 do { \
30 int local_errno = errno; \
31 (void) HANDLE_EINTR(Func); \
32 errno = local_errno; \
33 } while (false);
34
35 21
36 namespace { 22 namespace {
37 const int kNoTimeout = -1; 23 const int kNoTimeout = -1;
38 const int kConnectTimeOut = 10; // Seconds. 24 const int kConnectTimeOut = 10; // Seconds.
39 25
40 bool FamilyIsTCP(int family) { 26 bool FamilyIsTCP(int family) {
41 return family == AF_INET || family == AF_INET6; 27 return family == AF_INET || family == AF_INET6;
42 } 28 }
43 } // namespace 29 } // namespace
44 30
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 } 67 }
82 68
83 Socket::Socket() 69 Socket::Socket()
84 : socket_(-1), 70 : socket_(-1),
85 port_(0), 71 port_(0),
86 socket_error_(false), 72 socket_error_(false),
87 family_(AF_INET), 73 family_(AF_INET),
88 abstract_(false), 74 abstract_(false),
89 addr_ptr_(reinterpret_cast<sockaddr*>(&addr_.addr4)), 75 addr_ptr_(reinterpret_cast<sockaddr*>(&addr_.addr4)),
90 addr_len_(sizeof(sockaddr)), 76 addr_len_(sizeof(sockaddr)),
91 exit_notifier_fd_(-1) { 77 exit_notifier_fd_(-1),
78 exited_(false) {
92 memset(&addr_, 0, sizeof(addr_)); 79 memset(&addr_, 0, sizeof(addr_));
93 } 80 }
94 81
95 Socket::~Socket() { 82 Socket::~Socket() {
96 CHECK(IsClosed()); 83 Close();
97 } 84 }
98 85
99 void Socket::Shutdown() { 86 void Socket::Shutdown() {
100 if (!IsClosed()) { 87 if (!IsClosed()) {
101 PRESERVE_ERRNO_HANDLE_EINTR(shutdown(socket_, SHUT_RDWR)); 88 PRESERVE_ERRNO_HANDLE_EINTR(shutdown(socket_, SHUT_RDWR));
102 } 89 }
103 } 90 }
104 91
105 void Socket::Close() { 92 void Socket::Close() {
106 if (!IsClosed()) { 93 if (!IsClosed()) {
107 PRESERVE_ERRNO_HANDLE_EINTR(close(socket_)); 94 CloseFD(socket_);
108 socket_ = -1; 95 socket_ = -1;
109 } 96 }
110 } 97 }
111 98
112 bool Socket::InitSocketInternal() { 99 bool Socket::InitSocketInternal() {
113 socket_ = socket(family_, SOCK_STREAM, 0); 100 socket_ = socket(family_, SOCK_STREAM, 0);
114 if (socket_ < 0) 101 if (socket_ < 0)
115 return false; 102 return false;
116 tools::DisableNagle(socket_); 103 tools::DisableNagle(socket_);
117 int reuse_addr = 1; 104 int reuse_addr = 1;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 SetSocketError(); 222 SetSocketError();
236 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); 223 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
237 return false; 224 return false;
238 } 225 }
239 // Wait for connection to complete, or receive a notification. 226 // Wait for connection to complete, or receive a notification.
240 if (!WaitForEvent(WRITE, kConnectTimeOut)) { 227 if (!WaitForEvent(WRITE, kConnectTimeOut)) {
241 SetSocketError(); 228 SetSocketError();
242 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); 229 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
243 return false; 230 return false;
244 } 231 }
245 // Disable non-block since our code assumes blocking semantics. 232 int socket_errno;
233 socklen_t opt_len = sizeof(socket_errno);
234 if (!getsockopt(socket_, SOL_SOCKET, SO_ERROR, &socket_errno, &opt_len) < 0) {
Nico 2013/07/02 01:07:22 The "!" here is wrong, right?
Philippe 2013/07/02 09:35:38 Yeah, good catch!
235 LOG(ERROR) << "getsockopt(): " << safe_strerror(errno);
236 SetSocketError();
237 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
238 return false;
239 }
240 if (socket_errno != 0) {
241 LOG(ERROR) << "Could not connect to host: " << safe_strerror(socket_errno);
242 SetSocketError();
243 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
244 return false;
245 }
246 fcntl(socket_, F_SETFL, kFlags); 246 fcntl(socket_, F_SETFL, kFlags);
247 return true; 247 return true;
248 } 248 }
249 249
250 bool Socket::Resolve(const std::string& host) { 250 bool Socket::Resolve(const std::string& host) {
251 struct addrinfo hints; 251 struct addrinfo hints;
252 struct addrinfo* res; 252 struct addrinfo* res;
253 memset(&hints, 0, sizeof(hints)); 253 memset(&hints, 0, sizeof(hints));
254 hints.ai_family = AF_UNSPEC; 254 hints.ai_family = AF_UNSPEC;
255 hints.ai_socktype = SOCK_STREAM; 255 hints.ai_socktype = SOCK_STREAM;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 return FD_ISSET(socket_, &fds); 290 return FD_ISSET(socket_, &fds);
291 } 291 }
292 292
293 bool Socket::AddFdToSet(fd_set* fds) const { 293 bool Socket::AddFdToSet(fd_set* fds) const {
294 if (IsClosed()) 294 if (IsClosed())
295 return false; 295 return false;
296 FD_SET(socket_, fds); 296 FD_SET(socket_, fds);
297 return true; 297 return true;
298 } 298 }
299 299
300 int Socket::ReadNumBytes(char* buffer, size_t num_bytes) { 300 int Socket::ReadNumBytes(void* buffer, size_t num_bytes) {
301 int bytes_read = 0; 301 int bytes_read = 0;
302 int ret = 1; 302 int ret = 1;
303 while (bytes_read < num_bytes && ret > 0) { 303 while (bytes_read < num_bytes && ret > 0) {
304 ret = Read(buffer + bytes_read, num_bytes - bytes_read); 304 ret = Read(static_cast<char*>(buffer) + bytes_read, num_bytes - bytes_read);
305 if (ret >= 0) 305 if (ret >= 0)
306 bytes_read += ret; 306 bytes_read += ret;
307 } 307 }
308 return bytes_read; 308 return bytes_read;
309 } 309 }
310 310
311 void Socket::SetSocketError() { 311 void Socket::SetSocketError() {
312 socket_error_ = true; 312 socket_error_ = true;
313 // We never use non-blocking socket. 313 // We never use non-blocking socket.
314 DCHECK(errno != EAGAIN && errno != EWOULDBLOCK); 314 DCHECK(errno != EAGAIN && errno != EWOULDBLOCK);
315 Close(); 315 Close();
316 } 316 }
317 317
318 int Socket::Read(char* buffer, size_t buffer_size) { 318 int Socket::Read(void* buffer, size_t buffer_size) {
319 if (!WaitForEvent(READ, kNoTimeout)) { 319 if (!WaitForEvent(READ, kNoTimeout)) {
320 SetSocketError(); 320 SetSocketError();
321 return 0; 321 return 0;
322 } 322 }
323 int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size)); 323 int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size));
324 if (ret < 0) 324 if (ret < 0)
325 SetSocketError(); 325 SetSocketError();
326 return ret; 326 return ret;
327 } 327 }
328 328
329 int Socket::Write(const char* buffer, size_t count) { 329 int Socket::Write(const void* buffer, size_t count) {
330 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL)); 330 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL));
331 if (ret < 0) 331 if (ret < 0)
332 SetSocketError(); 332 SetSocketError();
333 return ret; 333 return ret;
334 } 334 }
335 335
336 int Socket::WriteString(const std::string& buffer) { 336 int Socket::WriteString(const std::string& buffer) {
337 return WriteNumBytes(buffer.c_str(), buffer.size()); 337 return WriteNumBytes(buffer.c_str(), buffer.size());
338 } 338 }
339 339
340 int Socket::WriteNumBytes(const char* buffer, size_t num_bytes) { 340 int Socket::WriteNumBytes(const void* buffer, size_t num_bytes) {
341 int bytes_written = 0; 341 int bytes_written = 0;
342 int ret = 1; 342 int ret = 1;
343 while (bytes_written < num_bytes && ret > 0) { 343 while (bytes_written < num_bytes && ret > 0) {
344 ret = Write(buffer + bytes_written, num_bytes - bytes_written); 344 ret = Write(static_cast<const char*>(buffer) + bytes_written,
345 num_bytes - bytes_written);
345 if (ret >= 0) 346 if (ret >= 0)
346 bytes_written += ret; 347 bytes_written += ret;
347 } 348 }
348 return bytes_written; 349 return bytes_written;
349 } 350 }
350 351
351 bool Socket::WaitForEvent(EventType type, int timeout_secs) const { 352 bool Socket::WaitForEvent(EventType type, int timeout_secs) {
352 if (exit_notifier_fd_ == -1 || socket_ == -1) 353 if (exit_notifier_fd_ == -1 || socket_ == -1)
353 return true; 354 return true;
354 const int nfds = std::max(socket_, exit_notifier_fd_) + 1; 355 const int nfds = std::max(socket_, exit_notifier_fd_) + 1;
355 fd_set read_fds; 356 fd_set read_fds;
356 fd_set write_fds; 357 fd_set write_fds;
357 FD_ZERO(&read_fds); 358 FD_ZERO(&read_fds);
358 FD_ZERO(&write_fds); 359 FD_ZERO(&write_fds);
359 if (type == READ) 360 if (type == READ)
360 FD_SET(socket_, &read_fds); 361 FD_SET(socket_, &read_fds);
361 else 362 else
362 FD_SET(socket_, &write_fds); 363 FD_SET(socket_, &write_fds);
363 FD_SET(exit_notifier_fd_, &read_fds); 364 FD_SET(exit_notifier_fd_, &read_fds);
364 365
365 timeval tv = {}; 366 timeval tv = {};
366 timeval* tv_ptr = NULL; 367 timeval* tv_ptr = NULL;
367 if (timeout_secs > 0) { 368 if (timeout_secs > 0) {
368 tv.tv_sec = timeout_secs; 369 tv.tv_sec = timeout_secs;
369 tv.tv_usec = 0; 370 tv.tv_usec = 0;
370 tv_ptr = &tv; 371 tv_ptr = &tv;
371 } 372 }
372 if (HANDLE_EINTR(select(nfds, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) 373 if (HANDLE_EINTR(select(nfds, &read_fds, &write_fds, NULL, tv_ptr)) <= 0)
373 return false; 374 return false;
374 return !FD_ISSET(exit_notifier_fd_, &read_fds); 375 if (FD_ISSET(exit_notifier_fd_, &read_fds)) {
376 exited_ = true;
377 return false;
378 }
379 return true;
375 } 380 }
376 381
377 // static 382 // static
378 int Socket::GetHighestFileDescriptor( 383 int Socket::GetHighestFileDescriptor(
379 const Socket& s1, const Socket& s2) { 384 const Socket& s1, const Socket& s2) {
380 return std::max(s1.socket_, s2.socket_); 385 return std::max(s1.socket_, s2.socket_);
381 } 386 }
382 387
383 } // namespace forwarder 388 } // namespace forwarder
OLDNEW
« no previous file with comments | « tools/android/forwarder2/socket.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698