OLD | NEW |
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> |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 } | 66 } |
67 return true; | 67 return true; |
68 } | 68 } |
69 | 69 |
70 Socket::Socket() | 70 Socket::Socket() |
71 : socket_(-1), | 71 : socket_(-1), |
72 port_(0), | 72 port_(0), |
73 socket_error_(false), | 73 socket_error_(false), |
74 family_(AF_INET), | 74 family_(AF_INET), |
75 addr_ptr_(reinterpret_cast<sockaddr*>(&addr_.addr4)), | 75 addr_ptr_(reinterpret_cast<sockaddr*>(&addr_.addr4)), |
76 addr_len_(sizeof(sockaddr)), | 76 addr_len_(sizeof(sockaddr)) { |
77 exit_notifier_fd_(-1), | |
78 exited_(false) { | |
79 memset(&addr_, 0, sizeof(addr_)); | 77 memset(&addr_, 0, sizeof(addr_)); |
80 } | 78 } |
81 | 79 |
82 Socket::~Socket() { | 80 Socket::~Socket() { |
83 Close(); | 81 Close(); |
84 } | 82 } |
85 | 83 |
86 void Socket::Shutdown() { | 84 void Socket::Shutdown() { |
87 if (!IsClosed()) { | 85 if (!IsClosed()) { |
88 PRESERVE_ERRNO_HANDLE_EINTR(shutdown(socket_, SHUT_RDWR)); | 86 PRESERVE_ERRNO_HANDLE_EINTR(shutdown(socket_, SHUT_RDWR)); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL)); | 321 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL)); |
324 if (ret < 0) | 322 if (ret < 0) |
325 SetSocketError(); | 323 SetSocketError(); |
326 return ret; | 324 return ret; |
327 } | 325 } |
328 | 326 |
329 int Socket::WriteString(const std::string& buffer) { | 327 int Socket::WriteString(const std::string& buffer) { |
330 return WriteNumBytes(buffer.c_str(), buffer.size()); | 328 return WriteNumBytes(buffer.c_str(), buffer.size()); |
331 } | 329 } |
332 | 330 |
| 331 void Socket::AddEventFd(int event_fd) { |
| 332 Event event; |
| 333 event.fd = event_fd; |
| 334 event.was_fired = false; |
| 335 events_.push_back(event); |
| 336 } |
| 337 |
| 338 bool Socket::DidReceiveEventOnFd(int fd) const { |
| 339 for (size_t i = 0; i < events_.size(); ++i) |
| 340 if (events_[i].fd == fd) |
| 341 return events_[i].was_fired; |
| 342 return false; |
| 343 } |
| 344 |
| 345 bool Socket::DidReceiveEvent() const { |
| 346 for (size_t i = 0; i < events_.size(); ++i) |
| 347 if (events_[i].was_fired) |
| 348 return true; |
| 349 return false; |
| 350 } |
| 351 |
333 int Socket::WriteNumBytes(const void* buffer, size_t num_bytes) { | 352 int Socket::WriteNumBytes(const void* buffer, size_t num_bytes) { |
334 int bytes_written = 0; | 353 int bytes_written = 0; |
335 int ret = 1; | 354 int ret = 1; |
336 while (bytes_written < num_bytes && ret > 0) { | 355 while (bytes_written < num_bytes && ret > 0) { |
337 ret = Write(static_cast<const char*>(buffer) + bytes_written, | 356 ret = Write(static_cast<const char*>(buffer) + bytes_written, |
338 num_bytes - bytes_written); | 357 num_bytes - bytes_written); |
339 if (ret >= 0) | 358 if (ret >= 0) |
340 bytes_written += ret; | 359 bytes_written += ret; |
341 } | 360 } |
342 return bytes_written; | 361 return bytes_written; |
343 } | 362 } |
344 | 363 |
345 bool Socket::WaitForEvent(EventType type, int timeout_secs) { | 364 bool Socket::WaitForEvent(EventType type, int timeout_secs) { |
346 if (exit_notifier_fd_ == -1 || socket_ == -1) | 365 if (events_.empty() || socket_ == -1) |
347 return true; | 366 return true; |
348 const int nfds = std::max(socket_, exit_notifier_fd_) + 1; | |
349 fd_set read_fds; | 367 fd_set read_fds; |
350 fd_set write_fds; | 368 fd_set write_fds; |
351 FD_ZERO(&read_fds); | 369 FD_ZERO(&read_fds); |
352 FD_ZERO(&write_fds); | 370 FD_ZERO(&write_fds); |
353 if (type == READ) | 371 if (type == READ) |
354 FD_SET(socket_, &read_fds); | 372 FD_SET(socket_, &read_fds); |
355 else | 373 else |
356 FD_SET(socket_, &write_fds); | 374 FD_SET(socket_, &write_fds); |
357 FD_SET(exit_notifier_fd_, &read_fds); | 375 for (size_t i = 0; i < events_.size(); ++i) |
358 | 376 FD_SET(events_[i].fd, &read_fds); |
359 timeval tv = {}; | 377 timeval tv = {}; |
360 timeval* tv_ptr = NULL; | 378 timeval* tv_ptr = NULL; |
361 if (timeout_secs > 0) { | 379 if (timeout_secs > 0) { |
362 tv.tv_sec = timeout_secs; | 380 tv.tv_sec = timeout_secs; |
363 tv.tv_usec = 0; | 381 tv.tv_usec = 0; |
364 tv_ptr = &tv; | 382 tv_ptr = &tv; |
365 } | 383 } |
366 if (HANDLE_EINTR(select(nfds, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) | 384 int max_fd = socket_; |
367 return false; | 385 for (size_t i = 0; i < events_.size(); ++i) |
368 if (FD_ISSET(exit_notifier_fd_, &read_fds)) { | 386 if (events_[i].fd > max_fd) |
369 exited_ = true; | 387 max_fd = events_[i].fd; |
| 388 if (HANDLE_EINTR( |
| 389 select(max_fd + 1, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) { |
370 return false; | 390 return false; |
371 } | 391 } |
372 return true; | 392 bool event_was_fired = false; |
| 393 for (size_t i = 0; i < events_.size(); ++i) { |
| 394 if (FD_ISSET(events_[i].fd, &read_fds)) { |
| 395 events_[i].was_fired = true; |
| 396 event_was_fired = true; |
| 397 } |
| 398 } |
| 399 return !event_was_fired; |
373 } | 400 } |
374 | 401 |
375 // static | 402 // static |
376 int Socket::GetHighestFileDescriptor(const Socket& s1, const Socket& s2) { | 403 int Socket::GetHighestFileDescriptor(const Socket& s1, const Socket& s2) { |
377 return std::max(s1.socket_, s2.socket_); | 404 return std::max(s1.socket_, s2.socket_); |
378 } | 405 } |
379 | 406 |
380 // static | 407 // static |
381 pid_t Socket::GetUnixDomainSocketProcessOwner(const std::string& path) { | 408 pid_t Socket::GetUnixDomainSocketProcessOwner(const std::string& path) { |
382 Socket socket; | 409 Socket socket; |
383 if (!socket.ConnectUnix(path)) | 410 if (!socket.ConnectUnix(path)) |
384 return -1; | 411 return -1; |
385 ucred ucred; | 412 ucred ucred; |
386 socklen_t len = sizeof(ucred); | 413 socklen_t len = sizeof(ucred); |
387 if (getsockopt(socket.socket_, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) { | 414 if (getsockopt(socket.socket_, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) { |
388 CHECK_NE(ENOPROTOOPT, errno); | 415 CHECK_NE(ENOPROTOOPT, errno); |
389 return -1; | 416 return -1; |
390 } | 417 } |
391 return ucred.pid; | 418 return ucred.pid; |
392 } | 419 } |
393 | 420 |
394 } // namespace forwarder2 | 421 } // namespace forwarder2 |
OLD | NEW |