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

Side by Side Diff: experimental/linux_debug_server/debugger/base/debug_socket.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months 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
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "debugger/base/debug_socket.h"
6 #include <memory.h>
7 #include <string.h>
8
9 #ifndef _WIN32
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <netdb.h>
13 #include <netinet/tcp.h>
14 #include <errno.h>
15 #endif
16
17 namespace {
18 fd_set* kNoFdSet = NULL;
19 const int kMicroPerMilli = 1000;
20 const char* kAnyLocalHost = NULL;
21 sockaddr* kNoPeerAddress = NULL;
22 const int kWaitForOneWriteMs = 1000;
23 const int kWaitForOneReadMs = 1000;
24 const int kWriteBufferSize = 2048;
25 const int kLingerSeconds = 10;
26
27 bool InitSocketLib() {
28 #ifdef _WIN32
29 WSADATA wsa_data;
30 WORD version_requested = MAKEWORD(1, 1);
31 return (WSAStartup(version_requested, &wsa_data) == 0);
32 #else
33 return true;
34 #endif
35 }
36
37 void FreeSocketLib() {
38 #ifdef _WIN32
39 WSACleanup();
40 #endif
41 }
42
43 timeval CreateTimeval(int milliseconds) {
44 timeval timeout;
45 timeout.tv_sec = 0;
46 timeout.tv_usec = milliseconds * kMicroPerMilli;
47 return timeout;
48 }
49
50 sockaddr_in CreateSockAddr(const char* host, int port) {
51 sockaddr_in addr;
52 memset(&addr, 0, sizeof(addr));
53 addr.sin_family = AF_INET;
54 addr.sin_port = htons(port); // Convert port number from host byte order
55 // to network byte order.
56 if ((NULL == host) || (strlen(host) == 0)) {
57 addr.sin_addr.s_addr = htonl(INADDR_ANY);
58 } else {
59 hostent* hostDescr = gethostbyname(host);
60 if (NULL != hostDescr)
61 addr.sin_addr.s_addr =
62 *(reinterpret_cast<unsigned int**>(hostDescr->h_addr_list)[0]);
63 }
64 return addr;
65 }
66
67 void SetSocketOptions(SOCKET sock) {
68 if (INVALID_SOCKET != sock) {
69 // Setup socket to flush pending data on close.
70 linger ling;
71 ling.l_onoff = 1;
72 // A socket should remain open for kLingerSeconds seconds after
73 // a closesocket function call to enable queued data to be sent.
74 ling.l_linger = kLingerSeconds;
75 setsockopt(sock,
76 SOL_SOCKET,
77 SO_LINGER,
78 reinterpret_cast<char*>(&ling),
79 sizeof(ling));
80 // Turn off buffering, to speedup debugger communication.
81 int opt = 1;
82 setsockopt(sock,
83 IPPROTO_TCP,
84 TCP_NODELAY,
85 reinterpret_cast<char*>(&opt),
86 sizeof(opt));
87 }
88 }
89 } // namespace
90
91 namespace debug {
92 SocketBase::SocketBase()
93 : sock_(INVALID_SOCKET),
94 init_success_(false),
95 saved_last_error_(kSocketNoError) {
96 init_success_ = InitSocketLib();
97 }
98
99 SocketBase::~SocketBase() {
100 if (init_success_)
101 FreeSocketLib();
102 }
103
104 int SocketBase::GetLastError() {
105 #ifdef _WIN32
106 int res = WSAGetLastError();
107 if (kSocketNoError == res)
108 return saved_last_error_;
109 return res;
110 #else
111 return errno;
112 #endif
113 }
114
115 void SocketBase::Close() {
116 if (INVALID_SOCKET != sock_) {
117 saved_last_error_ = GetLastError();
118 #ifdef _WIN32
119 closesocket(sock_);
120 #else
121 shutdown(sock_, SHUT_RDWR);
122 close(sock_);
123 #endif
124 sock_ = INVALID_SOCKET;
125 }
126 }
127
128 void SocketBase::ClearSavedLastError() {
129 saved_last_error_ = kSocketNoError;
130 }
131
132 bool ListeningSocket::Listen(int port) {
133 ClearSavedLastError();
134 Close();
135 sock_ = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
136 if (INVALID_SOCKET == sock_)
137 return false;
138
139 // Associate local address with socket.
140 sockaddr_in addr = CreateSockAddr(kAnyLocalHost, port);
141 if (bind(sock_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) != 0) {
142 Close();
143 return false;
144 }
145 // Mark a socket as accepting connections.
146 if (listen(sock_, SOMAXCONN) != 0) {
147 Close();
148 }
149 return (INVALID_SOCKET != sock_);
150 }
151
152 bool ListeningSocket::Accept(int wait_ms, Socket* new_connection) {
153 ClearSavedLastError();
154 fd_set socks;
155 FD_ZERO(&socks);
156 FD_SET(sock_, &socks);
157
158 // Wait for incoming connection.
159 timeval timeout = CreateTimeval(wait_ms);
160 if (select(sock_ + 1, &socks, kNoFdSet, kNoFdSet, &timeout) < 0) {
161 Close();
162 return false;
163 }
164 // No connection requests.
165 if (!FD_ISSET(sock_, &socks))
166 return false;
167
168 // Accept a connection request.
169 SOCKET sock = accept(sock_, kNoPeerAddress, 0);
170 if (INVALID_SOCKET != sock)
171 new_connection->AttachTo(sock);
172
173 return new_connection->IsConnected();
174 }
175
176 void Socket::AttachTo(SOCKET sock) {
177 Close();
178 ClearSavedLastError();
179 sock_ = sock;
180 SetSocketOptions(sock_);
181 }
182
183 bool Socket::ConnectTo(const std::string& host, int port) {
184 Close();
185 ClearSavedLastError();
186 sock_ = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
187 if (INVALID_SOCKET == sock_)
188 return false;
189
190 sockaddr_in addr = CreateSockAddr(host.c_str(), port);
191 if (connect(sock_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) != 0)
192 Close();
193 else
194 SetSocketOptions(sock_);
195 return IsConnected();
196 }
197
198 bool Socket::IsConnected() const {
199 bool connected = (INVALID_SOCKET != sock_);
200 if (!connected && (kSocketNoError == saved_last_error_))
201 const_cast<Socket*>(this)->saved_last_error_ = 666;
202 return connected;
203 }
204
205 size_t Socket::Write(const void* buff, size_t buff_len, int wait_ms) {
206 if (!IsConnected())
207 return 0;
208
209 ClearSavedLastError();
210 fd_set socks;
211 FD_ZERO(&socks);
212 FD_SET(sock_, &socks);
213
214 // Wait for 'write ready'.
215 timeval timeout = CreateTimeval(wait_ms);
216 if (select(sock_ + 1, kNoFdSet, &socks, kNoFdSet, &timeout) < 0) {
217 Close();
218 return 0;
219 }
220 int bytes_send = 0;
221 if (FD_ISSET(sock_, &socks)) {
222 bytes_send = send(sock_, static_cast<const char*>(buff), buff_len, 0);
223 if (bytes_send < 0) {
224 Close();
225 return 0;
226 }
227 }
228 return bytes_send;
229 }
230
231 // Blocks until all data has been sent.
232 size_t Socket::WriteAll(const void* buff, size_t buff_len) {
233 const char* ptr = static_cast<const char*>(buff);
234 size_t sent_bytes = 0;
235 while (IsConnected() && (buff_len > 0)) {
236 size_t wr = Write(ptr, buff_len, kWaitForOneWriteMs);
237 sent_bytes += wr;
238 buff_len -= wr;
239 ptr += wr;
240 }
241 return sent_bytes;
242 }
243
244 size_t Socket::WriteAll(const Blob& blob) {
245 size_t sent_bytes = 0;
246 while (IsConnected() && (sent_bytes < blob.size())) {
247 char buff[kWriteBufferSize];
248 size_t bytes_to_send = blob.Peek(sent_bytes, buff, sizeof(buff));
249 sent_bytes += WriteAll(buff, bytes_to_send);
250 }
251 return sent_bytes;
252 }
253
254 size_t Socket::Read(void* buff, size_t buff_len, int wait_ms) {
255 if (!IsConnected())
256 return 0;
257
258 ClearSavedLastError();
259 fd_set socks;
260 FD_ZERO(&socks);
261 FD_SET(sock_, &socks);
262 timeval timeout = CreateTimeval(wait_ms);
263
264 // Wait for data.
265 if (select(sock_ + 1, &socks, kNoFdSet, kNoFdSet, &timeout) < 0) {
266 Close();
267 return 0;
268 }
269 // No data available.
270 if (!FD_ISSET(sock_, &socks))
271 return 0;
272
273 ssize_t read_bytes = recv(sock_, static_cast<char*>(buff), buff_len, 0);
274 if ((-1 == read_bytes) || (0 == read_bytes)) {
275 Close();
276 return 0;
277 }
278 return read_bytes;
279 }
280
281 size_t Socket::ReadAll(void* buff, size_t buff_len) {
282 size_t total_rd_bytes = 0;
283 char* ptr = static_cast<char*>(buff);
284 char* buff_end = ptr + buff_len;
285 while (IsConnected() && (ptr < buff_end)) {
286 size_t rd = Read(ptr, buff_len - total_rd_bytes, kWaitForOneReadMs);
287 total_rd_bytes += rd;
288 ptr += rd;
289 }
290 return total_rd_bytes;
291 }
292
293 } // namespace debug
294
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698