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

Side by Side Diff: libraries/nacl-mounts/net/SocketSubSystem.cc

Issue 10392070: Socket subsystem implementation (Closed) Base URL: http://naclports.googlecode.com/svn/trunk/src/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium OS 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 <arpa/inet.h>
6 #include <irt.h>
7 #include <netinet/in.h>
8 #include <signal.h>
9 #include <string.h>
10 #include <sys/socket.h>
11
12 #include "base/KernelProxy.h"
13 #include "net/SocketSubSystem.h"
14 #include "net/TcpServerSocket.h"
15 #include "net/TcpSocket.h"
16 #include "ppapi/cpp/file_ref.h"
17 #include "util/DebugPrint.h"
18
19 FileStream* const SocketSubSystem::kBadFileStream =
20 reinterpret_cast<FileStream*>(-1);
21
22 SocketSubSystem* SocketSubSystem::instance_ = NULL;
23
24 SocketSubSystem::SocketSubSystem(pp::Instance* instance)
25 : pp_instance_(instance)
26 , first_unused_addr_(kFirstAddr) {
27 AddHostAddress("localhost", 0x7F000001);
28 instance_ = this;
29 }
30
31 void SocketSubSystem::AddHostAddress(const char* name, unsigned long addr) {
32 addr = htonl(addr);
33 hosts_[name] = addr;
34 addrs_[addr] = name;
35 }
36
37 unsigned long SocketSubSystem::gethostbyname(const char* name) {
38 Mutex::Lock lock(mutex_);
39 HostMap::iterator it = hosts_.find(name);
40 if (it != hosts_.end())
41 return it->second;
42
43 int addr = htonl(first_unused_addr_++);
44 hosts_[name] = addr;
45 addrs_[addr] = name;
46 return addr;
47 }
48
49 int SocketSubSystem::socket(int socket_family, int socket_type, int protocol) {
50 Mutex::Lock lock(mutex_);
51 int fd = KernelProxy::KPInstance()->CreateSocket();
52 return fd;
53 }
54
55 int SocketSubSystem::GetFirstUnusedDescriptor() {
56 return KernelProxy::KPInstance()->CreateSocket();
57 }
58
59 bool SocketSubSystem::IsKnowDescriptor(int fd) {
60 return KernelProxy::KPInstance()->GetFileHandle(fd) != 0 &&
61 KernelProxy::KPInstance()->GetFileHandle(fd)->stream != kBadFileStream;
62 }
63
64 FileStream* SocketSubSystem::GetStream(int fd) {
65 return KernelProxy::KPInstance()->GetFileHandle(fd)->stream;
66 }
67
68 int SocketSubSystem::bind(FileHandle* handle, unsigned long addr,
69 unsigned short port) {
70 Mutex::Lock lock(mutex_);
71
72 std::string host;
73 AddressMap::iterator it = addrs_.find(addr);
74 if (it != addrs_.end()) {
75 host = it->second;
76 } else {
77 in_addr iaddr;
78 iaddr.s_addr = addr;
79 host = inet_ntoa(iaddr);
80 }
81
82 handle->stream = new TCPServerSocket(0, host.c_str(), port);
83 return 0;
84 }
85
86 int SocketSubSystem::connect(FileHandle* handle, unsigned long addr,
87 unsigned short port) {
88 Mutex::Lock lock(mutex_);
89
90 std::string host;
91 AddressMap::iterator it = addrs_.find(addr);
92 if (it != addrs_.end()) {
93 host = it->second;
94 } else {
95 in_addr iaddr;
96 iaddr.s_addr = addr;
97 host = inet_ntoa(iaddr);
98 }
99
100 FileStream* stream = NULL;
101 TCPSocket* socket = new TCPSocket(O_RDWR);
102 if (!socket->connect(host.c_str(), port)) {
103 errno = ECONNREFUSED;
104 socket->release();
105 return -1;
106 }
107 stream = socket;
108
109 handle->stream = stream;
110 return 0;
111 }
112
113 SocketSubSystem::~SocketSubSystem() {
114 }
115
116 int SocketSubSystem::shutdown(int fd, int how) {
117 Mutex::Lock lock(mutex_);
118 FileStream* stream = GetStream(fd);
119 if (stream && stream != kBadFileStream) {
120 // Actually shutdown should be something more complicated by for now
121 // it works. Method close can be called multiple time.
122 stream->close();
123 return 0;
124 } else {
125 errno = EBADF;
126 return -1;
127 }
128 }
129
130 int SocketSubSystem::close(int fd) {
131 Mutex::Lock lock(mutex_);
132 if (!IsKnowDescriptor(fd))
133 return EBADF;
134
135 FileStream* stream = GetStream(fd);
136 if (stream && stream != kBadFileStream) {
137 stream->close();
138 stream->release();
139 }
140 KernelProxy::KPInstance()->RemoveFileStream(fd);
141 return 0;
142 }
143
144 int SocketSubSystem::read(FileHandle* handle, char* buf, size_t count,
145 size_t* nread) {
146 Mutex::Lock lock(mutex_);
147 FileStream* stream = handle->stream;
148 if (stream && stream != kBadFileStream)
149 return stream->read(buf, count, nread);
150 else
151 return EBADF;
152 }
153
154 int SocketSubSystem::write(FileHandle* handle, const char* buf, size_t count,
155 size_t* nwrote) {
156 Mutex::Lock lock(mutex_);
157 FileStream* stream = handle->stream;
158 if (stream && stream != kBadFileStream)
159 return stream->write(buf, count, nwrote);
160 else
161 return EBADF;
162 }
163
164 int SocketSubSystem::seek(FileHandle* handle, nacl_abi_off_t offset, int whence,
165 nacl_abi_off_t* new_offset) {
166 Mutex::Lock lock(mutex_);
167 FileStream* stream = handle->stream;
168 if (stream && stream != kBadFileStream)
169 return stream->seek(offset, whence, new_offset);
170 else
171 return EBADF;
172 }
173
174 /*int SocketSubSystem::dup(int fd, int *newfd) {
175 Mutex::Lock lock(mutex_);
176 FileStream* stream = GetStream(fd);
177 if (!stream || stream == kBadFileStream)
178 return EBADF;
179
180 // Mark as used.
181 *newfd = KernelProxy::KPInstance()->AddFileStream(NULL);
182 FileStream* new_stream = stream->dup(*newfd);
183 if (!new_stream) {
184 KernelProxy::KPInstance()->RemoveFileStream(*newfd);
185 return EACCES;
186 }
187
188 // TODO(vissi): check it
189 KernelProxy::KPInstance()->GetFileHandle(*newfd)->stream = new_stream;
190 return 0;
191 }
192
193 int SocketSubSystem::dup2(int fd, int newfd) {
194 Mutex::Lock lock(mutex_);
195 FileStream* stream = GetStream(fd);
196 if (!stream || stream == kBadFileStream)
197 return EBADF;
198
199 FileStream* new_stream = GetStream(newfd);
200 if (stream == kBadFileStream) {
201 return EBADF;
202 } else if (!new_stream) {
203 new_stream->close();
204 new_stream->release();
205 KernelProxy::KPInstance()->RemoveFileStream(newfd);
206 }
207
208 KernelProxy::KPInstance()->GetFileHandle(newfd)->stream
209 = stream->dup(newfd);
210 if (!new_stream)
211 return EACCES;
212
213 // TODO(vissi): AddFileStream(newfd, new_stream);
214 return 0;
215 }*/
216
217 int SocketSubSystem::fstat(FileHandle* handle, nacl_abi_stat* out) {
218 Mutex::Lock lock(mutex_);
219 FileStream* stream = handle->stream;
220 if (stream && stream != kBadFileStream)
221 return stream->fstat(out);
222 else
223 return EBADF;
224 }
225
226 int SocketSubSystem::fcntl(FileHandle* handle, int cmd, va_list ap) {
227 Mutex::Lock lock(mutex_);
228 FileStream* stream = handle->stream;
229 if (stream && stream != kBadFileStream) {
230 return stream->fcntl(cmd, ap);
231 } else {
232 errno = EBADF;
233 return -1;
234 }
235 }
236
237 int SocketSubSystem::ioctl(FileHandle* handle, int request, va_list ap) {
238 Mutex::Lock lock(mutex_);
239 FileStream* stream = handle->stream;
240 if (stream && stream != kBadFileStream) {
241 return stream->ioctl(request, ap);
242 } else {
243 errno = EBADF;
244 return -1;
245 }
246 }
247
248 int SocketSubSystem::IsReady(int nfds, fd_set* fds,
249 bool (FileStream::*is_ready)(), bool apply) {
250 if (!fds)
251 return 0;
252
253 int nset = 0;
254 for (int i = 0; i < nfds; i++) {
255 if (FD_ISSET(i, fds)) {
256 FileStream* stream = GetStream(i);
257 if (!stream)
258 return -1;
259 if ((stream->*is_ready)()) {
260 if (!apply)
261 return 1;
262 else
263 nset++;
264 } else {
265 if (apply)
266 FD_CLR(i, fds);
267 }
268 }
269 }
270 return nset;
271 }
272
273 int SocketSubSystem::listen(FileHandle *handle, int backlog) {
274 Mutex::Lock lock(mutex_);
275 FileStream *stream = handle->stream;
276 if (stream && stream != kBadFileStream) {
277 if (static_cast<TCPServerSocket*>(stream)->listen(backlog)) {
278 return 0;
279 } else {
280 errno = EACCES;
281 return -1;
282 }
283 } else {
284 errno = EBADF;
285 return -1;
286 }
287 }
288
289 int SocketSubSystem::accept(FileHandle* handle, struct sockaddr *addr,
290 socklen_t* addrlen) {
291 Mutex::Lock lock(mutex_);
292 FileStream *stream = handle->stream;
293 if (stream && stream != kBadFileStream) {
294 PP_Resource resource = static_cast<TCPServerSocket*>(stream)->accept();
295 if (resource) {
296 TCPSocket* socket = new TCPSocket(O_RDWR);
297 if (socket->accept(resource)) {
298 return KernelProxy::KPInstance()->AddFileStream(socket);
299 } else {
300 socket->release();
301 }
302 }
303 errno = EINVAL;
304 return -1;
305 } else {
306 errno = EBADF;
307 return -1;
308 }
309 }
310
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698