Merge from Chromium at DEPS revision 228962
This commit was generated by merge_to_master.py.
Change-Id: I23bd7d7766f213fd52f28ae5e1ecc6ae9df905ea
diff --git a/native_client_sdk/src/libraries/nacl_io/event_emitter_pipe.h b/native_client_sdk/src/libraries/nacl_io/event_emitter_pipe.h
index 27a5ba4..a357bea 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_emitter_pipe.h
+++ b/native_client_sdk/src/libraries/nacl_io/event_emitter_pipe.h
@@ -27,10 +27,11 @@
size_t Read_Locked(char* data, size_t len);
size_t Write_Locked(const char* data, size_t len);
+ protected:
virtual FIFOChar* in_fifo() { return &fifo_; }
virtual FIFOChar* out_fifo() { return &fifo_; }
-private:
+ private:
FIFOChar fifo_;
DISALLOW_COPY_AND_ASSIGN(EventEmitterPipe);
};
diff --git a/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.cc b/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.cc
index 600f234..5c636ab 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.cc
+++ b/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.cc
@@ -39,7 +39,12 @@
RaiseEvents_Locked(status);
}
+uint32_t EventEmitterStream::BytesInOutputFIFO() {
+ return out_fifo()->ReadAvailable();
+}
+
+uint32_t EventEmitterStream::SpaceInInputFIFO() {
+ return in_fifo()->WriteAvailable();
+}
} // namespace nacl_io
-
-
diff --git a/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.h b/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.h
index 34afec2..1b40b01 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.h
+++ b/native_client_sdk/src/libraries/nacl_io/event_emitter_stream.h
@@ -26,10 +26,13 @@
void DetachStream();
MountNodeStream* stream() { return stream_; }
- virtual FIFOInterface* in_fifo() = 0;
- virtual FIFOInterface* out_fifo() = 0;
+
+ uint32_t BytesInOutputFIFO();
+ uint32_t SpaceInInputFIFO();
protected:
+ virtual FIFOInterface* in_fifo() = 0;
+ virtual FIFOInterface* out_fifo() = 0;
void UpdateStatus_Locked();
protected:
diff --git a/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.cc b/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.cc
index 24d7cdd..8e11258 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.cc
+++ b/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.cc
@@ -16,7 +16,6 @@
EventEmitterTCP::EventEmitterTCP(size_t rsize, size_t wsize)
: in_fifo_(std::max<size_t>(65536, rsize)),
out_fifo_(std::max<size_t>(65536, wsize)) {
- UpdateStatus_Locked();
}
uint32_t EventEmitterTCP::ReadIn_Locked(char* data, uint32_t len) {
@@ -47,7 +46,21 @@
return count;
}
+void EventEmitterTCP::ConnectDone_Locked() {
+ RaiseEvents_Locked(POLLOUT);
+ UpdateStatus_Locked();
+}
+
+void EventEmitterTCP::SetAcceptedSocket_Locked(PP_Resource socket) {
+ accepted_socket_ = socket;
+ RaiseEvents_Locked(POLLIN);
+}
+
+PP_Resource EventEmitterTCP::GetAcceptedSocket_Locked() {
+ int rtn = accepted_socket_;
+ accepted_socket_ = 0;
+ ClearEvents_Locked(POLLIN);
+ return rtn;
+}
} // namespace nacl_io
-
-
diff --git a/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.h b/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.h
index 99a559a..2b40e29 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.h
+++ b/native_client_sdk/src/libraries/nacl_io/event_emitter_tcp.h
@@ -8,12 +8,17 @@
#include "nacl_io/event_emitter_stream.h"
#include "nacl_io/fifo_char.h"
+#include <ppapi/c/pp_resource.h>
+
#include "sdk_util/macros.h"
#include "sdk_util/scoped_ref.h"
+
namespace nacl_io {
class EventEmitterTCP;
+class MountNode;
+
typedef sdk_util::ScopedRef<EventEmitterTCP> ScopedEventEmitterTCP;
class EventEmitterTCP : public EventEmitterStream {
@@ -26,12 +31,18 @@
uint32_t ReadOut_Locked(char* buffer, uint32_t len);
uint32_t WriteOut_Locked(const char* buffer, uint32_t len);
+ void ConnectDone_Locked();
+ PP_Resource GetAcceptedSocket_Locked();
+ void SetAcceptedSocket_Locked(PP_Resource socket);
+
+ protected:
virtual FIFOChar* in_fifo() { return &in_fifo_; }
virtual FIFOChar* out_fifo() { return &out_fifo_; }
-protected:
+ private:
FIFOChar in_fifo_;
FIFOChar out_fifo_;
+ PP_Resource accepted_socket_;
DISALLOW_COPY_AND_ASSIGN(EventEmitterTCP);
};
diff --git a/native_client_sdk/src/libraries/nacl_io/event_emitter_tty.h b/native_client_sdk/src/libraries/nacl_io/event_emitter_tty.h
index c0ef09c..d3fbd89 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_emitter_tty.h
+++ b/native_client_sdk/src/libraries/nacl_io/event_emitter_tty.h
@@ -28,6 +28,7 @@
size_t Read_Locked(char* data, size_t len);
size_t Write_Locked(const char* data, size_t len);
+ protected:
virtual FIFOChar* in_fifo() { return &fifo_; }
virtual FIFONull* out_fifo() { return &null_; }
diff --git a/native_client_sdk/src/libraries/nacl_io/event_emitter_udp.h b/native_client_sdk/src/libraries/nacl_io/event_emitter_udp.h
index 02d64a4..cb64fbc 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_emitter_udp.h
+++ b/native_client_sdk/src/libraries/nacl_io/event_emitter_udp.h
@@ -27,10 +27,11 @@
Packet* ReadTXPacket_Locked();
void WriteTXPacket_Locked(Packet* packet);
+protected:
virtual FIFOPacket* in_fifo() { return &in_fifo_; }
virtual FIFOPacket* out_fifo() { return &out_fifo_; }
-protected:
+private:
FIFOPacket in_fifo_;
FIFOPacket out_fifo_;
DISALLOW_COPY_AND_ASSIGN(EventEmitterUDP);
diff --git a/native_client_sdk/src/libraries/nacl_io/event_listener.cc b/native_client_sdk/src/libraries/nacl_io/event_listener.cc
index ce679f8..8ad13bd 100644
--- a/native_client_sdk/src/libraries/nacl_io/event_listener.cc
+++ b/native_client_sdk/src/libraries/nacl_io/event_listener.cc
@@ -53,7 +53,7 @@
}
void EventListenerLock::ReceiveEvents(EventEmitter* emitter,
- uint32_t events) {
+ uint32_t events) {
// We are using the emitter's mutex, which is already locked.
pthread_cond_signal(&signal_cond_);
}
@@ -67,8 +67,8 @@
int return_code;
if (ms_timeout >= 0) {
return_code = pthread_cond_timedwait(&signal_cond_,
- emitter_->GetLock().mutex(),
- &timeout);
+ emitter_->GetLock().mutex(),
+ &timeout);
} else {
return_code = pthread_cond_wait(&signal_cond_,
emitter_->GetLock().mutex());
@@ -89,7 +89,7 @@
}
void EventListenerPoll::ReceiveEvents(EventEmitter* emitter,
- uint32_t events) {
+ uint32_t events) {
AUTO_LOCK(signal_lock_);
emitters_[emitter]->events |= events;
signaled_++;
@@ -97,8 +97,8 @@
}
Error EventListenerPoll::WaitOnAny(EventRequest* requests,
- size_t cnt,
- int ms_timeout) {
+ size_t cnt,
+ int ms_timeout) {
signaled_ = 0;
@@ -114,8 +114,8 @@
// responsible for it's own request.
for (size_t index = 0; index < cnt; index++) {
EventRequest* request = requests + index;
- requests->emitter->RegisterListener(this, request->filter);
- uint32_t events = requests->emitter->GetEventStatus() & request->filter;
+ request->emitter->RegisterListener(this, request->filter);
+ uint32_t events = request->emitter->GetEventStatus() & request->filter;
if (events) {
AUTO_LOCK(signal_lock_);
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc b/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc
index 37d3fa4..eab3ce8 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_handle.cc
@@ -5,11 +5,11 @@
#include "nacl_io/kernel_handle.h"
#include <errno.h>
-#include <fcntl.h>
#include <pthread.h>
#include "nacl_io/mount.h"
#include "nacl_io/mount_node.h"
+#include "nacl_io/mount_node_socket.h"
#include "nacl_io/osunistd.h"
#include "sdk_util/auto_lock.h"
@@ -18,10 +18,10 @@
// It is only legal to construct a handle while the kernel lock is held.
KernelHandle::KernelHandle()
- : mount_(NULL), node_(NULL), offs_(0) {}
+ : mount_(NULL), node_(NULL) {}
KernelHandle::KernelHandle(const ScopedMount& mnt, const ScopedMountNode& node)
- : mount_(mnt), node_(node), offs_(0) {}
+ : mount_(mnt), node_(node) {}
KernelHandle::~KernelHandle() {
// Force release order for cases where mount_ is not ref'd by mounting.
@@ -30,15 +30,17 @@
}
// Returns the MountNodeSocket* if this node is a socket.
-MountNodeSocket* KernelHandle::socket_node() {
+MountNodeSocket* KernelHandle::socket_node() {
if (node_.get() && node_->IsaSock())
return reinterpret_cast<MountNodeSocket*>(node_.get());
return NULL;
}
-Error KernelHandle::Init(int open_mode) {
- if (open_mode & O_APPEND) {
- Error error = node_->GetSize(&offs_);
+Error KernelHandle::Init(int open_flags) {
+ handle_attr_.flags = open_flags;
+
+ if (open_flags & O_APPEND) {
+ Error error = node_->GetSize(&handle_attr_.offs);
if (error)
return error;
}
@@ -52,7 +54,7 @@
size_t base;
size_t node_size;
- AUTO_LOCK(offs_lock_);
+ AUTO_LOCK(handle_lock_);
Error error = node_->GetSize(&node_size);
if (error)
return error;
@@ -64,7 +66,7 @@
base = 0;
break;
case SEEK_CUR:
- base = offs_;
+ base = handle_attr_.offs;
break;
case SEEK_END:
base = node_size;
@@ -84,32 +86,134 @@
return EINVAL;
}
- *out_offset = offs_ = new_offset;
+ *out_offset = handle_attr_.offs = new_offset;
return 0;
}
Error KernelHandle::Read(void* buf, size_t nbytes, int* cnt) {
- AUTO_LOCK(offs_lock_);
- Error error = node_->Read(offs_, buf, nbytes, cnt);
+ AUTO_LOCK(handle_lock_);
+ Error error = node_->Read(handle_attr_, buf, nbytes, cnt);
if (0 == error)
- offs_ += *cnt;
+ handle_attr_.offs += *cnt;
return error;
}
Error KernelHandle::Write(const void* buf, size_t nbytes, int* cnt) {
- AUTO_LOCK(offs_lock_);
- Error error = node_->Write(offs_, buf, nbytes, cnt);
+ AUTO_LOCK(handle_lock_);
+ Error error = node_->Write(handle_attr_, buf, nbytes, cnt);
if (0 == error)
- offs_ += *cnt;
+ handle_attr_.offs += *cnt;
return error;
}
Error KernelHandle::GetDents(struct dirent* pdir, size_t nbytes, int* cnt) {
- AUTO_LOCK(offs_lock_);
- Error error = node_->GetDents(offs_, pdir, nbytes, cnt);
+ AUTO_LOCK(handle_lock_);
+ Error error = node_->GetDents(handle_attr_.offs, pdir, nbytes, cnt);
if (0 == error)
- offs_ += *cnt;
+ handle_attr_.offs += *cnt;
return error;
}
+Error KernelHandle::Fcntl(int request, int* result, ...) {
+ va_list ap;
+ va_start(ap, result);
+ Error rtn = VFcntl(request, result, ap);
+ va_end(ap);
+ return rtn;
+}
+
+Error KernelHandle::VFcntl(int request, int* result, va_list args) {
+ switch (request) {
+ case F_GETFL: {
+ *result = handle_attr_.flags;
+ return 0;
+ }
+ case F_SETFL: {
+ AUTO_LOCK(handle_lock_);
+ int flags = va_arg(args, int);
+ if (!(flags & O_APPEND) && (handle_attr_.flags & O_APPEND)) {
+ // Attempt to clear O_APPEND.
+ return EPERM;
+ }
+ // Only certain flags are mutable
+ const int mutable_flags = O_ASYNC | O_NONBLOCK;
+ flags &= mutable_flags;
+ handle_attr_.flags &= ~mutable_flags;
+ handle_attr_.flags |= flags;
+ return 0;
+ }
+ }
+ return ENOSYS;
+}
+
+Error KernelHandle::Accept(PP_Resource* new_sock, struct sockaddr* addr,
+ socklen_t* len) {
+ MountNodeSocket* sock = socket_node();
+ if (!sock)
+ return ENOTSOCK;
+
+ AUTO_LOCK(handle_lock_);
+ return sock->Accept(handle_attr_, new_sock, addr, len);
+}
+
+Error KernelHandle::Connect(const struct sockaddr* addr, socklen_t len) {
+ MountNodeSocket* sock = socket_node();
+ if (!sock)
+ return ENOTSOCK;
+
+ AUTO_LOCK(handle_lock_);
+ return sock->Connect(handle_attr_, addr, len);
+}
+
+Error KernelHandle::Recv(void* buf, size_t len, int flags, int* out_len) {
+ MountNodeSocket* sock = socket_node();
+ if (!sock)
+ return ENOTSOCK;
+
+ AUTO_LOCK(handle_lock_);
+ return sock->Recv(handle_attr_, buf, len, flags, out_len);
+}
+
+Error KernelHandle::RecvFrom(void* buf,
+ size_t len,
+ int flags,
+ struct sockaddr* src_addr,
+ socklen_t* addrlen,
+ int* out_len) {
+ MountNodeSocket* sock = socket_node();
+ if (!sock)
+ return ENOTSOCK;
+
+ AUTO_LOCK(handle_lock_);
+ return sock->RecvFrom(handle_attr_, buf, len, flags, src_addr, addrlen,
+ out_len);
+}
+
+Error KernelHandle::Send(const void* buf,
+ size_t len,
+ int flags,
+ int* out_len) {
+ MountNodeSocket* sock = socket_node();
+ if (!sock)
+ return ENOTSOCK;
+
+ AUTO_LOCK(handle_lock_);
+ return sock->Send(handle_attr_, buf, len, flags, out_len);
+}
+
+Error KernelHandle::SendTo(const void* buf,
+ size_t len,
+ int flags,
+ const struct sockaddr* dest_addr,
+ socklen_t addrlen,
+ int* out_len) {
+ MountNodeSocket* sock = socket_node();
+ if (!sock)
+ return ENOTSOCK;
+
+ AUTO_LOCK(handle_lock_);
+ return sock->SendTo(handle_attr_, buf, len, flags, dest_addr, addrlen,
+ out_len);
+}
+
} // namespace nacl_io
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_handle.h b/native_client_sdk/src/libraries/nacl_io/kernel_handle.h
index fd76dde..a4609c3 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_handle.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_handle.h
@@ -5,11 +5,14 @@
#ifndef LIBRARIES_NACL_IO_KERNEL_HANDLE_H_
#define LIBRARIES_NACL_IO_KERNEL_HANDLE_H_
+#include <fcntl.h>
#include <pthread.h>
+#include <ppapi/c/pp_resource.h>
#include "nacl_io/error.h"
#include "nacl_io/mount.h"
#include "nacl_io/mount_node.h"
+#include "nacl_io/ossocket.h"
#include "nacl_io/ostypes.h"
#include "sdk_util/macros.h"
@@ -19,40 +22,68 @@
namespace nacl_io {
-class MountNode;
class MountNodeSocket;
+// HandleAttr struct is passed the MountNode in calls
+// to Read and Write. It contains handle specific state
+// such as the file offset and the open flags.
+struct HandleAttr {
+ HandleAttr() : offs(0), flags(0) {}
+ bool IsBlocking() const { return !(flags & O_NONBLOCK); }
+
+ size_t offs;
+ int flags;
+};
+
// KernelHandle provides a reference counted container for the open
// file information, such as it's mount, node, access type and offset.
// KernelHandle can only be referenced when the KernelProxy lock is held.
class KernelHandle : public sdk_util::RefObject {
public:
+
KernelHandle();
KernelHandle(const ScopedMount& mnt, const ScopedMountNode& node);
~KernelHandle();
Error Init(int open_flags);
+ Error Accept(PP_Resource* new_sock, struct sockaddr* addr, socklen_t* len);
+ Error Connect(const struct sockaddr* addr, socklen_t len);
+ Error Fcntl(int request, int* result, ...);
+ Error VFcntl(int request, int* result, va_list args);
+ Error GetDents(struct dirent* pdir, size_t count, int* bytes_written);
+ Error Read(void* buf, size_t nbytes, int* bytes_read);
+ Error Recv(void* buf, size_t len, int flags, int* out_len);
+ Error RecvFrom(void* buf,
+ size_t len,
+ int flags,
+ struct sockaddr* src_addr,
+ socklen_t* addrlen,
+ int* out_len);
// Assumes |out_offset| is non-NULL.
Error Seek(off_t offset, int whence, off_t* out_offset);
-
- // Dispatches Read, Write, GetDents to atomically update offs_.
- Error Read(void* buf, size_t nbytes, int* bytes_read);
+ Error Send(const void* buf, size_t len, int flags, int* out_len);
+ Error SendTo(const void* buf,
+ size_t len,
+ int flags,
+ const struct sockaddr* dest_addr,
+ socklen_t addrlen,
+ int* out_len);
Error Write(const void* buf, size_t nbytes, int* bytes_written);
- Error GetDents(struct dirent* pdir, size_t count, int* bytes_written);
const ScopedMountNode& node() { return node_; }
const ScopedMount& mount() { return mount_; }
+ const HandleAttr& Attr() { return handle_attr_; }
+private:
// Returns the MountNodeSocket* if this node is a socket otherwise returns
// NULL.
MountNodeSocket* socket_node();
-private:
ScopedMount mount_;
ScopedMountNode node_;
- sdk_util::SimpleLock offs_lock_;
- size_t offs_;
+ sdk_util::SimpleLock handle_lock_;
+ HandleAttr handle_attr_;
friend class KernelProxy;
DISALLOW_COPY_AND_ASSIGN(KernelHandle);
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
index 373b93a..4083d4f 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
@@ -100,6 +100,11 @@
return s_kp->chmod(path, mode);
}
+int ki_fchmod(int fd, mode_t mode) {
+ ON_NOSYS_RETURN(-1);
+ return s_kp->fchmod(fd, mode);
+}
+
int ki_stat(const char *path, struct stat *buf) {
ON_NOSYS_RETURN(-1);
return s_kp->stat(path, buf);
@@ -221,14 +226,14 @@
ON_NOSYS_RETURN(-1); return s_kp->open_resource(file);
}
-int ki_fcntl(int d, int request, char* argp) {
+int ki_fcntl(int d, int request, va_list args) {
ON_NOSYS_RETURN(-1);
- return s_kp->fcntl(d, request, argp);
+ return s_kp->fcntl(d, request, args);
}
-int ki_ioctl(int d, int request, char* argp) {
+int ki_ioctl(int d, int request, va_list args) {
ON_NOSYS_RETURN(-1);
- return s_kp->ioctl(d, request, argp);
+ return s_kp->ioctl(d, request, args);
}
int ki_chown(const char* path, uid_t owner, gid_t group) {
@@ -316,6 +321,7 @@
int ki_getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
return s_kp->getsockname(fd, addr, len);
}
+
int ki_getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
return s_kp->getsockopt(fd, lvl, optname, optval, len);
}
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
index f8ebeed..3fbb87a 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
@@ -5,6 +5,8 @@
#ifndef LIBRARIES_NACL_IO_KERNEL_INTERCEPT_H_
#define LIBRARIES_NACL_IO_KERNEL_INTERCEPT_H_
+#include <stdarg.h>
+
#include <ppapi/c/ppb.h>
#include <ppapi/c/pp_instance.h>
@@ -37,6 +39,7 @@
int ki_dup(int oldfd);
int ki_dup2(int oldfd, int newfd);
int ki_chmod(const char* path, mode_t mode);
+int ki_fchmod(int fd, mode_t mode);
int ki_stat(const char* path, struct stat* buf);
int ki_mkdir(const char* path, mode_t mode);
int ki_rmdir(const char* path);
@@ -63,8 +66,8 @@
off_t offset);
int ki_munmap(void* addr, size_t length);
int ki_open_resource(const char* file);
-int ki_fcntl(int d, int request, char* argp);
-int ki_ioctl(int d, int request, char* argp);
+int ki_fcntl(int d, int request, va_list args);
+int ki_ioctl(int d, int request, va_list args);
int ki_chown(const char* path, uid_t owner, gid_t group);
int ki_fchown(int fd, uid_t owner, gid_t group);
int ki_lchown(const char* path, uid_t owner, gid_t group);
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
index 82a3ec1..fd5f6b5 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
@@ -4,7 +4,6 @@
#include "nacl_io/kernel_proxy.h"
-
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@@ -155,18 +154,18 @@
return AllocateFD(handle);
}
-int KernelProxy::open(const char* path, int oflags) {
+int KernelProxy::open(const char* path, int open_flags) {
ScopedMount mnt;
ScopedMountNode node;
- Error error = AcquireMountAndNode(path, oflags, &mnt, &node);
+ Error error = AcquireMountAndNode(path, open_flags, &mnt, &node);
if (error) {
errno = error;
return -1;
}
ScopedKernelHandle handle(new KernelHandle(mnt, node));
- error = handle->Init(oflags);
+ error = handle->Init(open_flags);
if (error) {
errno = error;
return -1;
@@ -539,7 +538,7 @@
return 0;
}
-int KernelProxy::ioctl(int fd, int request, char* argp) {
+int KernelProxy::ioctl(int fd, int request, va_list args) {
ScopedKernelHandle handle;
Error error = AcquireHandle(fd, &handle);
if (error) {
@@ -547,7 +546,7 @@
return -1;
}
- error = handle->node()->Ioctl(request, argp);
+ error = handle->node()->VIoctl(request, args);
if (error) {
errno = error;
return -1;
@@ -624,7 +623,7 @@
return 0;
}
-int KernelProxy::fcntl(int fd, int request, char *argp) {
+int KernelProxy::fcntl(int fd, int request, va_list args) {
ScopedKernelHandle handle;
Error error = AcquireHandle(fd, &handle);
if (error) {
@@ -632,9 +631,14 @@
return -1;
}
- // TODO(sbc): Needs implementation.
- errno = ENOSYS;
- return -1;
+ int rtn = 0;
+ error = handle->VFcntl(request, &rtn, args);
+ if (error) {
+ errno = error;
+ return -1;
+ }
+
+ return rtn;
}
int KernelProxy::access(const char* path, int amode) {
@@ -1015,7 +1019,6 @@
}
-
// Socket Functions
int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
if (NULL == addr || NULL == len) {
@@ -1024,11 +1027,33 @@
}
ScopedKernelHandle handle;
- if (AcquireSocketHandle(fd, &handle) == -1)
+ Error error = AcquireHandle(fd, &handle);
+ if (error) {
+ errno = error;
return -1;
+ }
- errno = EINVAL;
- return -1;
+ PP_Resource new_sock = 0;
+ error = handle->Accept(&new_sock, addr, len);
+ if (error != 0) {
+ errno = error;
+ return -1;
+ }
+
+ MountNodeSocket* sock = new MountNodeTCP(stream_mount_.get(), new_sock);
+
+ // The MountNodeSocket now holds a reference to the new socket
+ // so we release ours.
+ ppapi_->ReleaseResource(new_sock);
+ error = sock->Init(S_IREAD | S_IWRITE);
+ if (error != 0) {
+ errno = error;
+ return -1;
+ }
+
+ ScopedMountNode node(sock);
+ ScopedKernelHandle new_handle(new KernelHandle(stream_mount_, node));
+ return AllocateFD(new_handle);
}
int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) {
@@ -1057,12 +1082,15 @@
}
ScopedKernelHandle handle;
- if (AcquireSocketHandle(fd, &handle) == -1)
+ Error error = AcquireHandle(fd, &handle);
+ if (error) {
+ errno = error;
return -1;
+ }
- Error err = handle->socket_node()->Connect(addr, len);
- if (err != 0) {
- errno = err;
+ error = handle->Connect(addr, len);
+ if (error != 0) {
+ errno = error;
return -1;
}
@@ -1112,10 +1140,10 @@
}
int KernelProxy::getsockopt(int fd,
- int lvl,
- int optname,
- void* optval,
- socklen_t* len) {
+ int lvl,
+ int optname,
+ void* optval,
+ socklen_t* len) {
if (NULL == optval || NULL == len) {
errno = EFAULT;
return -1;
@@ -1125,8 +1153,13 @@
if (AcquireSocketHandle(fd, &handle) == -1)
return -1;
- errno = EINVAL;
- return -1;
+ Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len);
+ if (err != 0) {
+ errno = err;
+ return -1;
+ }
+
+ return 0;
}
int KernelProxy::listen(int fd, int backlog) {
@@ -1134,8 +1167,13 @@
if (AcquireSocketHandle(fd, &handle) == -1)
return -1;
- errno = EOPNOTSUPP;
- return -1;
+ Error err = handle->socket_node()->Listen(backlog);
+ if (err != 0) {
+ errno = err;
+ return -1;
+ }
+
+ return 0;
}
ssize_t KernelProxy::recv(int fd,
@@ -1148,13 +1186,16 @@
}
ScopedKernelHandle handle;
- if (AcquireSocketHandle(fd, &handle) == -1)
+ Error error = AcquireHandle(fd, &handle);
+ if (error) {
+ errno = error;
return -1;
+ }
int out_len = 0;
- Error err = handle->socket_node()->Recv(buf, len, flags, &out_len);
- if (err != 0) {
- errno = err;
+ error = handle->Recv(buf, len, flags, &out_len);
+ if (error != 0) {
+ errno = error;
return -1;
}
@@ -1178,18 +1219,16 @@
}
ScopedKernelHandle handle;
- if (AcquireSocketHandle(fd, &handle) == -1)
+ Error error = AcquireHandle(fd, &handle);
+ if (error) {
+ errno = error;
return -1;
+ }
int out_len = 0;
- Error err = handle->socket_node()->RecvFrom(buf,
- len,
- flags,
- addr,
- addrlen,
- &out_len);
- if (err != 0) {
- errno = err;
+ error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len);
+ if (error != 0) {
+ errno = error;
return -1;
}
@@ -1217,13 +1256,16 @@
}
ScopedKernelHandle handle;
- if (AcquireSocketHandle(fd, &handle) == -1)
+ Error error = AcquireHandle(fd, &handle);
+ if (error) {
+ errno = error;
return -1;
+ }
int out_len = 0;
- Error err = handle->socket_node()->Send(buf, len, flags, &out_len);
- if (err != 0) {
- errno = err;
+ error = handle->Send(buf, len, flags, &out_len);
+ if (error != 0) {
+ errno = error;
return -1;
}
@@ -1247,15 +1289,16 @@
}
ScopedKernelHandle handle;
- if (AcquireSocketHandle(fd, &handle) == -1)
+ Error error = AcquireHandle(fd, &handle);
+ if (error) {
+ errno = error;
return -1;
+ }
int out_len = 0;
- Error err =
- handle->socket_node()->SendTo(buf, len, flags, addr, addrlen, &out_len);
-
- if (err != 0) {
- errno = err;
+ error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len);
+ if (error != 0) {
+ errno = error;
return -1;
}
@@ -1290,8 +1333,13 @@
if (AcquireSocketHandle(fd, &handle) == -1)
return -1;
- errno = EINVAL;
- return -1;
+ Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len);
+ if (err != 0) {
+ errno = err;
+ return -1;
+ }
+
+ return 0;
}
int KernelProxy::shutdown(int fd, int how) {
@@ -1330,13 +1378,14 @@
}
ScopedMountNode node(sock);
- if (sock->Init(S_IREAD | S_IWRITE) == 0) {
- ScopedKernelHandle handle(new KernelHandle(stream_mount_, node));
- return AllocateFD(handle);
+ Error rtn = sock->Init(S_IREAD | S_IWRITE);
+ if (rtn != 0) {
+ errno = rtn;
+ return -1;
}
- // If we failed to init, assume we don't have access.
- return EACCES;
+ ScopedKernelHandle handle(new KernelHandle(stream_mount_, node));
+ return AllocateFD(handle);
}
int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) {
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
index de175f8..82768b7 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
@@ -55,7 +55,7 @@
virtual int open_resource(const char* file);
// KernelHandle and FD allocation and manipulation functions.
- virtual int open(const char* path, int oflag);
+ virtual int open(const char* path, int open_flags);
virtual int close(int fd);
virtual int dup(int fd);
virtual int dup2(int fd, int newfd);
@@ -95,13 +95,13 @@
virtual ssize_t write(int fd, const void *buf, size_t nbyte);
virtual int fchmod(int fd, int prot);
- virtual int fcntl(int fd, int request, char *argp);
+ virtual int fcntl(int fd, int request, va_list args);
virtual int fstat(int fd, struct stat *buf);
virtual int getdents(int fd, void *buf, unsigned int count);
virtual int ftruncate(int fd, off_t length);
virtual int fsync(int fd);
virtual int isatty(int fd);
- virtual int ioctl(int fd, int request, char *argp);
+ virtual int ioctl(int fd, int request, va_list args);
// lseek() relies on the mount's Stat() to determine whether or not the
// file handle corresponding to fd is a directory
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_newlib.cc b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_newlib.cc
index db77914..8903775 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_newlib.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_newlib.cc
@@ -13,6 +13,7 @@
#include <dirent.h>
#include <errno.h>
#include <irt.h>
+#include <irt_dev.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -44,7 +45,7 @@
#define USE_WRAP(group, name) \
__libnacl_irt_##group.name = (typeof(REAL(name))) WRAP(name); \
-extern void __libnacl_irt_filename_init(void);
+extern void __libnacl_irt_dev_filename_init(void);
extern struct nacl_irt_fdio __libnacl_irt_fdio;
extern struct nacl_irt_dev_filename __libnacl_irt_dev_filename;
@@ -139,7 +140,7 @@
static void assign_real_pointers() {
static bool assigned = false;
if (!assigned) {
- __libnacl_irt_filename_init();
+ __libnacl_irt_dev_filename_init();
EXPAND_SYMBOL_LIST_OPERATION(ASSIGN_REAL_PTR)
assigned = true;
}
diff --git a/native_client_sdk/src/libraries/nacl_io/library.dsc b/native_client_sdk/src/libraries/nacl_io/library.dsc
index 0245928..4b74345 100644
--- a/native_client_sdk/src/libraries/nacl_io/library.dsc
+++ b/native_client_sdk/src/libraries/nacl_io/library.dsc
@@ -66,6 +66,7 @@
"syscalls/chmod.c",
"syscalls/chown.c",
"syscalls/connect.c",
+ "syscalls/fchmod.c",
"syscalls/fchown.c",
"syscalls/fcntl.c",
"syscalls/fdopen.c",
@@ -116,6 +117,7 @@
"syscalls/sigset.c",
"syscalls/socket.c",
"syscalls/socketpair.c",
+ "syscalls/symlink.c",
"syscalls/unlink.c",
"syscalls/umount.c",
"syscalls/uname.c",
diff --git a/native_client_sdk/src/libraries/nacl_io/mount.cc b/native_client_sdk/src/libraries/nacl_io/mount.cc
index ef5a70a..92f977a 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount.cc
@@ -39,9 +39,9 @@
return EINVAL;
}
-int Mount::OpenModeToPermission(int mode) {
+int Mount::OpenFlagsToPermission(int open_flags) {
int out;
- switch (mode & 3) {
+ switch (open_flags & 3) {
case O_RDONLY:
out = S_IREAD;
case O_WRONLY:
diff --git a/native_client_sdk/src/libraries/nacl_io/mount.h b/native_client_sdk/src/libraries/nacl_io/mount.h
index 4374c9b..e480d89 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount.h
@@ -54,7 +54,7 @@
// MountNode is created with a ref count of 1.
// Assumes that |out_node| is non-NULL.
virtual Error Open(const Path& path,
- int o_flags,
+ int open_flags,
ScopedMountNode* out_node) = 0;
// OpenResource is only used to read files from the NaCl NMF file. No mount
@@ -69,8 +69,8 @@
virtual Error Rmdir(const Path& path) = 0;
virtual Error Remove(const Path& path) = 0;
- // Convert from R,W,R/W open flags to STAT permission flags
- static int OpenModeToPermission(int mode);
+ // Convert from R,W,R/W open flags to STAT permissions.
+ static int OpenFlagsToPermission(int open_flags);
// Assumes that |node| is non-NULL.
void OnNodeCreated(MountNode* node);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_dev.cc b/native_client_sdk/src/libraries/nacl_io/mount_dev.cc
index 3c7ffe0..b0c2d5b 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_dev.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_dev.cc
@@ -34,8 +34,11 @@
public:
RealNode(Mount* mount, int fd);
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs,
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
@@ -49,8 +52,11 @@
public:
explicit NullNode(Mount* mount) : MountNodeCharDevice(mount) {}
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs,
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
@@ -60,7 +66,7 @@
public:
ConsoleNode(Mount* mount, PP_LogLevel level);
- virtual Error Write(size_t offs,
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
@@ -73,8 +79,11 @@
public:
explicit ZeroNode(Mount* mount);
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs,
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
@@ -84,8 +93,11 @@
public:
explicit UrandomNode(Mount* mount);
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs,
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
@@ -101,7 +113,10 @@
stat_.st_mode = S_IFCHR;
}
-Error RealNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error RealNode::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
*out_bytes = 0;
size_t readcnt;
@@ -113,7 +128,7 @@
return 0;
}
-Error RealNode::Write(size_t offs,
+Error RealNode::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -130,12 +145,15 @@
Error RealNode::GetStat(struct stat* stat) { return _real_fstat(fd_, stat); }
-Error NullNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error NullNode::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
*out_bytes = 0;
return 0;
}
-Error NullNode::Write(size_t offs,
+Error NullNode::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -147,7 +165,7 @@
: MountNodeCharDevice(mount), level_(level) {
}
-Error ConsoleNode::Write(size_t offs,
+Error ConsoleNode::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -159,9 +177,9 @@
if (!(var_intr && con_intr))
return ENOSYS;
- const char* data = static_cast<const char*>(buf);
+ const char* var_data = static_cast<const char*>(buf);
uint32_t len = static_cast<uint32_t>(count);
- struct PP_Var val = var_intr->VarFromUtf8(data, len);
+ struct PP_Var val = var_intr->VarFromUtf8(var_data, len);
con_intr->Log(mount_->ppapi()->GetInstance(), level_, val);
*out_bytes = count;
@@ -170,13 +188,16 @@
ZeroNode::ZeroNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; }
-Error ZeroNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error ZeroNode::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
memset(buf, 0, count);
*out_bytes = count;
return 0;
}
-Error ZeroNode::Write(size_t offs,
+Error ZeroNode::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -193,7 +214,10 @@
#endif
}
-Error UrandomNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error UrandomNode::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
*out_bytes = 0;
#if defined(__native_client__)
@@ -229,7 +253,7 @@
#endif
}
-Error UrandomNode::Write(size_t offs,
+Error UrandomNode::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -252,11 +276,13 @@
return 0;
}
-Error MountDev::Open(const Path& path, int mode, ScopedMountNode* out_node) {
+Error MountDev::Open(const Path& path,
+ int open_flags,
+ ScopedMountNode* out_node) {
out_node->reset(NULL);
// Don't allow creating any files.
- if (mode & O_CREAT)
+ if (open_flags & O_CREAT)
return EINVAL;
return root_->FindChild(path.Join(), out_node);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_dev.h b/native_client_sdk/src/libraries/nacl_io/mount_dev.h
index a967f5a..5b253cd 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_dev.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_dev.h
@@ -15,7 +15,9 @@
class MountDev : public Mount {
public:
virtual Error Access(const Path& path, int a_mode);
- virtual Error Open(const Path& path, int mode, ScopedMountNode* out_node);
+ virtual Error Open(const Path& path,
+ int open_flags,
+ ScopedMountNode* out_node);
virtual Error Unlink(const Path& path);
virtual Error Mkdir(const Path& path, int permissions);
virtual Error Rmdir(const Path& path);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc
index 9d364d7..f4d9a6d 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc
@@ -33,7 +33,7 @@
}
Error MountHtml5Fs::Open(const Path& path,
- int mode,
+ int open_flags,
ScopedMountNode* out_node) {
out_node->reset(NULL);
Error error = BlockUntilFilesystemOpen();
@@ -46,7 +46,7 @@
return ENOENT;
ScopedMountNode node(new MountNodeHtml5Fs(this, fileref));
- error = node->Init(mode);
+ error = node->Init(open_flags);
if (error)
return error;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_http.cc b/native_client_sdk/src/libraries/nacl_io/mount_http.cc
index 2a37a6a..6ced25d 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_http.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_http.cc
@@ -15,12 +15,12 @@
#include <vector>
-#include <ppapi/c/pp_errors.h>
-
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/mount_node_dir.h"
#include "nacl_io/mount_node_http.h"
#include "nacl_io/osinttypes.h"
#include "nacl_io/osunistd.h"
+#include <ppapi/c/pp_errors.h>
#include "sdk_util/string_util.h"
namespace nacl_io {
@@ -63,7 +63,7 @@
return 0;
}
-Error MountHttp::Open(const Path& path, int mode, ScopedMountNode* out_node) {
+Error MountHttp::Open(const Path& path, int flags, ScopedMountNode* out_node) {
out_node->reset(NULL);
assert(url_root_.empty() || url_root_[url_root_.length() - 1] == '/');
@@ -76,7 +76,7 @@
// If we can't find the node in the cache, create it
std::string url = MakeUrl(path);
ScopedMountNode node(new MountNodeHttp(this, url, cache_content_));
- Error error = node->Init(mode);
+ Error error = node->Init(OpenFlagsToPermission(flags));
if (error)
return error;
@@ -381,7 +381,7 @@
char* text = new char[size + 1];
int len;
- error = manifest_node->Read(0, text, size, &len);
+ error = manifest_node->Read(HandleAttr(), text, size, &len);
if (error)
return error;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_mem.cc b/native_client_sdk/src/libraries/nacl_io/mount_mem.cc
index 715d49a..2959599 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_mem.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_mem.cc
@@ -29,7 +29,7 @@
return error;
root_.reset(new MountNodeDir(this));
- error = root_->Init(S_IREAD | S_IWRITE);
+ error = root_->Init(S_IREAD | S_IWRITE | S_IEXEC);
if (error) {
root_.reset(NULL);
return error;
@@ -93,14 +93,14 @@
return 0;
}
-Error MountMem::Open(const Path& path, int mode, ScopedMountNode* out_node) {
+Error MountMem::Open(const Path& path, int flags, ScopedMountNode* out_node) {
out_node->reset(NULL);
ScopedMountNode node;
Error error = FindNode(path, 0, &node);
if (error) {
// If the node does not exist and we can't create it, fail
- if ((mode & O_CREAT) == 0)
+ if ((flags & O_CREAT) == 0)
return ENOENT;
// Now first find the parent directory to see if we can add it
@@ -110,7 +110,7 @@
return error;
node.reset(new MountNodeMem(this));
- error = node->Init(OpenModeToPermission(mode));
+ error = node->Init(OpenFlagsToPermission(flags));
if (error)
return error;
@@ -123,16 +123,16 @@
}
// Directories can only be opened read-only.
- if (node->IsaDir() && (mode & 3) != O_RDONLY)
+ if (node->IsaDir() && (flags & 3) != O_RDONLY)
return EISDIR;
// If we were expected to create it exclusively, fail
- if (mode & O_EXCL)
+ if (flags & O_EXCL)
return EEXIST;
// Verify we got the requested permissions.
- int req_mode = OpenModeToPermission(mode);
- int obj_mode = node->GetMode() & OpenModeToPermission(O_RDWR);
+ int req_mode = OpenFlagsToPermission(flags);
+ int obj_mode = node->GetMode() & (S_IREAD | S_IWRITE);
if ((obj_mode & req_mode) != req_mode)
return EACCES;
@@ -166,7 +166,7 @@
// it will get ref counted again. In either case, release the
// recount we have on exit.
node.reset(new MountNodeDir(this));
- error = node->Init(S_IREAD | S_IWRITE);
+ error = node->Init(S_IREAD | S_IWRITE | S_IEXEC);
if (error)
return error;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node.cc b/native_client_sdk/src/libraries/nacl_io/mount_node.cc
index 1f0dc24..787db32 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node.cc
@@ -13,6 +13,7 @@
#include <algorithm>
#include <string>
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/kernel_wrap_real.h"
#include "nacl_io/mount.h"
#include "nacl_io/osmman.h"
@@ -38,8 +39,8 @@
MountNode::~MountNode() {}
-Error MountNode::Init(int perm) {
- stat_.st_mode |= perm;
+Error MountNode::Init(int mode) {
+ stat_.st_mode |= mode;
return 0;
}
@@ -76,14 +77,25 @@
return 0;
}
-Error MountNode::Ioctl(int request, char* arg) { return EINVAL; }
+Error MountNode::Ioctl(int request, ...) {
+ va_list ap;
+ va_start(ap, request);
+ Error rtn = VIoctl(request, ap);
+ va_end(ap);
+ return rtn;
+}
-Error MountNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error MountNode::VIoctl(int request, va_list args) { return EINVAL; }
+
+Error MountNode::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
*out_bytes = 0;
return EINVAL;
}
-Error MountNode::Write(size_t offs,
+Error MountNode::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -115,8 +127,11 @@
return mmap_error;
}
+ HandleAttr data;
+ data.offs = offset;
+ data.flags = 0;
int bytes_read;
- Error read_error = Read(offset, new_addr, length, &bytes_read);
+ Error read_error = Read(data, new_addr, length, &bytes_read);
if (read_error) {
_real_munmap(new_addr, length);
return read_error;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node.h b/native_client_sdk/src/libraries/nacl_io/mount_node.h
index 37847c9..e998f2b 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node.h
@@ -5,6 +5,7 @@
#ifndef LIBRARIES_NACL_IO_MOUNT_NODE_H_
#define LIBRARIES_NACL_IO_MOUNT_NODE_H_
+#include <stdarg.h>
#include <string>
#include "nacl_io/error.h"
@@ -21,6 +22,7 @@
class Mount;
class MountNode;
+struct HandleAttr;
typedef sdk_util::ScopedRef<MountNode> ScopedMountNode;
@@ -32,8 +34,8 @@
virtual ~MountNode();
protected:
- // Initialize with node specific flags, in this case stat permissions.
- virtual Error Init(int flags);
+ // Initialize with stat mode flags
+ virtual Error Init(int mode);
virtual void Destroy();
public:
@@ -57,11 +59,15 @@
// Assume that |stat| is non-NULL.
virtual Error GetStat(struct stat* stat);
// Assume that |arg| is non-NULL.
- virtual Error Ioctl(int request, char* arg);
+ Error Ioctl(int request, ...);
+ virtual Error VIoctl(int request, va_list args);
// Assume that |buf| and |out_bytes| are non-NULL.
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
// Assume that |buf| and |out_bytes| are non-NULL.
- virtual Error Write(size_t offs,
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
@@ -87,7 +93,6 @@
virtual bool IsaSock();
virtual bool IsaTTY();
-
// Number of children for this node (directory)
virtual int ChildCount();
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc
index ae56550..4ce1c72 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc
@@ -34,14 +34,17 @@
}
}
-Error MountNodeDir::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error MountNodeDir::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
*out_bytes = 0;
return EISDIR;
}
Error MountNodeDir::FTruncate(off_t size) { return EISDIR; }
-Error MountNodeDir::Write(size_t offs,
+Error MountNodeDir::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_dir.h b/native_client_sdk/src/libraries/nacl_io/mount_node_dir.h
index 867afd4..049a3af 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_dir.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_dir.h
@@ -35,8 +35,9 @@
struct dirent* pdir,
size_t count,
int* out_bytes);
- virtual Error Read(size_t offs, void *buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs, const void *buf,
+ virtual Error Read(const HandleAttr& attr, void *buf,
+ size_t count, int* out_bytes);
+ virtual Error Write(const HandleAttr& attr, const void *buf,
size_t count, int* out_bytes);
// Adds a finds or adds a directory entry as an INO, updating the refcount
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc
index 3d4b1d1..19ebeaa 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc
@@ -13,7 +13,9 @@
#include <ppapi/c/ppb_file_io.h>
#include <string.h>
#include <vector>
+
#include "nacl_io/getdents_helper.h"
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/mount.h"
#include "nacl_io/osdirent.h"
#include "nacl_io/pepper_interface.h"
@@ -41,30 +43,30 @@
return output->data;
}
-int32_t ModeToOpenFlags(int mode) {
- int32_t open_flags = 0;
+int32_t OpenFlagsToPPAPIOpenFlags(int open_flags) {
+ int32_t ppapi_flags = 0;
- switch (mode & 3) {
+ switch (open_flags & 3) {
default:
case O_RDONLY:
- open_flags = PP_FILEOPENFLAG_READ;
+ ppapi_flags = PP_FILEOPENFLAG_READ;
break;
case O_WRONLY:
- open_flags = PP_FILEOPENFLAG_WRITE;
+ ppapi_flags = PP_FILEOPENFLAG_WRITE;
break;
case O_RDWR:
- open_flags = PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE;
+ ppapi_flags = PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE;
break;
}
- if (mode & O_CREAT)
- open_flags |= PP_FILEOPENFLAG_CREATE;
- if (mode & O_TRUNC)
- open_flags |= PP_FILEOPENFLAG_TRUNCATE;
- if (mode & O_EXCL)
- open_flags |= PP_FILEOPENFLAG_EXCLUSIVE;
+ if (open_flags & O_CREAT)
+ ppapi_flags |= PP_FILEOPENFLAG_CREATE;
+ if (open_flags & O_TRUNC)
+ ppapi_flags |= PP_FILEOPENFLAG_TRUNCATE;
+ if (open_flags & O_EXCL)
+ ppapi_flags |= PP_FILEOPENFLAG_EXCLUSIVE;
- return open_flags;
+ return ppapi_flags;
}
} // namespace
@@ -169,7 +171,7 @@
return 0;
}
-Error MountNodeHtml5Fs::Read(size_t offs,
+Error MountNodeHtml5Fs::Read(const HandleAttr& attr,
void* buf,
size_t count,
int* out_bytes) {
@@ -180,7 +182,7 @@
int32_t result =
mount_->ppapi()->GetFileIoInterface()->Read(fileio_resource_,
- offs,
+ attr.offs,
static_cast<char*>(buf),
static_cast<int32_t>(count),
PP_BlockUntilComplete());
@@ -202,7 +204,7 @@
return 0;
}
-Error MountNodeHtml5Fs::Write(size_t offs,
+Error MountNodeHtml5Fs::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -213,7 +215,7 @@
int32_t result = mount_->ppapi()->GetFileIoInterface()
->Write(fileio_resource_,
- offs,
+ attr.offs,
static_cast<const char*>(buf),
static_cast<int32_t>(count),
PP_BlockUntilComplete());
@@ -259,8 +261,8 @@
fileref_resource_(fileref_resource),
fileio_resource_(0) {}
-Error MountNodeHtml5Fs::Init(int perm) {
- Error error = MountNode::Init(Mount::OpenModeToPermission(perm));
+Error MountNodeHtml5Fs::Init(int open_flags) {
+ Error error = MountNode::Init(Mount::OpenFlagsToPermission(open_flags));
if (error)
return error;
@@ -274,16 +276,15 @@
if (query_result == PP_OK && file_info.type == PP_FILETYPE_DIRECTORY)
return 0;
- fileio_resource_ = mount_->ppapi()->GetFileIoInterface()
- ->Create(mount_->ppapi()->GetInstance());
+ FileIoInterface* file_io = mount_->ppapi()->GetFileIoInterface();
+ fileio_resource_ = file_io->Create(mount_->ppapi()->GetInstance());
if (!fileio_resource_)
return ENOSYS;
- int32_t open_result =
- mount_->ppapi()->GetFileIoInterface()->Open(fileio_resource_,
- fileref_resource_,
- ModeToOpenFlags(perm),
- PP_BlockUntilComplete());
+ int32_t open_result = file_io->Open(fileio_resource_,
+ fileref_resource_,
+ OpenFlagsToPPAPIOpenFlags(open_flags),
+ PP_BlockUntilComplete());
if (open_result != PP_OK)
return PPErrorToErrno(open_result);
return 0;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.h b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.h
index 6a4c0f5..d8ef90b 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.h
@@ -23,9 +23,12 @@
size_t count,
int* out_bytes);
virtual Error GetStat(struct stat* stat);
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
virtual Error FTruncate(off_t size);
- virtual Error Write(size_t offs,
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
@@ -39,7 +42,7 @@
MountNodeHtml5Fs(Mount* mount, PP_Resource fileref);
// Init with standard open flags
- virtual Error Init(int o_mode);
+ virtual Error Init(int open_flags);
virtual void Destroy();
private:
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_http.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_http.cc
index ce299a1..a9ff7ca 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_http.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_http.cc
@@ -11,6 +11,7 @@
#include <ppapi/c/pp_errors.h>
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/mount_http.h"
#include "nacl_io/osinttypes.h"
@@ -215,7 +216,7 @@
return 0;
}
-Error MountNodeHttp::Read(size_t offs,
+Error MountNodeHttp::Read(const HandleAttr& attr,
void* buf,
size_t count,
int* out_bytes) {
@@ -229,15 +230,15 @@
return error;
}
- return ReadPartialFromCache(offs, buf, count, out_bytes);
+ return ReadPartialFromCache(attr.offs, buf, count, out_bytes);
}
- return DownloadPartial(offs, buf, count, out_bytes);
+ return DownloadPartial(attr.offs, buf, count, out_bytes);
}
Error MountNodeHttp::FTruncate(off_t size) { return ENOSYS; }
-Error MountNodeHttp::Write(size_t offs,
+Error MountNodeHttp::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_http.h b/native_client_sdk/src/libraries/nacl_io/mount_node_http.h
index c027ba6..f920907 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_http.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_http.h
@@ -25,9 +25,12 @@
size_t count,
int* out_bytes);
virtual Error GetStat(struct stat* stat);
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
virtual Error FTruncate(off_t size);
- virtual Error Write(size_t offs,
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc
index 5f195f1..bd983be 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc
@@ -9,6 +9,7 @@
#include <algorithm>
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/osstat.h"
#include "sdk_util/auto_lock.h"
@@ -29,7 +30,10 @@
MountNodeMem::~MountNodeMem() {}
-Error MountNodeMem::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error MountNodeMem::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
*out_bytes = 0;
AUTO_LOCK(node_lock_);
@@ -38,16 +42,16 @@
size_t size = stat_.st_size;
- if (offs + count > size) {
- count = size - offs;
+ if (attr.offs + count > size) {
+ count = size - attr.offs;
}
- memcpy(buf, &data_[offs], count);
+ memcpy(buf, &data_[attr.offs], count);
*out_bytes = static_cast<int>(count);
return 0;
}
-Error MountNodeMem::Write(size_t offs,
+Error MountNodeMem::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
@@ -57,12 +61,12 @@
if (count == 0)
return 0;
- if (count + offs > stat_.st_size) {
- Resize(count + offs);
- count = stat_.st_size - offs;
+ if (count + attr.offs > stat_.st_size) {
+ Resize(count + attr.offs);
+ count = stat_.st_size - attr.offs;
}
- memcpy(&data_[offs], buf, count);
+ memcpy(&data_[attr.offs], buf, count);
*out_bytes = static_cast<int>(count);
return 0;
}
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_mem.h b/native_client_sdk/src/libraries/nacl_io/mount_node_mem.h
index 6f0bc1f..ef2ba49 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_mem.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_mem.h
@@ -20,8 +20,11 @@
public:
// Normal read/write operations on a file
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs,
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.cc
index 20d3ab2..cc27a1f 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.cc
@@ -11,6 +11,7 @@
#include "nacl_io/event_emitter_pipe.h"
#include "nacl_io/ioctl.h"
+#include "nacl_io/kernel_handle.h"
namespace {
const size_t kDefaultPipeSize = 512 * 1024;
@@ -27,11 +28,11 @@
return pipe_.get();
}
-Error MountNodePipe::Read(size_t offs,
+Error MountNodePipe::Read(const HandleAttr& attr,
void *buf,
size_t count,
int* out_bytes) {
- int ms = (GetMode() & O_NONBLOCK) ? 0 : read_timeout_;
+ int ms = attr.IsBlocking() ? read_timeout_ : 0;
EventListenerLock wait(GetEventEmitter());
Error err = wait.WaitOnEvent(POLLIN, ms);
@@ -42,11 +43,11 @@
return 0;
}
-Error MountNodePipe::Write(size_t offs,
+Error MountNodePipe::Write(const HandleAttr& attr,
const void *buf,
size_t count,
int* out_bytes) {
- int ms = (GetMode() & O_NONBLOCK) ? 0 : write_timeout_;
+ int ms = attr.IsBlocking() ? write_timeout_ : 0;
EventListenerLock wait(GetEventEmitter());
Error err = wait.WaitOnEvent(POLLOUT, ms);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.h b/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.h
index b7ae7f5..a109af9 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_pipe.h
@@ -18,8 +18,9 @@
explicit MountNodePipe(Mount* mnt);
virtual EventEmitter* GetEventEmitter();
- virtual Error Read(size_t offs, void *buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs, const void *buf,
+ virtual Error Read(const HandleAttr& attr, void *buf, size_t count,
+ int* out_bytes);
+ virtual Error Write(const HandleAttr& attr, const void *buf,
size_t count, int* out_bytes);
protected:
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc
index abaf55b..0571659 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc
@@ -7,8 +7,8 @@
#include <errno.h>
#include <string.h>
-#include <sys/fcntl.h>
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/mount.h"
#include "nacl_io/mount_node_socket.h"
#include "nacl_io/pepper_interface.h"
@@ -28,6 +28,17 @@
stat_.st_mode |= S_IFSOCK;
}
+MountNodeSocket::MountNodeSocket(Mount* mount, PP_Resource socket)
+ : MountNodeStream(mount),
+ socket_resource_(socket),
+ local_addr_(0),
+ remote_addr_(0),
+ socket_flags_(0),
+ last_errno_(0) {
+ stat_.st_mode |= S_IFSOCK;
+ mount_->ppapi()->AddRefResource(socket_resource_);
+}
+
void MountNodeSocket::Destroy() {
if (socket_resource_)
mount_->ppapi()->ReleaseResource(socket_resource_);
@@ -53,18 +64,18 @@
// Normal read/write operations on a Socket are equivalent to
// send/recv with a flag value of 0.
-Error MountNodeSocket::Read(size_t offs,
+Error MountNodeSocket::Read(const HandleAttr& attr,
void* buf,
size_t count,
int* out_bytes) {
- return Recv(buf, count, 0, out_bytes);
+ return Recv(attr, buf, count, 0, out_bytes);
}
-Error MountNodeSocket::Write(size_t offs,
- const void* buf,
- size_t count,
- int* out_bytes) {
- return Send(buf, count, 0, out_bytes);
+Error MountNodeSocket::Write(const HandleAttr& attr,
+ const void* buf,
+ size_t count,
+ int* out_bytes) {
+ return Send(attr, buf, count, 0, out_bytes);
}
@@ -181,12 +192,16 @@
return memcmp(saddr1, saddr2, len1) == 0;
}
-
-Error MountNodeSocket::Accept(const struct sockaddr* addr, socklen_t len) {
+Error MountNodeSocket::Accept(const HandleAttr& attr,
+ PP_Resource* new_sock,
+ struct sockaddr* addr,
+ socklen_t* len) {
return ENOSYS;
}
-Error MountNodeSocket::Connect(const struct sockaddr* addr, socklen_t len) {
+Error MountNodeSocket::Connect(const HandleAttr& attr,
+ const struct sockaddr* addr,
+ socklen_t len) {
if (len < 1)
return EINVAL;
@@ -204,34 +219,72 @@
int optname,
void* optval,
socklen_t* len) {
- return EINVAL;
+ if (lvl != SOL_SOCKET)
+ return ENOPROTOOPT;
+
+ switch (optname) {
+ case SO_REUSEADDR: {
+ // SO_REUSEADDR is effectivly always on since we can't
+ // disable it with PPAPI sockets.
+ int value = 1;
+ int copy_bytes = std::min(sizeof(int), *len);
+ memcpy(optval, &value, copy_bytes);
+ *len = sizeof(int);
+ return 0;
+ }
+ case SO_ERROR: {
+ int copy_bytes = std::min(sizeof(int), *len);
+ memcpy(optval, &last_errno_, copy_bytes);
+ *len = sizeof(int);
+ last_errno_ = 0;
+ return 0;
+ }
+ }
+
+ return ENOPROTOOPT;
}
Error MountNodeSocket::SetSockOpt(int lvl,
int optname,
const void* optval,
socklen_t len) {
- return EINVAL;
+ if (lvl != SOL_SOCKET)
+ return ENOPROTOOPT;
+
+ switch (optname) {
+ case SO_REUSEADDR: {
+ // SO_REUSEADDR is effectivly always on since we can't
+ // disable it with PPAPI sockets. Just return success
+ // here regardless.
+ return 0;
+ }
+ }
+
+ return ENOPROTOOPT;
}
Error MountNodeSocket::Bind(const struct sockaddr* addr, socklen_t len) {
return EINVAL;
}
-
-Error MountNodeSocket::Recv(void* buf, size_t len, int flags, int* out_len) {
- return RecvFrom(buf, len, flags, NULL, 0, out_len);
+Error MountNodeSocket::Recv(const HandleAttr& attr,
+ void* buf,
+ size_t len,
+ int flags,
+ int* out_len) {
+ return RecvFrom(attr, buf, len, flags, NULL, 0, out_len);
}
-Error MountNodeSocket::RecvFrom(void* buf,
+Error MountNodeSocket::RecvFrom(const HandleAttr& attr,
+ void* buf,
size_t len,
int flags,
struct sockaddr* src_addr,
socklen_t* addrlen,
int* out_len) {
- PP_Resource addr;
- Error err = RecvHelper(buf, len, flags, &addr, out_len);
- if (0 != addr) {
+ PP_Resource addr = 0;
+ Error err = RecvHelper(attr, buf, len, flags, &addr, out_len);
+ if (0 == err && 0 != addr) {
if (src_addr)
*addrlen = ResourceToSockAddr(addr, *addrlen, src_addr);
@@ -241,7 +294,8 @@
return err;
}
-Error MountNodeSocket::RecvHelper(void* buf,
+Error MountNodeSocket::RecvHelper(const HandleAttr& attr,
+ void* buf,
size_t len,
int flags,
PP_Resource* addr,
@@ -250,7 +304,7 @@
return EBADF;
int ms = read_timeout_;
- if ((flags & MSG_DONTWAIT) || (GetMode() & O_NONBLOCK))
+ if ((flags & MSG_DONTWAIT) || !attr.IsBlocking())
ms = 0;
//TODO(noelallen) BUG=295177
@@ -273,15 +327,16 @@
return err;
}
-
-Error MountNodeSocket::Send(const void* buf,
- size_t len,
- int flags,
- int* out_len) {
- return SendHelper(buf, len, flags, remote_addr_, out_len);
+Error MountNodeSocket::Send(const HandleAttr& attr,
+ const void* buf,
+ size_t len,
+ int flags,
+ int* out_len) {
+ return SendHelper(attr, buf, len, flags, remote_addr_, out_len);
}
-Error MountNodeSocket::SendTo(const void* buf,
+Error MountNodeSocket::SendTo(const HandleAttr& attr,
+ const void* buf,
size_t len,
int flags,
const struct sockaddr* dest_addr,
@@ -291,16 +346,16 @@
return EDESTADDRREQ;
PP_Resource addr = SockAddrToResource(dest_addr, addrlen);
- if (addr) {
- Error err = SendHelper(buf, len, flags, addr, out_len);
- mount_->ppapi()->ReleaseResource(addr);
- return err;
- }
+ if (0 == addr)
+ return EINVAL;
- return EINVAL;
+ Error err = SendHelper(attr, buf, len, flags, addr, out_len);
+ mount_->ppapi()->ReleaseResource(addr);
+ return err;
}
-Error MountNodeSocket::SendHelper(const void* buf,
+Error MountNodeSocket::SendHelper(const HandleAttr& attr,
+ const void* buf,
size_t len,
int flags,
PP_Resource addr,
@@ -312,7 +367,7 @@
return ENOTCONN;
int ms = write_timeout_;
- if ((flags & MSG_DONTWAIT) || (GetMode() & O_NONBLOCK))
+ if ((flags & MSG_DONTWAIT) || !attr.IsBlocking())
ms = 0;
EventListenerLock wait(GetEventEmitter());
@@ -372,4 +427,4 @@
} // namespace nacl_io
-#endif // PROVIDES_SOCKET_API
\ No newline at end of file
+#endif // PROVIDES_SOCKET_API
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_socket.h b/native_client_sdk/src/libraries/nacl_io/mount_node_socket.h
index 5cd4ba2..7254c64 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_socket.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_socket.h
@@ -8,6 +8,7 @@
#include "nacl_io/ossocket.h"
#ifdef PROVIDES_SOCKET_API
+#include <sys/fcntl.h>
#include <ppapi/c/pp_errors.h>
#include <ppapi/c/pp_resource.h>
#include <ppapi/c/ppb_net_address.h>
@@ -28,27 +29,29 @@
class MountNodeSocket : public MountNodeStream {
public:
explicit MountNodeSocket(Mount* mount);
+ MountNodeSocket(Mount* mount, PP_Resource socket);
protected:
virtual void Destroy();
- virtual Error Init(int flags) = 0;
public:
// Normal read/write operations on a file (recv/send).
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
- virtual Error Write(size_t offs,
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes);
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
- // Unsuported Functions
- virtual Error Accept(const struct sockaddr* addr, socklen_t len);
- virtual Error Listen(int backlog);
virtual Error GetSockOpt(int lvl, int optname, void* optval, socklen_t* len);
virtual Error SetSockOpt(int lvl,
int optname,
const void* optval,
socklen_t len);
+
+ // Unsupported Functions
virtual Error Shutdown(int how);
virtual Error MMap(void* addr,
size_t length,
@@ -58,18 +61,35 @@
void** out_addr);
// Socket Functions.
+ virtual Error Accept(const HandleAttr& attr,
+ PP_Resource* new_sock,
+ struct sockaddr* addr,
+ socklen_t* len);
virtual Error Bind(const struct sockaddr* addr, socklen_t len);
- virtual Error Connect(const struct sockaddr* addr, socklen_t len);
- virtual Error Recv(void* buf, size_t len, int flags, int* out_len);
- virtual Error RecvFrom(void* buf,
+ virtual Error Connect(const HandleAttr& attr,
+ const struct sockaddr* addr,
+ socklen_t len);
+ virtual Error Listen(int backlog);
+ virtual Error Recv(const HandleAttr& attr,
+ void* buf,
+ size_t len,
+ int flags,
+ int* out_len);
+ virtual Error RecvFrom(const HandleAttr& attr,
+ void* buf,
size_t len,
int flags,
struct sockaddr* src_addr,
socklen_t* addrlen,
int* out_len);
- virtual Error Send(const void* buf, size_t len, int flags, int* out_len);
- virtual Error SendTo(const void* buf,
+ virtual Error Send(const HandleAttr& attr,
+ const void* buf,
+ size_t len,
+ int flags,
+ int* out_len);
+ virtual Error SendTo(const HandleAttr& attr,
+ const void* buf,
size_t len,
int flags,
const struct sockaddr* dest_addr,
@@ -80,21 +100,25 @@
virtual Error GetSockName(struct sockaddr* addr, socklen_t* len);
PP_Resource socket_resource() { return socket_resource_; }
+ PP_Resource remote_addr() { return remote_addr_; }
// Updates socket's state, recording last error.
void SetError_Locked(int pp_error_num);
+
protected:
// Wraps common error checks, timeouts, work pump for send.
- Error SendHelper(const void* buf,
+ Error SendHelper(const HandleAttr& attr,
+ const void* buf,
size_t len,
int flags,
PP_Resource addr,
int* out_len);
// Wraps common error checks, timeouts, work pump for recv.
- Error RecvHelper(void* buf,
+ Error RecvHelper(const HandleAttr& attr,
+ void* buf,
size_t len,
int flags,
PP_Resource* addr,
@@ -140,4 +164,4 @@
#endif // PROVIDES_SOCKET_API
-#endif // LIBRARIES_NACL_IO_MOUNT_NODE_SOCKET_H_
\ No newline at end of file
+#endif // LIBRARIES_NACL_IO_MOUNT_NODE_SOCKET_H_
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_stream.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_stream.cc
index c3cbc23..0623976 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_stream.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_stream.cc
@@ -23,9 +23,9 @@
stream_state_flags_(0) {
}
-Error MountNodeStream::Init(int perm) {
- MountNode::Init(perm);
- if (perm & O_NONBLOCK)
+Error MountNodeStream::Init(int open_flags) {
+ MountNode::Init(Mount::OpenFlagsToPermission(open_flags));
+ if (open_flags & O_NONBLOCK)
SetStreamFlags(SSF_NON_BLOCK);
return 0;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_stream.h b/native_client_sdk/src/libraries/nacl_io/mount_node_stream.h
index c855aff..fedd5ab 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_stream.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_stream.h
@@ -24,8 +24,11 @@
SSF_SENDING = 0x0002,
SSF_RECVING = 0x0004,
SSF_CLOSING = 0x0008,
+ SSF_LISTENING = 0x000f,
SSF_CAN_SEND = 0x0020,
SSF_CAN_RECV = 0x0040,
+ SSF_CAN_ACCEPT = 0x0080,
+ SSF_CAN_CONNECT = 0x00f0,
SSF_NON_BLOCK = 0x1000,
SSF_ERROR = 0x4000,
SSF_CLOSED = 0x8000
@@ -36,7 +39,7 @@
public:
explicit MountNodeStream(Mount* mnt);
- virtual Error Init(int perm);
+ virtual Error Init(int open_flags);
// Attempts to pump input and output
virtual void QueueInput();
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.cc
index bdc4b10..d34cf7c 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.cc
@@ -6,10 +6,12 @@
#include "nacl_io/ossocket.h"
#ifdef PROVIDES_SOCKET_API
+#include <assert.h>
#include <errno.h>
#include <string.h>
#include <algorithm>
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/mount_node_tcp.h"
#include "nacl_io/mount_stream.h"
#include "nacl_io/pepper_interface.h"
@@ -42,7 +44,6 @@
char* data_;
};
-
class TCPSendWork : public TCPWork {
public:
explicit TCPSendWork(const ScopedEventEmitterTCP& emitter)
@@ -58,9 +59,8 @@
// If not currently sending...
if (!stream->TestStreamFlags(SSF_SENDING)) {
- size_t tx_data_avail = emitter_->out_fifo()->ReadAvailable();
- int capped_len =
- static_cast<int32_t>(std::min(tx_data_avail, kMaxPacketSize));
+ size_t tx_data_avail = emitter_->BytesInOutputFIFO();
+ int capped_len = std::min(tx_data_avail, kMaxPacketSize);
if (capped_len == 0)
return false;
@@ -115,7 +115,7 @@
// If we are not currently receiving
if (!stream->TestStreamFlags(SSF_RECVING)) {
- size_t rx_space_avail = emitter_->in_fifo()->WriteAvailable();
+ size_t rx_space_avail = emitter_->SpaceInInputFIFO();
int capped_len =
static_cast<int32_t>(std::min(rx_space_avail, kMaxPacketSize));
@@ -125,9 +125,9 @@
stream->SetStreamFlags(SSF_RECVING);
data_ = new char[capped_len];
int err = TCPInterface()->Read(stream->socket_resource(),
- data_,
- capped_len,
- mount()->GetRunCompletion(this));
+ data_,
+ capped_len,
+ mount()->GetRunCompletion(this));
if (err == PP_OK_COMPLETIONPENDING)
return true;
@@ -145,6 +145,7 @@
if (stream) {
if (length_error > 0) {
emitter_->WriteIn_Locked(data_, length_error);
+ stream->ClearStreamFlags(SSF_RECVING);
stream->QueueInput();
} else {
stream->SetError_Locked(length_error);
@@ -153,6 +154,109 @@
}
};
+class TCPAcceptWork : public MountStream::Work {
+ public:
+ explicit TCPAcceptWork(MountStream* stream,
+ const ScopedEventEmitterTCP& emitter)
+ : MountStream::Work(stream),
+ emitter_(emitter) {}
+
+ TCPSocketInterface* TCPInterface() {
+ return mount()->ppapi()->GetTCPSocketInterface();
+ }
+
+ virtual bool Start(int32_t val) {
+ AUTO_LOCK(emitter_->GetLock());
+ MountNodeTCP* node = static_cast<MountNodeTCP*>(emitter_->stream());
+
+ // Does the stream exist, and can it accept?
+ if (NULL == node)
+ return false;
+
+ // If we are not currently accepting
+ if (!node->TestStreamFlags(SSF_LISTENING))
+ return false;
+
+ int err = TCPInterface()->Accept(node->socket_resource(),
+ &new_socket_,
+ mount()->GetRunCompletion(this));
+
+ if (err != PP_OK_COMPLETIONPENDING)
+ // Anything else, we should assume the socket has gone bad.
+ node->SetError_Locked(err);
+
+ return true;
+ }
+
+ virtual void Run(int32_t error) {
+ AUTO_LOCK(emitter_->GetLock());
+ MountNodeTCP* node = static_cast<MountNodeTCP*>(emitter_->stream());
+
+ if (node == NULL)
+ return;
+
+ if (error != PP_OK) {
+ node->SetError_Locked(error);
+ return;
+ }
+
+ emitter_->SetAcceptedSocket_Locked(new_socket_);
+ }
+
+ protected:
+ PP_Resource new_socket_;
+ ScopedEventEmitterTCP emitter_;
+};
+
+class TCPConnectWork : public MountStream::Work {
+ public:
+ explicit TCPConnectWork(MountStream* stream,
+ const ScopedEventEmitterTCP& emitter)
+ : MountStream::Work(stream),
+ emitter_(emitter) {}
+
+ TCPSocketInterface* TCPInterface() {
+ return mount()->ppapi()->GetTCPSocketInterface();
+ }
+
+ virtual bool Start(int32_t val) {
+ AUTO_LOCK(emitter_->GetLock());
+ MountNodeTCP* node = static_cast<MountNodeTCP*>(emitter_->stream());
+
+ // Does the stream exist, and can it connect?
+ if (NULL == node)
+ return false;
+
+ int err = TCPInterface()->Connect(node->socket_resource(),
+ node->remote_addr(),
+ mount()->GetRunCompletion(this));
+
+ if (err != PP_OK_COMPLETIONPENDING)
+ // Anything else, we should assume the socket has gone bad.
+ node->SetError_Locked(err);
+
+ return true;
+ }
+
+ virtual void Run(int32_t error) {
+ AUTO_LOCK(emitter_->GetLock());
+ MountNodeTCP* node = static_cast<MountNodeTCP*>(emitter_->stream());
+
+ if (node == NULL)
+ return;
+
+ if (error != PP_OK) {
+ node->ConnectFailed_Locked();
+ node->SetError_Locked(error);
+ return;
+ }
+
+ node->ConnectDone_Locked();
+ }
+
+ protected:
+ ScopedEventEmitterTCP emitter_;
+};
MountNodeTCP::MountNodeTCP(Mount* mount)
: MountNodeSocket(mount),
@@ -160,36 +264,100 @@
emitter_->AttachStream(this);
}
+MountNodeTCP::MountNodeTCP(Mount* mount, PP_Resource socket)
+ : MountNodeSocket(mount, socket),
+ emitter_(new EventEmitterTCP(kDefaultFifoSize, kDefaultFifoSize)) {
+ emitter_->AttachStream(this);
+}
+
void MountNodeTCP::Destroy() {
emitter_->DetachStream();
MountNodeSocket::Destroy();
}
-Error MountNodeTCP::Init(int flags) {
+Error MountNodeTCP::Init(int open_flags) {
+ Error err = MountNodeSocket::Init(open_flags);
+ if (err != 0)
+ return err;
+
if (TCPInterface() == NULL)
return EACCES;
- socket_resource_ = TCPInterface()->Create(mount_->ppapi()->GetInstance());
- if (0 == socket_resource_)
- return EACCES;
+ SetStreamFlags(SSF_CAN_CONNECT);
+
+ if (socket_resource_ != 0) {
+ // TCP sockets that are contructed with an existing socket_resource_
+ // are those that generated from calls to Accept() and therefore are
+ // already connected.
+ remote_addr_ = TCPInterface()->GetRemoteAddress(socket_resource_);
+ ConnectDone_Locked();
+ } else {
+ socket_resource_ = TCPInterface()->Create(mount_->ppapi()->GetInstance());
+ if (0 == socket_resource_)
+ return EACCES;
+ }
return 0;
}
-EventEmitterTCP* MountNodeTCP::GetEventEmitter() {
+EventEmitter* MountNodeTCP::GetEventEmitter() {
return emitter_.get();
}
+void MountNodeTCP::QueueAccept() {
+ MountStream::Work* work = new TCPAcceptWork(mount_stream(), emitter_);
+ mount_stream()->EnqueueWork(work);
+}
+
+void MountNodeTCP::QueueConnect() {
+ MountStream::Work* work = new TCPConnectWork(mount_stream(), emitter_);
+ mount_stream()->EnqueueWork(work);
+}
+
void MountNodeTCP::QueueInput() {
- TCPRecvWork* work = new TCPRecvWork(emitter_);
+ MountStream::Work* work = new TCPRecvWork(emitter_);
mount_stream()->EnqueueWork(work);
}
void MountNodeTCP::QueueOutput() {
- TCPSendWork* work = new TCPSendWork(emitter_);
+ MountStream::Work* work = new TCPSendWork(emitter_);
mount_stream()->EnqueueWork(work);
}
+Error MountNodeTCP::Accept(const HandleAttr& attr,
+ PP_Resource* out_sock,
+ struct sockaddr* addr,
+ socklen_t* len) {
+ EventListenerLock wait(GetEventEmitter());
+
+ if (!TestStreamFlags(SSF_LISTENING))
+ return EINVAL;
+
+ // Either block forever or not at all
+ int ms = attr.IsBlocking() ? -1 : 0;
+
+ Error err = wait.WaitOnEvent(POLLIN, ms);
+
+ if (ETIMEDOUT == err)
+ return EWOULDBLOCK;
+
+ int s = emitter_->GetAcceptedSocket_Locked();
+ // Non-blocking case.
+ if (s == 0)
+ return EAGAIN;
+
+ // Consume the new socket and start listening for the next one
+ *out_sock = s;
+ emitter_->ClearEvents_Locked(POLLIN);
+
+ // Set the out paramaters
+ PP_Resource remote_addr = TCPInterface()->GetRemoteAddress(*out_sock);
+ *len = ResourceToSockAddr(remote_addr, *len, addr);
+ mount_->ppapi()->ReleaseResource(remote_addr);
+
+ QueueAccept();
+ return 0;
+}
// We can not bind a client socket with PPAPI. For now we ignore the
// bind but report the correct address later, just in case someone is
@@ -198,58 +366,101 @@
Error MountNodeTCP::Bind(const struct sockaddr* addr, socklen_t len) {
AUTO_LOCK(node_lock_);
- if (0 == socket_resource_)
- return EBADF;
-
/* Only bind once. */
if (local_addr_ != 0)
return EINVAL;
- /* Lie, we won't know until we connect. */
+ local_addr_ = SockAddrToResource(addr, len);
+ int err = TCPInterface()->Bind(socket_resource_,
+ local_addr_,
+ PP_BlockUntilComplete());
+
+ // If we fail, release the local addr resource
+ if (err != PP_OK) {
+ mount_->ppapi()->ReleaseResource(local_addr_);
+ local_addr_ = 0;
+ return PPErrorToErrno(err);
+ }
+
return 0;
}
-Error MountNodeTCP::Connect(const struct sockaddr* addr, socklen_t len) {
- AUTO_LOCK(node_lock_);
+Error MountNodeTCP::Connect(const HandleAttr& attr,
+ const struct sockaddr* addr,
+ socklen_t len) {
+ EventListenerLock wait(GetEventEmitter());
- if (0 == socket_resource_)
- return EBADF;
+ if (TestStreamFlags(SSF_CONNECTING))
+ return EALREADY;
- if (remote_addr_ != 0)
+ if (remote_addr_ != 0) {
return EISCONN;
+ }
remote_addr_ = SockAddrToResource(addr, len);
if (0 == remote_addr_)
return EINVAL;
- int err = TCPInterface()->Connect(socket_resource_,
- remote_addr_,
- PP_BlockUntilComplete());
+ int ms = attr.IsBlocking() ? -1 : 0;
+
+ SetStreamFlags(SSF_CONNECTING);
+ QueueConnect();
+
+ Error err = wait.WaitOnEvent(POLLOUT, ms);
+ if (ETIMEDOUT == err)
+ return EINPROGRESS;
// If we fail, release the dest addr resource
- if (err != PP_OK) {
- mount_->ppapi()->ReleaseResource(remote_addr_);
- remote_addr_ = 0;
- return PPErrorToErrno(err);
+ if (err != 0) {
+ ConnectFailed_Locked();
+ return err;
}
- local_addr_ = TCPInterface()->GetLocalAddress(socket_resource_);
- mount_->ppapi()->AddRefResource(local_addr_);
-
- // Now that we are connected, we can start sending and receiving.
- SetStreamFlags(SSF_CAN_SEND | SSF_CAN_RECV);
-
- // Begin the input pump
- QueueInput();
+ ConnectDone_Locked();
return 0;
}
+void MountNodeTCP::ConnectDone_Locked() {
+ local_addr_ = TCPInterface()->GetLocalAddress(socket_resource_);
+
+ // Now that we are connected, we can start sending and receiving.
+ ClearStreamFlags(SSF_CONNECTING | SSF_CAN_CONNECT);
+ SetStreamFlags(SSF_CAN_SEND | SSF_CAN_RECV);
+
+ emitter_->ConnectDone_Locked();
+
+ // Begin the input pump
+ QueueInput();
+}
+
+void MountNodeTCP::ConnectFailed_Locked() {
+ mount_->ppapi()->ReleaseResource(remote_addr_);
+ remote_addr_ = 0;
+}
+
+Error MountNodeTCP::Listen(int backlog) {
+ AUTO_LOCK(node_lock_);
+ if (0 == local_addr_)
+ return EINVAL;
+
+ int err = TCPInterface()->Listen(socket_resource_,
+ backlog,
+ PP_BlockUntilComplete());
+ if (err != PP_OK)
+ return PPErrorToErrno(err);
+
+ ClearStreamFlags(SSF_CAN_CONNECT);
+ SetStreamFlags(SSF_LISTENING);
+ QueueAccept();
+ return 0;
+}
Error MountNodeTCP::Recv_Locked(void* buf,
size_t len,
PP_Resource* out_addr,
int* out_len) {
- *out_len = emitter_->in_fifo()->Read(buf, len);
+ assert(emitter_.get());
+ *out_len = emitter_->ReadIn_Locked((char*)buf, len);
*out_addr = remote_addr_;
// Ref the address copy we pass back.
@@ -262,11 +473,12 @@
size_t len,
PP_Resource,
int* out_len) {
- *out_len = emitter_->out_fifo()->Write(buf, len);
+ assert(emitter_.get());
+ *out_len = emitter_->WriteOut_Locked((char*)buf, len);
return 0;
}
} // namespace nacl_io
-#endif // PROVIDES_SOCKET_API
\ No newline at end of file
+#endif // PROVIDES_SOCKET_API
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.h b/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.h
index 077276f..afd593a 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_tcp.h
@@ -20,19 +20,32 @@
class MountNodeTCP : public MountNodeSocket {
public:
explicit MountNodeTCP(Mount* mount);
+ MountNodeTCP(Mount* mount, PP_Resource socket);
protected:
- virtual Error Init(int flags);
+ virtual Error Init(int open_flags);
virtual void Destroy();
public:
- virtual EventEmitterTCP* GetEventEmitter();
+ virtual EventEmitter* GetEventEmitter();
+ virtual void QueueAccept();
+ virtual void QueueConnect();
virtual void QueueInput();
virtual void QueueOutput();
+ virtual Error Accept(const HandleAttr& attr,
+ PP_Resource* out_sock,
+ struct sockaddr* addr,
+ socklen_t* len);
virtual Error Bind(const struct sockaddr* addr, socklen_t len);
- virtual Error Connect(const struct sockaddr* addr, socklen_t len);
+ virtual Error Listen(int backlog);
+ virtual Error Connect(const HandleAttr& attr,
+ const struct sockaddr* addr,
+ socklen_t len);
+
+ void ConnectDone_Locked();
+ void ConnectFailed_Locked();
protected:
virtual Error Recv_Locked(void* buf,
@@ -46,6 +59,7 @@
int* out_len);
ScopedEventEmitterTCP emitter_;
+ PP_Resource accepted_socket_;
};
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
index 4b6c565..af9b754 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
@@ -15,6 +15,7 @@
#include <algorithm>
#include "nacl_io/ioctl.h"
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/mount.h"
#include "nacl_io/pepper_interface.h"
#include "sdk_util/auto_lock.h"
@@ -76,11 +77,10 @@
return emitter_.get();
}
-Error MountNodeTty::Write(size_t offs,
- const void* buf,
- size_t count,
- int* out_bytes) {
-
+Error MountNodeTty::Write(const HandleAttr& attr,
+ const void* buf,
+ size_t count,
+ int* out_bytes) {
AUTO_LOCK(output_lock_);
*out_bytes = 0;
@@ -102,7 +102,10 @@
}
-Error MountNodeTty::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+Error MountNodeTty::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
EventListenerLock wait(GetEventEmitter());
*out_bytes = 0;
@@ -151,7 +154,8 @@
Error MountNodeTty::Echo(const char* string, int count) {
int wrote;
- Error error = Write(0, string, count, &wrote);
+ HandleAttr data;
+ Error error = Write(data, string, count, &wrote);
if (error != 0 || wrote != count) {
// TOOD(sbc): Do something more useful in response to a
// failure to echo.
@@ -228,9 +232,10 @@
return 0;
}
-Error MountNodeTty::Ioctl(int request, char* arg) {
+Error MountNodeTty::VIoctl(int request, va_list args) {
switch (request) {
case TIOCNACLOUTPUT: {
+ struct tioc_nacl_output* arg = va_arg(args, struct tioc_nacl_output*);
AUTO_LOCK(output_lock_);
if (arg == NULL) {
output_handler_.handler = NULL;
@@ -238,18 +243,18 @@
}
if (output_handler_.handler != NULL)
return EALREADY;
- output_handler_ = *reinterpret_cast<tioc_nacl_output*>(arg);
+ output_handler_ = *arg;
return 0;
}
case TIOCNACLINPUT: {
// This ioctl is used to deliver data from the user to this tty node's
// input buffer.
struct tioc_nacl_input_string* message =
- reinterpret_cast<struct tioc_nacl_input_string*>(arg);
+ va_arg(args, struct tioc_nacl_input_string*);
return ProcessInput(message);
}
case TIOCSWINSZ: {
- struct winsize* size = reinterpret_cast<struct winsize*>(arg);
+ struct winsize* size = va_arg(args, struct winsize*);
{
AUTO_LOCK(node_lock_);
rows_ = size->ws_row;
@@ -266,7 +271,7 @@
return 0;
}
case TIOCGWINSZ: {
- struct winsize* size = reinterpret_cast<struct winsize*>(arg);
+ struct winsize* size = va_arg(args, struct winsize*);
size->ws_row = rows_;
size->ws_col = cols_;
return 0;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_tty.h b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.h
index 1c8e65d..b47396f 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_tty.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.h
@@ -23,15 +23,14 @@
virtual EventEmitter* GetEventEmitter();
- virtual Error Ioctl(int request,
- char* arg);
+ virtual Error VIoctl(int request, va_list args);
- virtual Error Read(size_t offs,
+ virtual Error Read(const HandleAttr& attr,
void* buf,
size_t count,
int* out_bytes);
- virtual Error Write(size_t offs,
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_udp.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_udp.cc
index cb8c23e..29886b1 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_udp.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_udp.cc
@@ -170,7 +170,11 @@
return emitter_.get();
}
-Error MountNodeUDP::Init(int flags) {
+Error MountNodeUDP::Init(int open_flags) {
+ Error err = MountNodeSocket::Init(open_flags);
+ if (err != 0)
+ return err;
+
if (UDPInterface() == NULL)
return EACCES;
@@ -219,7 +223,9 @@
return 0;
}
-Error MountNodeUDP::Connect(const struct sockaddr* addr, socklen_t len) {
+Error MountNodeUDP::Connect(const HandleAttr& attr,
+ const struct sockaddr* addr,
+ socklen_t len) {
if (0 == socket_resource_)
return EBADF;
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_udp.h b/native_client_sdk/src/libraries/nacl_io/mount_node_udp.h
index 2fef513..95f2889 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_udp.h
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_udp.h
@@ -22,7 +22,7 @@
explicit MountNodeUDP(Mount* mount);
protected:
- virtual Error Init(int flags);
+ virtual Error Init(int open_flags);
virtual void Destroy();
public:
@@ -32,7 +32,9 @@
virtual void QueueOutput();
virtual Error Bind(const struct sockaddr* addr, socklen_t len);
- virtual Error Connect(const struct sockaddr* addr, socklen_t len);
+ virtual Error Connect(const HandleAttr& attr,
+ const struct sockaddr* addr,
+ socklen_t len);
protected:
virtual Error Recv_Locked(void* buf,
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_passthrough.cc b/native_client_sdk/src/libraries/nacl_io/mount_passthrough.cc
index a84d4c5..f4c9951 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_passthrough.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_passthrough.cc
@@ -3,7 +3,10 @@
// found in the LICENSE file.
#include "nacl_io/mount_passthrough.h"
+
#include <errno.h>
+
+#include "nacl_io/kernel_handle.h"
#include "nacl_io/kernel_wrap_real.h"
namespace nacl_io {
@@ -24,11 +27,14 @@
public:
// Normal read/write operations on a file
- virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+ virtual Error Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
*out_bytes = 0;
off_t new_offset;
- int err = _real_lseek(real_fd_, offs, 0, &new_offset);
+ int err = _real_lseek(real_fd_, attr.offs, 0, &new_offset);
if (err)
return err;
@@ -41,14 +47,14 @@
return 0;
}
- virtual Error Write(size_t offs,
+ virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
*out_bytes = 0;
off_t new_offset;
- int err = _real_lseek(real_fd_, offs, 0, &new_offset);
+ int err = _real_lseek(real_fd_, attr.offs, 0, &new_offset);
if (err)
return err;
diff --git a/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h b/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h
index 95f802a..c667802 100644
--- a/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h
+++ b/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h
@@ -115,6 +115,7 @@
struct PP_NetAddress_IPv4*)
METHOD2(NetAddressInterface, PP_Bool, DescribeAsIPv6Address, PP_Resource,
struct PP_NetAddress_IPv6*)
+ METHOD2(NetAddressInterface, PP_Var, DescribeAsString, PP_Resource, PP_Bool)
END_INTERFACE(NetAddressInterface, PPB_NetAddress_1_0)
BEGIN_INTERFACE(URLLoaderInterface, PPB_URLLoader_1_0,
@@ -141,9 +142,15 @@
PP_URLResponseProperty)
END_INTERFACE(URLResponseInfoInterface, PPB_URLResponseInfo_1_0)
-BEGIN_INTERFACE(TCPSocketInterface, PPB_TCPSocket_1_0,
- PPB_TCPSOCKET_INTERFACE_1_0)
+BEGIN_INTERFACE(TCPSocketInterface, PPB_TCPSocket_1_1,
+ PPB_TCPSOCKET_INTERFACE_1_1)
METHOD1(TCPSocketInterface, PP_Resource, Create, PP_Instance)
+ METHOD3(TCPSocketInterface, int32_t, Bind, PP_Resource, PP_Resource,
+ PP_CompletionCallback)
+ METHOD3(TCPSocketInterface, int32_t, Listen, PP_Resource, int32_t,
+ PP_CompletionCallback)
+ METHOD3(TCPSocketInterface, int32_t, Accept, PP_Resource, PP_Resource*,
+ PP_CompletionCallback)
METHOD1(TCPSocketInterface, PP_Bool, IsTCPSocket, PP_Resource)
METHOD3(TCPSocketInterface, int32_t, Connect, PP_Resource, PP_Resource,
PP_CompletionCallback)
@@ -156,7 +163,7 @@
METHOD1(TCPSocketInterface, void, Close, PP_Resource)
METHOD4(TCPSocketInterface, int32_t, SetOption, PP_Resource,
PP_TCPSocket_Option, PP_Var, PP_CompletionCallback)
-END_INTERFACE(TCPSocketInterface, PPB_TCPSocket_1_0)
+END_INTERFACE(TCPSocketInterface, PPB_TCPSocket_1_1)
BEGIN_INTERFACE(UDPSocketInterface, PPB_UDPSocket_1_0,
PPB_UDPSOCKET_INTERFACE_1_0)
diff --git a/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc b/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc
index 53a8a0f..3fcc7a0 100644
--- a/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc
+++ b/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc
@@ -3,11 +3,13 @@
// found in the LICENSE file.
#include "nacl_io/real_pepper_interface.h"
+
#include <assert.h>
#include <stdio.h>
-
#include <ppapi/c/pp_errors.h>
+#include "nacl_io/dbgprint.h"
+
namespace nacl_io {
#include "nacl_io/pepper/undef_macros.h"
@@ -79,10 +81,15 @@
#include "nacl_io/pepper/undef_macros.h"
#include "nacl_io/pepper/define_empty_macros.h"
#undef BEGIN_INTERFACE
-#define BEGIN_INTERFACE(BaseClass, PPInterface, InterfaceString) \
- BaseClass##interface_ = new Real##BaseClass( \
- static_cast<const PPInterface*>( \
- get_browser_interface(InterfaceString)));
+#define BEGIN_INTERFACE(BaseClass, PPInterface, InterfaceString) { \
+ const PPInterface* iface = static_cast<const PPInterface*>( \
+ get_browser_interface(InterfaceString)); \
+ BaseClass##interface_ = NULL; \
+ if (iface) \
+ BaseClass##interface_ = new Real##BaseClass(iface); \
+ else \
+ dbgprintf("nacl_io: interface missing: %s\n", InterfaceString); \
+ }
#include "nacl_io/pepper/all_interfaces.h"
}
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/fchmod.c b/native_client_sdk/src/libraries/nacl_io/syscalls/fchmod.c
new file mode 100644
index 0000000..1958f15
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/fchmod.c
@@ -0,0 +1,10 @@
+/* Copyright (c) 2013 The Chromium 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 "nacl_io/kernel_intercept.h"
+#include "nacl_io/kernel_wrap.h"
+
+int fchmod(int fd, mode_t mode) {
+ return ki_fchmod(fd, mode);
+}
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/fcntl.c b/native_client_sdk/src/libraries/nacl_io/syscalls/fcntl.c
index e96ed38..11f7182 100644
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/fcntl.c
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/fcntl.c
@@ -10,7 +10,7 @@
int fcntl(int fd, int cmd, ...) {
va_list ap;
va_start(ap, cmd);
- char* arg = va_arg(ap, char*);
+ int rtn = ki_fcntl(fd, cmd, ap);
va_end(ap);
- return ki_fcntl(fd, cmd, arg);
+ return rtn;
}
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/ioctl.c b/native_client_sdk/src/libraries/nacl_io/syscalls/ioctl.c
index c1cd7d0..472eed2 100644
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/ioctl.c
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/ioctl.c
@@ -6,11 +6,12 @@
#include "nacl_io/kernel_intercept.h"
#include "nacl_io/kernel_wrap.h"
+#include "nacl_io/dbgprint.h"
int ioctl(int fd, unsigned long request, ...) {
va_list ap;
va_start(ap, request);
- char* arg = va_arg(ap, char*);
+ int rtn = ki_ioctl(fd, request, ap);
va_end(ap);
- return ki_ioctl(fd, request, arg);
+ return rtn;
}