Chromium Code Reviews| Index: libraries/nacl-mounts/net/SocketSubSystem.cc |
| =================================================================== |
| --- libraries/nacl-mounts/net/SocketSubSystem.cc (revision 0) |
| +++ libraries/nacl-mounts/net/SocketSubSystem.cc (revision 0) |
| @@ -0,0 +1,207 @@ |
| +// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <arpa/inet.h> |
| +#include <irt.h> |
| +#include <netinet/in.h> |
| +#include <signal.h> |
| +#include <string.h> |
| +#include <sys/socket.h> |
| + |
| +#include "net/SocketSubSystem.h" |
| +#include "net/TcpServerSocket.h" |
| +#include "net/TcpSocket.h" |
| +#include "ppapi/cpp/file_ref.h" |
| +#include "util/DebugPrint.h" |
| + |
| + |
| +SocketSubSystem* SocketSubSystem::instance_ = NULL; |
|
Evgeniy Stepanov
2012/05/25 12:05:57
unused
vissi
2012/05/25 13:07:09
No, it's used by GetSocketSubSystem() referenced i
Evgeniy Stepanov
2012/05/25 13:19:51
Pass pp::Instance through TCPSocket constructor.
vissi
2012/05/25 14:32:06
They use the same condition variable. Should they?
vissi
2012/05/25 14:54:08
Per offline discussion, we decided that it would b
|
| + |
| +SocketSubSystem::SocketSubSystem(pp::Instance* instance) |
| + : pp_instance_(instance) |
| + , first_unused_addr_(kFirstAddr) { |
| + AddHostAddress("localhost", 0x7F000001); |
| + instance_ = this; |
| +} |
| + |
| +void SocketSubSystem::AddHostAddress(const char* name, unsigned long addr) { |
| + addr = htonl(addr); |
| + hosts_[name] = addr; |
| + addrs_[addr] = name; |
| +} |
| + |
| +unsigned long SocketSubSystem::gethostbyname(const char* name) { |
| + Mutex::Lock lock(mutex_); |
| + HostMap::iterator it = hosts_.find(name); |
| + if (it != hosts_.end()) |
| + return it->second; |
| + |
| + int addr = htonl(first_unused_addr_++); |
| + hosts_[name] = addr; |
| + addrs_[addr] = name; |
| + return addr; |
| +} |
| + |
| +int SocketSubSystem::bind(FileStream** stream, unsigned long addr, |
| + unsigned short port) { |
| + Mutex::Lock lock(mutex_); |
| + |
| + std::string host; |
| + AddressMap::iterator it = addrs_.find(addr); |
| + if (it != addrs_.end()) { |
| + host = it->second; |
| + } else { |
| + in_addr iaddr; |
| + iaddr.s_addr = addr; |
| + host = inet_ntoa(iaddr); |
| + } |
| + |
| + *stream = new TCPServerSocket(0, host.c_str(), port); |
| + return 0; |
| +} |
| + |
| +int SocketSubSystem::connect(FileStream** stream, unsigned long addr, |
| + unsigned short port) { |
| + Mutex::Lock lock(mutex_); |
| + |
| + std::string host; |
| + AddressMap::iterator it = addrs_.find(addr); |
|
Evgeniy Stepanov
2012/05/25 12:05:57
factor this piece out
vissi
2012/05/25 13:07:09
Why?
Evgeniy Stepanov
2012/05/25 13:19:51
I mean, make it a function. It's repeated twice in
vissi
2012/05/25 14:32:06
Done.
|
| + if (it != addrs_.end()) { |
| + host = it->second; |
| + } else { |
| + in_addr iaddr; |
| + iaddr.s_addr = addr; |
| + host = inet_ntoa(iaddr); |
| + } |
| + |
| + FileStream* new_stream = NULL; |
| + TCPSocket* socket = new TCPSocket(O_RDWR); |
| + if (!socket->connect(host.c_str(), port)) { |
| + errno = ECONNREFUSED; |
| + socket->release(); |
| + return -1; |
| + } |
| + new_stream = socket; |
| + |
| + *stream = new_stream; |
| + return 0; |
| +} |
| + |
| +SocketSubSystem::~SocketSubSystem() { |
| +} |
| + |
| +int SocketSubSystem::shutdown(FileStream* stream, int how) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) { |
| + // Actually shutdown should be something more complicated by for now |
| + // it works. Method close can be called multiple time. |
| + stream->close(); |
| + return 0; |
| + } else { |
| + errno = EBADF; |
| + return -1; |
| + } |
| +} |
| + |
| +int SocketSubSystem::close(FileStream* stream) { |
| + Mutex::Lock lock(mutex_); |
| + |
| + if (stream && stream != kBadFileStream) { |
|
Evgeniy Stepanov
2012/05/25 12:05:57
could we get rid of this constant?
vissi
2012/05/25 13:07:09
yup.
|
| + stream->close(); |
| + stream->release(); |
| + } |
| + return 0; |
| +} |
| + |
| +int SocketSubSystem::read(FileStream* stream, char* buf, size_t count, |
| + size_t* nread) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) |
|
Evgeniy Stepanov
2012/05/25 12:05:57
move this check to KernelProxy, assume that stream
vissi
2012/05/25 13:07:09
Haven't moved this yet. We check if FileHandle is
|
| + return stream->read(buf, count, nread); |
| + else |
| + return EBADF; |
| +} |
| + |
| +int SocketSubSystem::write(FileStream* stream, const char* buf, size_t count, |
| + size_t* nwrote) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) |
| + return stream->write(buf, count, nwrote); |
| + else |
| + return EBADF; |
| +} |
| + |
| +int SocketSubSystem::seek(FileStream* stream, nacl_abi_off_t offset, int whence, |
| + nacl_abi_off_t* new_offset) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) |
| + return stream->seek(offset, whence, new_offset); |
| + else |
| + return EBADF; |
| +} |
| + |
| +int SocketSubSystem::fstat(FileStream* stream, nacl_abi_stat* out) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) |
| + return stream->fstat(out); |
| + else |
| + return EBADF; |
| +} |
| + |
| +int SocketSubSystem::fcntl(FileStream* stream, int cmd, va_list ap) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) { |
| + return stream->fcntl(cmd, ap); |
| + } else { |
| + errno = EBADF; |
| + return -1; |
| + } |
| +} |
| + |
| +int SocketSubSystem::ioctl(FileStream* stream, int request, va_list ap) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) { |
| + return stream->ioctl(request, ap); |
| + } else { |
| + errno = EBADF; |
| + return -1; |
| + } |
| +} |
| + |
| +int SocketSubSystem::listen(FileStream* stream, int backlog) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) { |
| + if (static_cast<TCPServerSocket*>(stream)->listen(backlog)) { |
| + return 0; |
| + } else { |
| + errno = EACCES; |
| + return -1; |
| + } |
| + } else { |
| + errno = EBADF; |
| + return -1; |
| + } |
| +} |
| + |
| +FileStream* SocketSubSystem::accept(FileStream* stream, struct sockaddr *addr, |
| + socklen_t* addrlen) { |
| + Mutex::Lock lock(mutex_); |
| + if (stream && stream != kBadFileStream) { |
| + PP_Resource resource = static_cast<TCPServerSocket*>(stream)->accept(); |
| + if (resource) { |
| + TCPSocket* socket = new TCPSocket(O_RDWR); |
| + if (socket->accept(resource)) { |
| + return socket; |
| + } else { |
| + socket->release(); |
| + } |
| + } |
| + errno = EINVAL; |
| + return 0; |
| + } else { |
| + errno = EBADF; |
| + return 0; |
| + } |
| +} |
| + |