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 "base/sync_socket.h" | 5 #include "base/sync_socket.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <limits.h> | 9 #include <limits.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 22 matching lines...) Expand all Loading... | |
33 const void* buffer, | 33 const void* buffer, |
34 size_t length) { | 34 size_t length) { |
35 DCHECK_GT(length, 0u); | 35 DCHECK_GT(length, 0u); |
36 DCHECK_LE(length, kMaxMessageLength); | 36 DCHECK_LE(length, kMaxMessageLength); |
37 DCHECK_NE(handle, SyncSocket::kInvalidHandle); | 37 DCHECK_NE(handle, SyncSocket::kInvalidHandle); |
38 const char* charbuffer = static_cast<const char*>(buffer); | 38 const char* charbuffer = static_cast<const char*>(buffer); |
39 const int len = file_util::WriteFileDescriptor(handle, charbuffer, length); | 39 const int len = file_util::WriteFileDescriptor(handle, charbuffer, length); |
40 return len < 0 ? 0 : static_cast<size_t>(len); | 40 return len < 0 ? 0 : static_cast<size_t>(len); |
41 } | 41 } |
42 | 42 |
43 bool CloseHandle(SyncSocket::Handle handle) { | |
44 if (handle != SyncSocket::kInvalidHandle && close(handle) < 0) { | |
DaleCurtis
2013/11/01 00:15:59
Removed the EINTR here per http://crbug.com/269623
| |
45 DPLOG(ERROR) << "close"; | |
46 return false; | |
47 } | |
48 | |
49 return true; | |
50 } | |
51 | |
43 } // namespace | 52 } // namespace |
44 | 53 |
45 const SyncSocket::Handle SyncSocket::kInvalidHandle = -1; | 54 const SyncSocket::Handle SyncSocket::kInvalidHandle = -1; |
46 | 55 |
47 SyncSocket::SyncSocket() : handle_(kInvalidHandle) {} | 56 SyncSocket::SyncSocket() : handle_(kInvalidHandle) {} |
48 | 57 |
49 SyncSocket::~SyncSocket() { | 58 SyncSocket::~SyncSocket() { |
50 Close(); | 59 Close(); |
51 } | 60 } |
52 | 61 |
53 // static | 62 // static |
54 bool SyncSocket::CreatePair(SyncSocket* socket_a, SyncSocket* socket_b) { | 63 bool SyncSocket::CreatePair(SyncSocket* socket_a, SyncSocket* socket_b) { |
55 DCHECK_NE(socket_a, socket_b); | 64 DCHECK_NE(socket_a, socket_b); |
56 DCHECK_EQ(socket_a->handle_, kInvalidHandle); | 65 DCHECK_EQ(socket_a->handle_, kInvalidHandle); |
57 DCHECK_EQ(socket_b->handle_, kInvalidHandle); | 66 DCHECK_EQ(socket_b->handle_, kInvalidHandle); |
58 | 67 |
59 #if defined(OS_MACOSX) | 68 #if defined(OS_MACOSX) |
60 int nosigpipe = 1; | 69 int nosigpipe = 1; |
61 #endif // defined(OS_MACOSX) | 70 #endif // defined(OS_MACOSX) |
62 | 71 |
63 Handle handles[2] = { kInvalidHandle, kInvalidHandle }; | 72 Handle handles[2] = { kInvalidHandle, kInvalidHandle }; |
64 if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) | 73 if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) { |
65 goto cleanup; | 74 CloseHandle(handles[0]); |
75 CloseHandle(handles[1]); | |
76 return false; | |
77 } | |
66 | 78 |
67 #if defined(OS_MACOSX) | 79 #if defined(OS_MACOSX) |
68 // On OSX an attempt to read or write to a closed socket may generate a | 80 // On OSX an attempt to read or write to a closed socket may generate a |
69 // SIGPIPE rather than returning -1. setsockopt will shut this off. | 81 // SIGPIPE rather than returning -1. setsockopt will shut this off. |
70 if (0 != setsockopt(handles[0], SOL_SOCKET, SO_NOSIGPIPE, | 82 if (0 != setsockopt(handles[0], SOL_SOCKET, SO_NOSIGPIPE, |
71 &nosigpipe, sizeof nosigpipe) || | 83 &nosigpipe, sizeof nosigpipe) || |
72 0 != setsockopt(handles[1], SOL_SOCKET, SO_NOSIGPIPE, | 84 0 != setsockopt(handles[1], SOL_SOCKET, SO_NOSIGPIPE, |
73 &nosigpipe, sizeof nosigpipe)) { | 85 &nosigpipe, sizeof nosigpipe)) { |
74 goto cleanup; | 86 CloseHandle(handles[0]); |
87 CloseHandle(handles[1]); | |
88 return false; | |
75 } | 89 } |
76 #endif | 90 #endif |
77 | 91 |
78 // Copy the handles out for successful return. | 92 // Copy the handles out for successful return. |
79 socket_a->handle_ = handles[0]; | 93 socket_a->handle_ = handles[0]; |
80 socket_b->handle_ = handles[1]; | 94 socket_b->handle_ = handles[1]; |
81 | 95 |
82 return true; | 96 return true; |
83 | |
84 cleanup: | |
85 if (handles[0] != kInvalidHandle) { | |
86 if (HANDLE_EINTR(close(handles[0])) < 0) | |
87 DPLOG(ERROR) << "close"; | |
88 } | |
89 if (handles[1] != kInvalidHandle) { | |
90 if (HANDLE_EINTR(close(handles[1])) < 0) | |
91 DPLOG(ERROR) << "close"; | |
92 } | |
93 | |
94 return false; | |
95 } | 97 } |
96 | 98 |
97 bool SyncSocket::Close() { | 99 bool SyncSocket::Close() { |
98 if (handle_ == kInvalidHandle) | 100 const bool retval = CloseHandle(handle_); |
99 return true; | |
100 const int retval = HANDLE_EINTR(close(handle_)); | |
101 DPLOG_IF(ERROR, retval < 0) << "close"; | |
102 handle_ = kInvalidHandle; | 101 handle_ = kInvalidHandle; |
103 return retval == 0; | 102 return retval; |
104 } | 103 } |
105 | 104 |
106 size_t SyncSocket::Send(const void* buffer, size_t length) { | 105 size_t SyncSocket::Send(const void* buffer, size_t length) { |
107 ThreadRestrictions::AssertIOAllowed(); | 106 ThreadRestrictions::AssertIOAllowed(); |
108 return SendHelper(handle_, buffer, length); | 107 return SendHelper(handle_, buffer, length); |
109 } | 108 } |
110 | 109 |
111 size_t SyncSocket::Receive(void* buffer, size_t length) { | 110 size_t SyncSocket::Receive(void* buffer, size_t length) { |
112 ThreadRestrictions::AssertIOAllowed(); | 111 ThreadRestrictions::AssertIOAllowed(); |
113 DCHECK_GT(length, 0u); | 112 DCHECK_GT(length, 0u); |
114 DCHECK_LE(length, kMaxMessageLength); | 113 DCHECK_LE(length, kMaxMessageLength); |
115 DCHECK_NE(handle_, kInvalidHandle); | 114 DCHECK_NE(handle_, kInvalidHandle); |
116 char* charbuffer = static_cast<char*>(buffer); | 115 char* charbuffer = static_cast<char*>(buffer); |
117 if (file_util::ReadFromFD(handle_, charbuffer, length)) | 116 if (file_util::ReadFromFD(handle_, charbuffer, length)) |
118 return length; | 117 return length; |
119 return 0; | 118 return 0; |
120 } | 119 } |
121 | 120 |
122 size_t SyncSocket::ReceiveWithTimeout(void* buffer, | 121 size_t SyncSocket::ReceiveWithTimeout(void* buffer, |
123 size_t length, | 122 size_t length, |
124 TimeDelta timeout) { | 123 TimeDelta timeout) { |
125 ThreadRestrictions::AssertIOAllowed(); | 124 ThreadRestrictions::AssertIOAllowed(); |
126 DCHECK_GT(length, 0u); | 125 DCHECK_GT(length, 0u); |
127 DCHECK_LE(length, kMaxMessageLength); | 126 DCHECK_LE(length, kMaxMessageLength); |
128 DCHECK_NE(handle_, kInvalidHandle); | 127 DCHECK_NE(handle_, kInvalidHandle); |
129 DCHECK_LT(handle_, FD_SETSIZE); | 128 CHECK_LT(handle_, FD_SETSIZE); |
130 | 129 |
131 // Only timeouts greater than zero and less than one second are allowed. | 130 // Only timeouts greater than zero and less than one second are allowed. |
132 DCHECK_GT(timeout.InMicroseconds(), 0); | 131 DCHECK_GT(timeout.InMicroseconds(), 0); |
133 DCHECK_LT(timeout.InMicroseconds(), | 132 DCHECK_LT(timeout.InMicroseconds(), |
134 base::TimeDelta::FromSeconds(1).InMicroseconds()); | 133 base::TimeDelta::FromSeconds(1).InMicroseconds()); |
135 | 134 |
136 // Track the start time so we can reduce the timeout as data is read. | 135 // Track the start time so we can reduce the timeout as data is read. |
137 TimeTicks start_time = TimeTicks::Now(); | 136 TimeTicks start_time = TimeTicks::Now(); |
138 const TimeTicks finish_time = start_time + timeout; | 137 const TimeTicks finish_time = start_time + timeout; |
139 | 138 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 return len; | 217 return len; |
219 } | 218 } |
220 | 219 |
221 // static | 220 // static |
222 bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a, | 221 bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a, |
223 CancelableSyncSocket* socket_b) { | 222 CancelableSyncSocket* socket_b) { |
224 return SyncSocket::CreatePair(socket_a, socket_b); | 223 return SyncSocket::CreatePair(socket_a, socket_b); |
225 } | 224 } |
226 | 225 |
227 } // namespace base | 226 } // namespace base |
OLD | NEW |