summaryrefslogtreecommitdiff
path: root/native_client_sdk
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2013-08-12 14:20:17 +0100
committerBen Murdoch <benm@google.com>2013-08-12 14:20:17 +0100
commitba5b9a6411cb1792fd21f0a078d7a25cd1ceec16 (patch)
treeaa3b1013e823cb7bdee9ece936928292f57b31f4 /native_client_sdk
parentf7fa989080f1e63c6a8aa24d5434922d52d9f51e (diff)
downloadchromium_org-ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16.tar.gz
Merge from Chromium at DEPS revision r216972
This commit was generated by merge_to_master.py. Change-Id: I01cb28d94e3fcf99e3624d75cafa50d929787ddd
Diffstat (limited to 'native_client_sdk')
-rwxr-xr-xnative_client_sdk/src/build_tools/build_sdk.py15
-rw-r--r--native_client_sdk/src/build_tools/sdk_files.list33
-rw-r--r--native_client_sdk/src/examples/common.js13
-rw-r--r--native_client_sdk/src/examples/demo/earth/earth.cc11
-rw-r--r--native_client_sdk/src/examples/demo/flock/flock.cc3
-rw-r--r--native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c1
-rw-r--r--native_client_sdk/src/examples/tutorial/dlopen/dlopen.cc1
-rw-r--r--native_client_sdk/src/libraries/nacl_io/host_resolver.cc49
-rw-r--r--native_client_sdk/src/libraries/nacl_io/host_resolver.h2
-rw-r--r--native_client_sdk/src/libraries/nacl_io/include/sys/mount.h19
-rw-r--r--native_client_sdk/src/libraries/nacl_io/include/sys/termios.h6
-rw-r--r--native_client_sdk/src/libraries/nacl_io/include/sys/utsname.h12
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc8
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_intercept.h2
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc8
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_proxy.h2
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_wrap.h2
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_wrap_glibc.cc99
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_wrap_newlib.cc112
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h1
-rw-r--r--native_client_sdk/src/libraries/nacl_io/library.dsc41
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_dev.cc123
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_node_char.h21
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc271
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_node_tty.h60
-rw-r--r--native_client_sdk/src/libraries/nacl_io/nacl_io.h19
-rw-r--r--native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h1
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/accept.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/bind.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/connect.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/gethostbyname.c16
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/getpeername.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/getsockname.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/getsockopt.c15
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/herror.c19
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc54
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/htonl.c23
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/htons.c21
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc6
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc6
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/listen.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/ntohl.c21
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/ntohs.c19
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/recv.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/recvfrom.c15
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/recvmsg.c10
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/send.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/sendmsg.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/sendto.c15
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/setsockopt.c15
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/shutdown.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/socket.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io/syscalls/socketpair.c14
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.h2
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/kernel_wrap_test.cc10
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/mount_test.cc2
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/socket_test.cc56
-rw-r--r--native_client_sdk/src/libraries/third_party/newlib-extras/README.chromium3
-rw-r--r--native_client_sdk/src/libraries/third_party/newlib-extras/arpa/inet.h15
-rw-r--r--native_client_sdk/src/libraries/third_party/newlib-extras/netinet/in.h7
-rw-r--r--native_client_sdk/src/libraries/third_party/newlib-extras/netinet/tcp.h167
-rw-r--r--native_client_sdk/src/tools/common.mk6
-rw-r--r--native_client_sdk/src/tools/nacl_gcc.mk19
-rw-r--r--native_client_sdk/src/tools/nacl_llvm.mk43
64 files changed, 1236 insertions, 452 deletions
diff --git a/native_client_sdk/src/build_tools/build_sdk.py b/native_client_sdk/src/build_tools/build_sdk.py
index 190e5c33f7..37626fadce 100755
--- a/native_client_sdk/src/build_tools/build_sdk.py
+++ b/native_client_sdk/src/build_tools/build_sdk.py
@@ -54,7 +54,7 @@ import oshelpers
CYGTAR = os.path.join(NACL_DIR, 'build', 'cygtar.py')
NACLPORTS_URL = 'https://naclports.googlecode.com/svn/trunk/src'
-NACLPORTS_REV = 774
+NACLPORTS_REV = 850
GYPBUILD_DIR = 'gypbuild'
@@ -186,6 +186,18 @@ def BuildStepCopyTextFiles(pepperdir, pepper_ver, chrome_revision,
open(os.path.join(pepperdir, 'README'), 'w').write(readme_text)
+def PrunePNaClToolchain(root):
+ dirs_to_prune = [
+ 'newlib/lib-bc-x86-64',
+ 'newlib/usr-bc-x86-64'
+ # TODO(sbc): remove this once its really not needed.
+ # Currently we seem to rely on it at least for <bits/stat.h>
+ #'newlib/sysroot',
+ ]
+ for dirname in dirs_to_prune:
+ buildbot_common.RemoveDir(os.path.join(root, dirname))
+
+
def BuildStepUntarToolchains(pepperdir, arch, toolchains):
buildbot_common.BuildStep('Untar Toolchains')
platform = getos.GetPlatform()
@@ -236,6 +248,7 @@ def BuildStepUntarToolchains(pepperdir, arch, toolchains):
# Then rename/move it to the pepper toolchain directory
pnacldir = os.path.join(pepperdir, 'toolchain', tcname + '_pnacl')
buildbot_common.Move(tmpdir, pnacldir)
+ PrunePNaClToolchain(pnacldir)
buildbot_common.RemoveDir(tmpdir)
diff --git a/native_client_sdk/src/build_tools/sdk_files.list b/native_client_sdk/src/build_tools/sdk_files.list
index f4e890a9ab..a210f4ab48 100644
--- a/native_client_sdk/src/build_tools/sdk_files.list
+++ b/native_client_sdk/src/build_tools/sdk_files.list
@@ -314,7 +314,6 @@ include/KHR/khrplatform.h
include/nacl_io/error.h
include/nacl_io/event_emitter.h
include/nacl_io/event_listener.h
-include/nacl_io/error.h
include/nacl_io/host_resolver.h
include/nacl_io/inode_pool.h
include/nacl_io/ioctl.h
@@ -331,10 +330,12 @@ include/nacl_io/mount_html5fs.h
include/nacl_io/mount_http.h
include/nacl_io/mount_mem.h
include/nacl_io/mount_node.h
+include/nacl_io/mount_node_char.h
include/nacl_io/mount_node_dir.h
include/nacl_io/mount_node_html5fs.h
include/nacl_io/mount_node_http.h
include/nacl_io/mount_node_mem.h
+include/nacl_io/mount_node_tty.h
include/nacl_io/mount_passthrough.h
include/nacl_io/nacl_io.h
include/nacl_io/osdirent.h
@@ -357,8 +358,10 @@ include/nacl_io/typed_mount_factory.h
include/newlib/arpa/inet.h
include/newlib/netdb.h
include/newlib/netinet/in.h
+include/newlib/netinet/tcp.h
include/newlib/netinet6/in6.h
include/newlib/poll.h
+include/newlib/sys/mount.h
include/newlib/sys/select.h
include/newlib/sys/socket.h
include/newlib/sys/termios.h
@@ -366,8 +369,10 @@ include/newlib/sys/utsname.h
include/pnacl/arpa/inet.h
include/pnacl/netdb.h
include/pnacl/netinet/in.h
+include/pnacl/netinet/tcp.h
include/pnacl/netinet6/in6.h
include/pnacl/poll.h
+include/pnacl/sys/mount.h
include/pnacl/sys/select.h
include/pnacl/sys/socket.h
include/pnacl/sys/termios.h
@@ -612,7 +617,6 @@ include/win/poll.h
[win]include/win/pthread.h
[win]include/win/sched.h
[win]include/win/semaphore.h
-
[linux]lib/${PLATFORM}_host/Debug/libgmock.a
[linux]lib/${PLATFORM}_host/Debug/libgtest.a
[linux]lib/${PLATFORM}_host/Debug/libjsoncpp.a
@@ -858,33 +862,58 @@ src/nacl_io/mount_node_dir.cc
src/nacl_io/mount_node_html5fs.cc
src/nacl_io/mount_node_http.cc
src/nacl_io/mount_node_mem.cc
+src/nacl_io/mount_node_tty.cc
src/nacl_io/mount_passthrough.cc
src/nacl_io/nacl_io.cc
src/nacl_io/path.cc
src/nacl_io/pepper_interface.cc
src/nacl_io/real_pepper_interface.cc
+src/nacl_io/syscalls/accept.c
src/nacl_io/syscalls/access.c
+src/nacl_io/syscalls/bind.c
src/nacl_io/syscalls/chdir.c
src/nacl_io/syscalls/chmod.c
src/nacl_io/syscalls/chown.c
+src/nacl_io/syscalls/connect.c
src/nacl_io/syscalls/fchown.c
src/nacl_io/syscalls/fsync.c
src/nacl_io/syscalls/ftruncate.c
src/nacl_io/syscalls/getcwd.c
src/nacl_io/syscalls/getdents.c
+src/nacl_io/syscalls/gethostbyname.c
+src/nacl_io/syscalls/getpeername.c
+src/nacl_io/syscalls/getsockname.c
+src/nacl_io/syscalls/getsockopt.c
src/nacl_io/syscalls/getwd.c
+src/nacl_io/syscalls/herror.c
+src/nacl_io/syscalls/hstrerror.cc
+src/nacl_io/syscalls/htonl.c
+src/nacl_io/syscalls/htons.c
src/nacl_io/syscalls/inet_ntoa.cc
src/nacl_io/syscalls/inet_ntop.cc
src/nacl_io/syscalls/ioctl.c
src/nacl_io/syscalls/isatty.c
src/nacl_io/syscalls/lchown.c
src/nacl_io/syscalls/link.c
+src/nacl_io/syscalls/listen.c
src/nacl_io/syscalls/mkdir.c
src/nacl_io/syscalls/mount.c
+src/nacl_io/syscalls/ntohl.c
+src/nacl_io/syscalls/ntohs.c
src/nacl_io/syscalls/poll.c
+src/nacl_io/syscalls/recv.c
+src/nacl_io/syscalls/recvfrom.c
+src/nacl_io/syscalls/recvmsg.c
src/nacl_io/syscalls/remove.c
src/nacl_io/syscalls/rmdir.c
src/nacl_io/syscalls/select.c
+src/nacl_io/syscalls/send.c
+src/nacl_io/syscalls/sendmsg.c
+src/nacl_io/syscalls/sendto.c
+src/nacl_io/syscalls/setsockopt.c
+src/nacl_io/syscalls/shutdown.c
+src/nacl_io/syscalls/socket.c
+src/nacl_io/syscalls/socketpair.c
src/nacl_io/syscalls/tcflush.c
src/nacl_io/syscalls/tcgetattr.c
src/nacl_io/syscalls/tcsetattr.c
diff --git a/native_client_sdk/src/examples/common.js b/native_client_sdk/src/examples/common.js
index efa140c5bc..51adb54157 100644
--- a/native_client_sdk/src/examples/common.js
+++ b/native_client_sdk/src/examples/common.js
@@ -6,6 +6,10 @@
// string.
var isTest = false;
+// Set to true when loading a "Release" NaCl module, false when loading a
+// "Debug" NaCl module.
+var isRelease = false;
+
// Javascript module pattern:
// see http://en.wikipedia.org/wiki/Unobtrusive_JavaScript#Namespaces
// In essence, we define an anonymous function which is immediately called and
@@ -22,11 +26,10 @@ var common = (function() {
* Return the mime type for NaCl plugin.
*
* @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc.
- * @param {bool} isRelease True if this is a release build.
* @return {string} The mime-type for the kind of NaCl plugin matching
* the given toolchain.
*/
- function mimeTypeForTool(tool, isRelease) {
+ function mimeTypeForTool(tool) {
// For NaCl modules use application/x-nacl.
var mimetype = 'application/x-nacl';
if (isHostToolchain(tool)) {
@@ -36,7 +39,7 @@ var common = (function() {
mimetype = 'application/x-ppapi-release';
else
mimetype = 'application/x-ppapi-debug';
- } else if (tool == 'pnacl') {
+ } else if (tool == 'pnacl' && isRelease) {
mimetype = 'application/x-pnacl';
}
return mimetype;
@@ -293,8 +296,7 @@ var common = (function() {
// status message indicating that the module is still loading. Otherwise,
// do not change the status message.
updateStatus('Page loaded.');
- var isRelease = path.toLowerCase().indexOf('release') != -1;
- if (!browserSupportsNaCl(tool, isRelease)) {
+ if (!browserSupportsNaCl(tool)) {
updateStatus(
'Browser does not support NaCl (' + tool + '), or NaCl is disabled');
} else if (common.naclModule == null) {
@@ -399,6 +401,7 @@ document.addEventListener('DOMContentLoaded', function() {
var path = pathFormat.replace('{tc}', tc).replace('{config}', config);
isTest = searchVars.test === 'true';
+ isRelease = path.toLowerCase().indexOf('release') != -1;
loadFunction(body.dataset.name, tc, path, body.dataset.width,
body.dataset.height, attrs);
diff --git a/native_client_sdk/src/examples/demo/earth/earth.cc b/native_client_sdk/src/examples/demo/earth/earth.cc
index d0c6de740c..2a1c95810c 100644
--- a/native_client_sdk/src/examples/demo/earth/earth.cc
+++ b/native_client_sdk/src/examples/demo/earth/earth.cc
@@ -383,9 +383,14 @@ void Planet::wRenderPixelSpan(int x0, int x1, int y) {
if (!base_tex_ || !night_tex_)
return;
const int kColorBlack = MakeRGBA(0, 0, 0, 0xFF);
+ float width = ps_context_->width;
+ float height = ps_context_->height;
+ float min_dim = width < height ? width : height;
+ float offset_x = width < height ? 0 : (width - min_dim) * 0.5f;
+ float offset_y = width < height ? (height - min_dim) * 0.5f : 0;
float y0 = eye_y_;
float z0 = eye_z_;
- float y1 = (static_cast<float>(y) / ps_context_->height) * 2.0f - 1.0f;
+ float y1 = (static_cast<float>(y - offset_y) / min_dim) * 2.0f - 1.0f;
float z1 = 0.0f;
float dy = (y1 - y0);
float dz = (z1 - z0);
@@ -394,11 +399,11 @@ void Planet::wRenderPixelSpan(int x0, int x1, int y) {
2.0f * dz * (z0 - planet_z_);
float planet_xyz_eye_xyz = planet_xyz_ + eye_xyz_;
float y_y0_z_z0 = planet_y_ * y0 + planet_z_ * z0;
- float oowidth = 1.0f / ps_context_->width;
+ float oowidth = 1.0f / min_dim;
uint32_t* pixels = this->wGetAddr(x0, y);
for (int x = x0; x <= x1; ++x) {
// scan normalized screen -1..1
- float x1 = (static_cast<float>(x) * oowidth) * 2.0f - 1.0f;
+ float x1 = (static_cast<float>(x - offset_x) * oowidth) * 2.0f - 1.0f;
// eye
float x0 = eye_x_;
// delta from screen to eye
diff --git a/native_client_sdk/src/examples/demo/flock/flock.cc b/native_client_sdk/src/examples/demo/flock/flock.cc
index de23691149..94707a03e9 100644
--- a/native_client_sdk/src/examples/demo/flock/flock.cc
+++ b/native_client_sdk/src/examples/demo/flock/flock.cc
@@ -5,14 +5,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mount.h>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
-#include "nacl_io/nacl_io.h"
-
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/pp_size.h"
diff --git a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
index 9a1babd1ab..c38fefc368 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
+++ b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mount.h>
#include <pthread.h>
#include "ppapi/c/pp_errors.h"
diff --git a/native_client_sdk/src/examples/tutorial/dlopen/dlopen.cc b/native_client_sdk/src/examples/tutorial/dlopen/dlopen.cc
index 9291464165..8b5df974f9 100644
--- a/native_client_sdk/src/examples/tutorial/dlopen/dlopen.cc
+++ b/native_client_sdk/src/examples/tutorial/dlopen/dlopen.cc
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mount.h>
#include <ppapi/cpp/completion_callback.h>
#include <ppapi/cpp/instance.h>
diff --git a/native_client_sdk/src/libraries/nacl_io/host_resolver.cc b/native_client_sdk/src/libraries/nacl_io/host_resolver.cc
index f059f9a9ae..beae7261b5 100644
--- a/native_client_sdk/src/libraries/nacl_io/host_resolver.cc
+++ b/native_client_sdk/src/libraries/nacl_io/host_resolver.cc
@@ -4,13 +4,9 @@
#include "nacl_io/host_resolver.h"
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sstream>
-#include <string>
-
#include "nacl_io/kernel_proxy.h"
#include "nacl_io/ossocket.h"
#include "nacl_io/pepper_interface.h"
@@ -176,51 +172,6 @@ void HostResolver::hostent_cleanup() {
hostent_.h_addr_list = NULL;
}
-void HostResolver::herror(const char* s) {
- if (s) {
- fprintf(stderr, "%s: ", s);
- }
-
- fprintf(stderr, "%s\n", hstrerror(h_errno));
-}
-
-const char* HostResolver::hstrerror(int err) {
- // These error message texts are taken straight from the man page
- const char* host_not_found_msg =
- "The specified host is unknown.";
- const char* no_address_msg =
- "The requested name is valid but does not have an IP address.";
- const char* no_recovery_msg =
- "A nonrecoverable name server error occurred.";
- const char* try_again_msg =
- "A temporary error occurred on an authoritative name server. "
- "Try again later.";
- const char* internal_msg =
- "Internal error in gethostbyname.";
- const char* unknown_msg_base =
- "Unknown error in gethostbyname: ";
-
- switch (err) {
- case HOST_NOT_FOUND:
- return host_not_found_msg;
- case NO_ADDRESS:
- return no_address_msg;
- case NO_RECOVERY:
- return no_recovery_msg;
- case TRY_AGAIN:
- return try_again_msg;
- case NETDB_INTERNAL:
- return internal_msg;
- default:
- std::stringstream msg;
- msg << unknown_msg_base << err << ".";
-
- static std::string unknown_msg;
- unknown_msg.assign(msg.str());
- return unknown_msg.c_str();
- }
-}
-
} // namespace nacl_io
#endif // PROVIDES_SOCKET_API
diff --git a/native_client_sdk/src/libraries/nacl_io/host_resolver.h b/native_client_sdk/src/libraries/nacl_io/host_resolver.h
index 0a942bd60e..59f3f7f470 100644
--- a/native_client_sdk/src/libraries/nacl_io/host_resolver.h
+++ b/native_client_sdk/src/libraries/nacl_io/host_resolver.h
@@ -20,8 +20,6 @@ class HostResolver {
void Init(PepperInterface* ppapi);
struct hostent* gethostbyname(const char* name);
- static void herror(const char* s);
- static const char* hstrerror(int err);
private:
void hostent_initialize();
diff --git a/native_client_sdk/src/libraries/nacl_io/include/sys/mount.h b/native_client_sdk/src/libraries/nacl_io/include/sys/mount.h
new file mode 100644
index 0000000000..dde0ab3896
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/include/sys/mount.h
@@ -0,0 +1,19 @@
+/* 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. */
+
+#ifndef LIBRARIES_NACL_IO_INCLUDE_SYS_MOUNT_H
+#define LIBRARIES_NACL_IO_INCLUDE_SYS_MOUNT_H
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+int mount(const char* source, const char* target, const char* filesystemtype,
+ unsigned long mountflags, const void *data);
+
+int umount(const char *target);
+
+__END_DECLS
+
+#endif /* LIBRARIES_NACL_IO_INCLUDE_SYS_MOUNT_H */
diff --git a/native_client_sdk/src/libraries/nacl_io/include/sys/termios.h b/native_client_sdk/src/libraries/nacl_io/include/sys/termios.h
index 8eabbd9681..a8175659a1 100644
--- a/native_client_sdk/src/libraries/nacl_io/include/sys/termios.h
+++ b/native_client_sdk/src/libraries/nacl_io/include/sys/termios.h
@@ -2,8 +2,8 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#ifndef SYS_TERMIOS_H_
-#define SYS_TERMIOS_H_
+#ifndef LIBRARIES_NACL_IO_INCLUDE_SYS_TERMIOS_H_
+#define LIBRARIES_NACL_IO_INCLUDE_SYS_TERMIOS_H_
#define IGNBRK 0000001
#define BRKINT 0000002
@@ -126,4 +126,4 @@ int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
__END_DECLS
-#endif /* SYS_TERMIOS_H_ */
+#endif /* LIBRARIES_NACL_IO_INCLUDE_SYS_TERMIOS_H_ */
diff --git a/native_client_sdk/src/libraries/nacl_io/include/sys/utsname.h b/native_client_sdk/src/libraries/nacl_io/include/sys/utsname.h
index 2e3cd3daa2..22929159a2 100644
--- a/native_client_sdk/src/libraries/nacl_io/include/sys/utsname.h
+++ b/native_client_sdk/src/libraries/nacl_io/include/sys/utsname.h
@@ -2,8 +2,8 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#ifndef LIBRARIES_NACL_SYS_UTSNAME_H_
-#define LIBRARIES_NACL_SYS_UTSNAME_H_
+#ifndef LIBRARIES_NACL_IO_INCLUDE_SYS_UTSNAME_H_
+#define LIBRARIES_NACL_IO_INCLUDE_SYS_UTSNAME_H_
#define _UTSNAME_LENGTH 65
@@ -15,6 +15,12 @@ struct utsname {
char machine[_UTSNAME_LENGTH];
};
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
int uname(struct utsname *buf);
-#endif
+__END_DECLS
+
+#endif /* LIBRARIES_NACL_IO_INCLUDE_SYS_UTSNAME_H_ */
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 912fd18a84..d1bad01831 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.cc
@@ -287,14 +287,6 @@ int ki_getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
return s_kp->getsockopt(fd, lvl, optname, optval, len);
}
-void ki_herror(const char *s) {
- return s_kp->herror(s);
-}
-
-const char *ki_hstrerror(int err) {
- return s_kp->hstrerror(err);
-}
-
int ki_listen(int fd, int backlog) {
return s_kp->listen(fd, backlog);
}
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 b570c8f136..6ef44b3a5a 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h
@@ -85,8 +85,6 @@ struct hostent* ki_gethostbyname(const char* name);
int ki_getpeername(int fd, struct sockaddr* addr, socklen_t* len);
int ki_getsockname(int fd, struct sockaddr* addr, socklen_t* len);
int ki_getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len);
-void ki_herror(const char *s);
-const char *ki_hstrerror(int err);
int ki_listen(int fd, int backlog);
ssize_t ki_recv(int fd, void* buf, size_t len, int flags);
ssize_t ki_recvfrom(int fd, void* buf, size_t len, int flags,
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 a64a80013c..292f91ebef 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc
@@ -975,14 +975,6 @@ int KernelProxy::getsockopt(int fd,
return -1;
}
-void KernelProxy::herror(const char* s) {
- return host_resolver_.herror(s);
-}
-
-const char* KernelProxy::hstrerror(int err) {
- return host_resolver_.hstrerror(err);
-}
-
int KernelProxy::listen(int fd, int backlog) {
ScopedKernelHandle handle;
if (AcquireSocketHandle(fd, &handle) == -1)
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 47b6f779d7..fc0191fe82 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.h
@@ -142,8 +142,6 @@ class KernelProxy : protected KernelObject {
int optname,
void* optval,
socklen_t* len);
- virtual void herror(const char* s);
- virtual const char* hstrerror(int err);
virtual int listen(int fd, int backlog);
virtual ssize_t recv(int fd,
void* buf,
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h b/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h
index 6b79d4f0b7..33a4c2d597 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h
@@ -106,8 +106,6 @@ struct hostent* gethostbyname(const char* name);
int getpeername(int fd, struct sockaddr* addr, socklen_t* len);
int getsockname(int fd, struct sockaddr* addr, socklen_t* len);
int getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len);
-void herror(const char *s);
-const char *hstrerror(int err);
int listen(int fd, int backlog);
ssize_t recv(int fd, void* buf, size_t len, int flags);
ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_glibc.cc b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_glibc.cc
index 7c52f4daaf..c2a9e1f737 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_glibc.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_glibc.cc
@@ -11,6 +11,7 @@
#include "nacl_io/kernel_wrap.h"
#include <alloca.h>
+#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <irt.h>
@@ -103,9 +104,14 @@ EXTERN_C_BEGIN
// Macro to get the WRAP function
#define WRAP(name) __nacl_irt_##name##_wrap
-// Declare REAL function pointer and assign it the REAL function.
+// Declare REAL function pointer.
#define DECLARE_REAL_PTR(name) \
- typeof(__nacl_irt_##name) REAL(name) = __nacl_irt_##name;
+ typeof(__nacl_irt_##name) REAL(name);
+
+// Assign the REAL function pointer.
+#define ASSIGN_REAL_PTR(name) \
+ assert(__nacl_irt_##name != NULL); \
+ REAL(name) = __nacl_irt_##name;
// Switch IRT's pointer to the REAL pointer
#define USE_REAL(name) \
@@ -279,90 +285,6 @@ int WRAP(write)(int fd, const void* buf, size_t count, size_t* nwrote) {
return (signed_nwrote < 0) ? errno : 0;
}
-// Socket functions
-int accept(int fd, struct sockaddr* addr, socklen_t* len) {
- return ki_accept(fd, addr, len);
-}
-
-int bind(int fd, const struct sockaddr* addr, socklen_t len) {
- return ki_bind(fd, addr, len);
-}
-
-int connect(int fd, const struct sockaddr* addr, socklen_t len) {
- return ki_connect(fd, addr, len);
-}
-
-struct hostent* gethostbyname(const char* name) {
- return ki_gethostbyname(name);
-}
-
-int getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
- return ki_getpeername(fd, addr, len);
-}
-
-int getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
- return ki_getsockname(fd, addr, len);
-}
-
-int getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
- return ki_getsockopt(fd, lvl, optname, optval, len);
-}
-
-void herror(const char *s) {
- return ki_herror(s);
-}
-
-const char *hstrerror(int err) {
- return ki_hstrerror(err);
-}
-
-int listen(int fd, int backlog) {
- return ki_listen(fd, backlog);
-}
-
-ssize_t recv(int fd, void* buf, size_t len, int flags) {
- return ki_recv(fd, buf, len, flags);
-}
-
-ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
- struct sockaddr* addr, socklen_t* addrlen) {
- return ki_recvfrom(fd, buf, len, flags, addr, addrlen);
-}
-
-ssize_t recvmsg(int fd, struct msghdr* msg, int flags) {
- return ki_recvmsg(fd, msg, flags);
-}
-
-ssize_t send(int fd, const void* buf, size_t len, int flags) {
- return ki_send(fd, buf, len, flags);
-}
-
-ssize_t sendto(int fd, const void* buf, size_t len, int flags,
- const struct sockaddr* addr, socklen_t addrlen) {
- return ki_sendto(fd, buf, len, flags, addr, addrlen);
-}
-
-ssize_t sendmsg(int fd, const struct msghdr* msg, int flags) {
- return ki_sendmsg(fd, msg, flags);
-}
-
-int setsockopt(int fd, int lvl, int optname, const void* optval,
- socklen_t len) {
- return ki_setsockopt(fd, lvl, optname, optval, len);
-}
-
-int shutdown(int fd, int how) {
- return ki_shutdown(fd, how);
-}
-
-int socket(int domain, int type, int protocol) {
- return ki_socket(domain, type, protocol);
-}
-
-int socketpair(int domain, int type, int protocol, int* sv) {
- return ki_socketpair(domain, type, protocol, sv);
-}
-
// "real" functions, i.e. the unwrapped original functions.
int _real_close(int fd) {
@@ -454,8 +376,13 @@ uint64_t usec_since_epoch() {
}
static bool s_wrapped = false;
+static bool s_assigned = false;
void kernel_wrap_init() {
if (!s_wrapped) {
+ if (!s_assigned) {
+ EXPAND_SYMBOL_LIST_OPERATION(ASSIGN_REAL_PTR)
+ s_assigned = true;
+ }
EXPAND_SYMBOL_LIST_OPERATION(USE_WRAP)
s_wrapped = true;
}
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 e21830161d..34ab407f83 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
@@ -9,6 +9,7 @@
#if defined(__native_client__) && !defined(__GLIBC__)
#include "nacl_io/kernel_wrap.h"
+#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <irt.h>
@@ -25,9 +26,14 @@ EXTERN_C_BEGIN
// Macro to get the WRAP function
#define WRAP(name) __nacl_irt_##name##_wrap
-// Declare REAL function pointer and assign it the REAL function.
+// Declare REAL function pointer.
#define DECLARE_REAL_PTR(group, name) \
- typeof(__libnacl_irt_##group.name) REAL(name) = __libnacl_irt_##group.name;
+ typeof(__libnacl_irt_##group.name) REAL(name);
+
+// Assign the REAL function pointer.
+#define ASSIGN_REAL_PTR(group, name) \
+ assert(__libnacl_irt_##group.name != NULL); \
+ REAL(name) = __libnacl_irt_##group.name;
// Switch IRT's pointer to the REAL pointer
#define USE_REAL(group, name) \
@@ -37,10 +43,10 @@ EXTERN_C_BEGIN
#define USE_WRAP(group, name) \
__libnacl_irt_##group.name = (typeof(REAL(name))) WRAP(name); \
-
+extern void __libnacl_irt_filename_init(void);
extern struct nacl_irt_fdio __libnacl_irt_fdio;
-extern struct nacl_irt_filename __libnacl_irt_filename;
+extern struct nacl_irt_dev_filename __libnacl_irt_dev_filename;
extern struct nacl_irt_memory __libnacl_irt_memory;
// Create function pointers to the REAL implementation
@@ -53,8 +59,8 @@ extern struct nacl_irt_memory __libnacl_irt_memory;
OP(fdio, read); \
OP(fdio, seek); \
OP(fdio, write); \
- OP(filename, open); \
- OP(filename, stat); \
+ OP(dev_filename, open); \
+ OP(dev_filename, stat); \
OP(memory, mmap); \
OP(memory, munmap);
@@ -131,90 +137,6 @@ int WRAP(write)(int fd, const void* buf, size_t count, size_t* nwrote) {
return (signed_nwrote < 0) ? errno : 0;
}
-// Socket functions
-int accept(int fd, struct sockaddr* addr, socklen_t* len) {
- return ki_accept(fd, addr, len);
-}
-
-int bind(int fd, const struct sockaddr* addr, socklen_t len) {
- return ki_bind(fd, addr, len);
-}
-
-int connect(int fd, const struct sockaddr* addr, socklen_t len) {
- return ki_connect(fd, addr, len);
-}
-
-struct hostent* gethostbyname(const char* name) {
- return ki_gethostbyname(name);
-}
-
-int getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
- return ki_getpeername(fd, addr, len);
-}
-
-int getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
- return ki_getsockname(fd, addr, len);
-}
-
-int getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
- return ki_getsockopt(fd, lvl, optname, optval, len);
-}
-
-void herror(const char* s) {
- return ki_herror(s);
-}
-
-const char* hstrerror(int err) {
- return ki_hstrerror(err);
-}
-
-int listen(int fd, int backlog) {
- return ki_listen(fd, backlog);
-}
-
-ssize_t recv(int fd, void* buf, size_t len, int flags) {
- return ki_recv(fd, buf, len, flags);
-}
-
-ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
- struct sockaddr* addr, socklen_t* addrlen) {
- return ki_recvfrom(fd, buf, len, flags, addr, addrlen);
-}
-
-ssize_t recvmsg(int fd, struct msghdr* msg, int flags) {
- return ki_recvmsg(fd, msg, flags);
-}
-
-ssize_t send(int fd, const void* buf, size_t len, int flags) {
- return ki_send(fd, buf, len, flags);
-}
-
-ssize_t sendto(int fd, const void* buf, size_t len, int flags,
- const struct sockaddr* addr, socklen_t addrlen) {
- return ki_sendto(fd, buf, len, flags, addr, addrlen);
-}
-
-ssize_t sendmsg(int fd, const struct msghdr* msg, int flags) {
- return ki_sendmsg(fd, msg, flags);
-}
-
-int setsockopt(int fd, int lvl, int optname, const void* optval,
- socklen_t len) {
- return ki_setsockopt(fd, lvl, optname, optval, len);
-}
-
-int shutdown(int fd, int how) {
- return ki_shutdown(fd, how);
-}
-
-int socket(int domain, int type, int protocol) {
- return ki_socket(domain, type, protocol);
-}
-
-int socketpair(int domain, int type, int protocol, int* sv) {
- return ki_socketpair(domain, type, protocol, sv);
-}
-
// "real" functions, i.e. the unwrapped original functions.
int _real_close(int fd) {
@@ -273,16 +195,22 @@ uint64_t usec_since_epoch() {
}
static bool s_wrapped = false;
+static bool s_assigned = false;
void kernel_wrap_init() {
if (!s_wrapped) {
- EXPAND_SYMBOL_LIST_OPERATION(USE_WRAP);
+ if (!s_assigned) {
+ __libnacl_irt_filename_init();
+ EXPAND_SYMBOL_LIST_OPERATION(ASSIGN_REAL_PTR)
+ s_assigned = true;
+ }
+ EXPAND_SYMBOL_LIST_OPERATION(USE_WRAP)
s_wrapped = true;
}
}
void kernel_wrap_uninit() {
if (s_wrapped) {
- EXPAND_SYMBOL_LIST_OPERATION(USE_REAL);
+ EXPAND_SYMBOL_LIST_OPERATION(USE_REAL)
s_wrapped = false;
}
}
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h
index b13d7f886b..9a9bce6de5 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h
@@ -5,6 +5,7 @@
#ifndef LIBRARIES_NACL_IO_KERNEL_WRAP_REAL_H_
#define LIBRARIES_NACL_IO_KERNEL_WRAP_REAL_H_
+#include "nacl_io/osstat.h"
#include "nacl_io/ostypes.h"
#include "sdk_util/macros.h"
diff --git a/native_client_sdk/src/libraries/nacl_io/library.dsc b/native_client_sdk/src/libraries/nacl_io/library.dsc
index 011a9c6105..4d75b2cd6d 100644
--- a/native_client_sdk/src/libraries/nacl_io/library.dsc
+++ b/native_client_sdk/src/libraries/nacl_io/library.dsc
@@ -32,36 +32,61 @@
"mount_node_html5fs.cc",
"mount_node_http.cc",
"mount_node_mem.cc",
+ "mount_node_tty.cc",
"mount_passthrough.cc",
"nacl_io.cc",
"path.cc",
"pepper_interface.cc",
"real_pepper_interface.cc",
+ "syscalls/accept.c",
"syscalls/access.c",
+ "syscalls/bind.c",
"syscalls/chdir.c",
"syscalls/chmod.c",
"syscalls/chown.c",
+ "syscalls/connect.c",
"syscalls/fchown.c",
"syscalls/fsync.c",
"syscalls/ftruncate.c",
+ "syscalls/getcwd.c",
"syscalls/getdents.c",
+ "syscalls/gethostbyname.c",
+ "syscalls/getpeername.c",
+ "syscalls/getsockname.c",
+ "syscalls/getsockopt.c",
"syscalls/getwd.c",
- "syscalls/getcwd.c",
+ "syscalls/herror.c",
+ "syscalls/hstrerror.cc",
+ "syscalls/htonl.c",
+ "syscalls/htons.c",
"syscalls/inet_ntoa.cc",
"syscalls/inet_ntop.cc",
"syscalls/ioctl.c",
"syscalls/isatty.c",
- "syscalls/link.c",
"syscalls/lchown.c",
+ "syscalls/link.c",
+ "syscalls/listen.c",
"syscalls/mkdir.c",
"syscalls/mount.c",
+ "syscalls/ntohl.c",
+ "syscalls/ntohs.c",
"syscalls/poll.c",
- "syscalls/remove.c",
"syscalls/rmdir.c",
- "syscalls/select.c",
+ "syscalls/recv.c",
+ "syscalls/recvfrom.c",
+ "syscalls/recvmsg.c",
+ "syscalls/remove.c",
"syscalls/tcflush.c",
"syscalls/tcgetattr.c",
"syscalls/tcsetattr.c",
+ "syscalls/select.c",
+ "syscalls/send.c",
+ "syscalls/sendmsg.c",
+ "syscalls/sendto.c",
+ "syscalls/setsockopt.c",
+ "syscalls/shutdown.c",
+ "syscalls/socket.c",
+ "syscalls/socketpair.c",
"syscalls/unlink.c",
"syscalls/umount.c",
"syscalls/uname.c",
@@ -90,11 +115,13 @@
"mount_html5fs.h",
"mount_http.h",
"mount_mem.h",
- "mount_node_dir.h",
"mount_node.h",
+ "mount_node_char.h",
+ "mount_node_dir.h",
"mount_node_html5fs.h",
"mount_node_http.h",
"mount_node_mem.h",
+ "mount_node_tty.h",
"mount_passthrough.h",
"nacl_io.h",
"osdirent.h",
@@ -119,8 +146,10 @@
"arpa/inet.h",
"netdb.h",
"netinet/in.h",
+ "netinet/tcp.h",
"netinet6/in6.h",
"poll.h",
+ "sys/mount.h",
"sys/select.h",
"sys/socket.h",
"sys/termios.h",
@@ -133,8 +162,10 @@
"arpa/inet.h",
"netdb.h",
"netinet/in.h",
+ "netinet/tcp.h",
"netinet6/in6.h",
"poll.h",
+ "sys/mount.h",
"sys/select.h",
"sys/socket.h",
"sys/termios.h",
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 f409b1985c..3c7ffe01a7 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_dev.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_dev.cc
@@ -11,13 +11,11 @@
#include <pthread.h>
#include <string.h>
-#include <deque>
-
-#include "nacl_io/ioctl.h"
#include "nacl_io/kernel_wrap_real.h"
#include "nacl_io/mount_dev.h"
#include "nacl_io/mount_node.h"
#include "nacl_io/mount_node_dir.h"
+#include "nacl_io/mount_node_tty.h"
#include "nacl_io/osunistd.h"
#include "nacl_io/pepper_interface.h"
#include "sdk_util/auto_lock.h"
@@ -47,9 +45,9 @@ class RealNode : public MountNode {
int fd_;
};
-class NullNode : public MountNode {
+class NullNode : public MountNodeCharDevice {
public:
- explicit NullNode(Mount* mount);
+ 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,
@@ -58,7 +56,7 @@ class NullNode : public MountNode {
int* out_bytes);
};
-class ConsoleNode : public NullNode {
+class ConsoleNode : public MountNodeCharDevice {
public:
ConsoleNode(Mount* mount, PP_LogLevel level);
@@ -71,30 +69,6 @@ class ConsoleNode : public NullNode {
PP_LogLevel level_;
};
-class TtyNode : public NullNode {
- public:
- explicit TtyNode(Mount* mount);
- ~TtyNode();
-
- virtual Error Ioctl(int request,
- char* arg);
-
- virtual Error Read(size_t offs,
- void* buf,
- size_t count,
- int* out_bytes);
-
- virtual Error Write(size_t offs,
- const void* buf,
- size_t count,
- int* out_bytes);
-
- private:
- std::deque<char> input_buffer_;
- pthread_cond_t is_readable_;
- std::string prefix_;
-};
-
class ZeroNode : public MountNode {
public:
explicit ZeroNode(Mount* mount);
@@ -156,8 +130,6 @@ Error RealNode::Write(size_t offs,
Error RealNode::GetStat(struct stat* stat) { return _real_fstat(fd_, stat); }
-NullNode::NullNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; }
-
Error NullNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
*out_bytes = 0;
return 0;
@@ -172,8 +144,7 @@ Error NullNode::Write(size_t offs,
}
ConsoleNode::ConsoleNode(Mount* mount, PP_LogLevel level)
- : NullNode(mount), level_(level) {
- stat_.st_mode = S_IFCHR;
+ : MountNodeCharDevice(mount), level_(level) {
}
Error ConsoleNode::Write(size_t offs,
@@ -197,88 +168,6 @@ Error ConsoleNode::Write(size_t offs,
return 0;
}
-TtyNode::TtyNode(Mount* mount) : NullNode(mount) {
- pthread_cond_init(&is_readable_, NULL);
-}
-
-TtyNode::~TtyNode() {
- pthread_cond_destroy(&is_readable_);
-}
-
-Error TtyNode::Write(size_t offs,
- const void* buf,
- size_t count,
- int* out_bytes) {
- *out_bytes = 0;
-
- MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface();
- VarInterface* var_intr = mount_->ppapi()->GetVarInterface();
-
- if (!(var_intr && msg_intr))
- return ENOSYS;
-
- // We append the prefix_ to the data in buf, then package it up
- // and post it as a message.
- const char* data = static_cast<const char*>(buf);
- std::string message;
- {
- AUTO_LOCK(node_lock_);
- message = prefix_;
- }
- message.append(data, count);
- uint32_t len = static_cast<uint32_t>(message.size());
- struct PP_Var val = var_intr->VarFromUtf8(message.data(), len);
- msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val);
- *out_bytes = count;
- return 0;
-}
-
-Error TtyNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
- AUTO_LOCK(node_lock_);
- while (input_buffer_.size() <= 0) {
- pthread_cond_wait(&is_readable_, node_lock_.mutex());
- }
-
- // Copies data from the input buffer into buf.
- size_t bytes_to_copy = std::min(count, input_buffer_.size());
- std::copy(input_buffer_.begin(), input_buffer_.begin() + bytes_to_copy,
- static_cast<char*>(buf));
- *out_bytes = bytes_to_copy;
- input_buffer_.erase(input_buffer_.begin(),
- input_buffer_.begin() + bytes_to_copy);
- return 0;
-}
-
-Error TtyNode::Ioctl(int request, char* arg) {
- if (request == TIOCNACLPREFIX) {
- // This ioctl is used to change the prefix for this tty node.
- // The prefix is used to distinguish messages intended for this
- // tty node from all the other messages cluttering up the
- // javascript postMessage() channel.
- AUTO_LOCK(node_lock_);
- prefix_ = arg;
- return 0;
- } else if (request == TIOCNACLINPUT) {
- // This ioctl is used to deliver data from the user to this tty node's
- // input buffer. We check if the prefix in the input data matches the
- // prefix for this node, and only deliver the data if so.
- struct tioc_nacl_input_string* message =
- reinterpret_cast<struct tioc_nacl_input_string*>(arg);
- AUTO_LOCK(node_lock_);
- if (message->length >= prefix_.size() &&
- strncmp(message->buffer, prefix_.data(), prefix_.size()) == 0) {
- input_buffer_.insert(input_buffer_.end(),
- message->buffer + prefix_.size(),
- message->buffer + message->length);
- pthread_cond_broadcast(&is_readable_);
- return 0;
- }
- return ENOTTY;
- } else {
- return EINVAL;
- }
-}
-
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) {
@@ -407,7 +296,7 @@ Error MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
INITIALIZE_DEV_NODE_1("/console1", ConsoleNode, PP_LOGLEVEL_LOG);
INITIALIZE_DEV_NODE_1("/console2", ConsoleNode, PP_LOGLEVEL_WARNING);
INITIALIZE_DEV_NODE_1("/console3", ConsoleNode, PP_LOGLEVEL_ERROR);
- INITIALIZE_DEV_NODE("/tty", TtyNode);
+ INITIALIZE_DEV_NODE("/tty", MountNodeTty);
INITIALIZE_DEV_NODE_1("/stdin", RealNode, 0);
INITIALIZE_DEV_NODE_1("/stdout", RealNode, 1);
INITIALIZE_DEV_NODE_1("/stderr", RealNode, 2);
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_char.h b/native_client_sdk/src/libraries/nacl_io/mount_node_char.h
new file mode 100644
index 0000000000..48ad86fc65
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_char.h
@@ -0,0 +1,21 @@
+// 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.
+
+#ifndef LIBRARIES_NACL_IO_MOUNT_NODE_CHAR_H
+#define LIBRARIES_NACL_IO_MOUNT_NODE_CHAR_H
+
+#include "nacl_io/mount_node.h"
+
+namespace nacl_io {
+
+class MountNodeCharDevice : public MountNode {
+ public:
+ explicit MountNodeCharDevice(Mount* mount) : MountNode(mount) {
+ stat_.st_mode = S_IFCHR;
+ }
+};
+
+}
+
+#endif // LIBRARIES_NACL_IO_MOUNT_NODE_CHAR_H
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
new file mode 100644
index 0000000000..7b9fb7943a
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
@@ -0,0 +1,271 @@
+// 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/mount_node_tty.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <algorithm>
+
+#include "nacl_io/ioctl.h"
+#include "nacl_io/mount.h"
+#include "nacl_io/pepper_interface.h"
+#include "sdk_util/auto_lock.h"
+
+#define CHECK_LFLAG(TERMIOS, FLAG) (TERMIOS .c_lflag & FLAG)
+
+#define IS_ECHO CHECK_LFLAG(termios_, ECHO)
+#define IS_ECHOE CHECK_LFLAG(termios_, ECHOE)
+#define IS_ECHONL CHECK_LFLAG(termios_, ECHONL)
+#define IS_ECHOCTL CHECK_LFLAG(termios_, ECHOCTL)
+#define IS_ICANON CHECK_LFLAG(termios_, ICANON)
+
+namespace nacl_io {
+
+MountNodeTty::MountNodeTty(Mount* mount) : MountNodeCharDevice(mount),
+ is_readable_(false) {
+ pthread_cond_init(&is_readable_cond_, NULL);
+ InitTermios();
+}
+
+void MountNodeTty::InitTermios() {
+ // Some sane values that produce good result.
+ termios_.c_iflag = ICRNL | IXON | IXOFF | IUTF8;
+ termios_.c_oflag = OPOST | ONLCR;
+ termios_.c_cflag = CREAD | 077;
+ termios_.c_lflag =
+ ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
+ termios_.c_ispeed = B38400;
+ termios_.c_ospeed = B38400;
+ termios_.c_cc[VINTR] = 3;
+ termios_.c_cc[VQUIT] = 28;
+ termios_.c_cc[VERASE] = 127;
+ termios_.c_cc[VKILL] = 21;
+ termios_.c_cc[VEOF] = 4;
+ termios_.c_cc[VTIME] = 0;
+ termios_.c_cc[VMIN] = 1;
+ termios_.c_cc[VSWTC] = 0;
+ termios_.c_cc[VSTART] = 17;
+ termios_.c_cc[VSTOP] = 19;
+ termios_.c_cc[VSUSP] = 26;
+ termios_.c_cc[VEOL] = 0;
+ termios_.c_cc[VREPRINT] = 18;
+ termios_.c_cc[VDISCARD] = 15;
+ termios_.c_cc[VWERASE] = 23;
+ termios_.c_cc[VLNEXT] = 22;
+ termios_.c_cc[VEOL2] = 0;
+}
+
+MountNodeTty::~MountNodeTty() {
+ pthread_cond_destroy(&is_readable_cond_);
+}
+
+Error MountNodeTty::Write(size_t offs,
+ const void* buf,
+ size_t count,
+ int* out_bytes) {
+ return Write(offs, buf, count, out_bytes, false);
+}
+
+Error MountNodeTty::Write(size_t offs,
+ const void* buf,
+ size_t count,
+ int* out_bytes,
+ bool locked) {
+ *out_bytes = 0;
+
+ if (!mount_->ppapi())
+ return ENOSYS;
+
+ MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface();
+ VarInterface* var_intr = mount_->ppapi()->GetVarInterface();
+
+ if (!(var_intr && msg_intr))
+ return ENOSYS;
+
+ // We append the prefix_ to the data in buf, then package it up
+ // and post it as a message.
+ const char* data = static_cast<const char*>(buf);
+ std::string message;
+ if (locked) {
+ message = prefix_;
+ } else {
+ AUTO_LOCK(node_lock_);
+ message = prefix_;
+ }
+
+ message.append(data, count);
+ uint32_t len = static_cast<uint32_t>(message.size());
+ struct PP_Var val = var_intr->VarFromUtf8(message.data(), len);
+ msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val);
+ var_intr->Release(val);
+ *out_bytes = count;
+ return 0;
+}
+
+Error MountNodeTty::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
+ AUTO_LOCK(node_lock_);
+ while (!is_readable_) {
+ pthread_cond_wait(&is_readable_cond_, node_lock_.mutex());
+ }
+
+ size_t bytes_to_copy = std::min(count, input_buffer_.size());
+
+ if (IS_ICANON) {
+ // Only read up to (and including) the first newline
+ std::deque<char>::iterator nl = std::find(input_buffer_.begin(),
+ input_buffer_.end(),
+ '\n');
+
+ if (nl != input_buffer_.end()) {
+ // We found a newline in the buffer, adjust bytes_to_copy accordingly
+ size_t line_len = static_cast<size_t>(nl - input_buffer_.begin()) + 1;
+ bytes_to_copy = std::min(bytes_to_copy, line_len);
+ }
+ }
+
+
+ // Copies data from the input buffer into buf.
+ std::copy(input_buffer_.begin(), input_buffer_.begin() + bytes_to_copy,
+ static_cast<char*>(buf));
+ *out_bytes = bytes_to_copy;
+ input_buffer_.erase(input_buffer_.begin(),
+ input_buffer_.begin() + bytes_to_copy);
+
+ // mark input as no longer readable if we consumed
+ // the entire buffer or, in the case of buffered input,
+ // we consumed the final \n char.
+ if (IS_ICANON)
+ is_readable_ =
+ std::find(input_buffer_.begin(),
+ input_buffer_.end(), '\n') != input_buffer_.end();
+ else
+ is_readable_ = input_buffer_.size() > 0;
+
+ return 0;
+}
+
+Error MountNodeTty::Echo(const char* string, int count) {
+ int wrote;
+ Error error = Write(0, string, count, &wrote, true);
+ if (error != 0 || wrote != count) {
+ // TOOD(sbc): Do something more useful in response to a
+ // failure to echo.
+ return error;
+ }
+
+ return 0;
+}
+
+Error MountNodeTty::ProcessInput(struct tioc_nacl_input_string* message) {
+ AUTO_LOCK(node_lock_);
+ if (message->length < prefix_.size() ||
+ strncmp(message->buffer, prefix_.data(), prefix_.size()) != 0) {
+ return ENOTTY;
+ }
+
+ const char* buffer = message->buffer + prefix_.size();
+ int num_bytes = message->length - prefix_.size();
+
+ for (int i = 0; i < num_bytes; i++) {
+ char c = buffer[i];
+ // Transform characters according to input flags.
+ if (c == '\r') {
+ if (termios_.c_iflag & IGNCR)
+ continue;
+ if (termios_.c_iflag & ICRNL)
+ c = '\n';
+ } else if (c == '\n') {
+ if (termios_.c_iflag & INLCR)
+ c = '\r';
+ }
+
+ bool skip = false;
+
+ // ICANON mode means we wait for a newline before making the
+ // file readable.
+ if (IS_ICANON) {
+ if (IS_ECHOE && c == termios_.c_cc[VERASE]) {
+ // Remove previous character in the line if any.
+ if (!input_buffer_.empty()) {
+ char char_to_delete = input_buffer_.back();
+ if (char_to_delete != '\n') {
+ input_buffer_.pop_back();
+ if (IS_ECHO)
+ Echo("\b \b", 3);
+
+ // When ECHOCTL is set the echo buffer contains an extra
+ // char for each control char.
+ if (IS_ECHOCTL && iscntrl(char_to_delete))
+ Echo("\b \b", 3);
+ }
+ }
+ continue;
+ } else if (IS_ECHO || (IS_ECHONL && c == '\n')) {
+ if (c == termios_.c_cc[VEOF]) {
+ // VEOF sequence is not echoed, nor is it sent as
+ // input.
+ skip = true;
+ } else if (c != '\n' && iscntrl(c) && IS_ECHOCTL) {
+ // In ECHOCTL mode a control char C is echoed as '^'
+ // followed by the ascii char which at C + 0x40.
+ char visible_char = c + 0x40;
+ Echo("^", 1);
+ Echo(&visible_char, 1);
+ } else {
+ Echo(&c, 1);
+ }
+ }
+ }
+
+ if (!skip)
+ input_buffer_.push_back(c);
+
+ if (c == '\n' || c == termios_.c_cc[VEOF] || !IS_ICANON)
+ is_readable_ = true;
+ }
+
+ if (is_readable_)
+ pthread_cond_broadcast(&is_readable_cond_);
+ return 0;
+}
+
+Error MountNodeTty::Ioctl(int request, char* arg) {
+ if (request == TIOCNACLPREFIX) {
+ // This ioctl is used to change the prefix for this tty node.
+ // The prefix is used to distinguish messages intended for this
+ // tty node from all the other messages cluttering up the
+ // javascript postMessage() channel.
+ AUTO_LOCK(node_lock_);
+ prefix_ = arg;
+ return 0;
+ } else if (request == TIOCNACLINPUT) {
+ // This ioctl is used to deliver data from the user to this tty node's
+ // input buffer. We check if the prefix in the input data matches the
+ // prefix for this node, and only deliver the data if so.
+ struct tioc_nacl_input_string* message =
+ reinterpret_cast<struct tioc_nacl_input_string*>(arg);
+ return ProcessInput(message);
+ } else {
+ return EINVAL;
+ }
+}
+
+Error MountNodeTty::Tcgetattr(struct termios* termios_p) {
+ AUTO_LOCK(node_lock_);
+ *termios_p = termios_;
+ return 0;
+}
+
+Error MountNodeTty::Tcsetattr(int optional_actions,
+ const struct termios *termios_p) {
+ AUTO_LOCK(node_lock_);
+ termios_ = *termios_p;
+ 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
new file mode 100644
index 0000000000..0707420a0c
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.h
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef LIBRARIES_NACL_IO_MOUNT_NODE_TTY_H_
+#define LIBRARIES_NACL_IO_MOUNT_NODE_TTY_H_
+
+#include <pthread.h>
+
+#include <deque>
+
+#include "nacl_io/ioctl.h"
+#include "nacl_io/mount_node_char.h"
+#include "nacl_io/ostermios.h"
+
+
+namespace nacl_io {
+
+class MountNodeTty : public MountNodeCharDevice {
+ public:
+ explicit MountNodeTty(Mount* mount);
+ ~MountNodeTty();
+
+ virtual Error Ioctl(int request,
+ char* arg);
+
+ virtual Error Read(size_t offs,
+ void* buf,
+ size_t count,
+ int* out_bytes);
+
+ virtual Error Write(size_t offs,
+ const void* buf,
+ size_t count,
+ int* out_bytes);
+
+ virtual Error Tcgetattr(struct termios* termios_p);
+ virtual Error Tcsetattr(int optional_actions,
+ const struct termios *termios_p);
+
+ private:
+ virtual Error Write(size_t offs,
+ const void* buf,
+ size_t count,
+ int* out_bytes,
+ bool locked);
+ Error ProcessInput(struct tioc_nacl_input_string* message);
+ Error Echo(const char* string, int count);
+ void InitTermios();
+
+ std::deque<char> input_buffer_;
+ bool is_readable_;
+ pthread_cond_t is_readable_cond_;
+ std::string prefix_;
+ struct termios termios_;
+};
+
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/nacl_io.h b/native_client_sdk/src/libraries/nacl_io/nacl_io.h
index e72b5a5f5a..058ba68c70 100644
--- a/native_client_sdk/src/libraries/nacl_io/nacl_io.h
+++ b/native_client_sdk/src/libraries/nacl_io/nacl_io.h
@@ -8,20 +8,20 @@
#include <ppapi/c/pp_instance.h>
#include <ppapi/c/ppb.h>
-#include "nacl_io/kernel_wrap.h"
#include "sdk_util/macros.h"
EXTERN_C_BEGIN
-
-/** Initialize nacl_io.
+/**
+ * Initialize nacl_io.
*
* NOTE: If you initialize nacl_io with this constructor, you cannot
* use any mounts that require PPAPI; e.g. persistent storage, etc.
*/
void nacl_io_init();
-/** Initialize nacl_io with PPAPI support.
+/**
+ * Initialize nacl_io with PPAPI support.
*
* Usage:
* PP_Instance instance;
@@ -42,7 +42,11 @@ void nacl_io_init_ppapi(PP_Instance instance,
PPB_GetInterface get_interface);
-/** Mount a new filesystem type.
+/**
+ * Mount a new filesystem type.
+ *
+ * This function is declared in <sys/mount.h>, but we document it here
+ * because nacl_io is controlled primarily through mount(2)/umount(2).
*
* Some parameters are dependent on the filesystem type being mounted.
*
@@ -108,9 +112,10 @@ void nacl_io_init_ppapi(PP_Instance instance,
* @param[in] mountflags Unused.
* @param[in] data Depends on the filesystem type. See above.
* @return 0 on success, -1 on failure (with errno set).
+ *
+ * int mount(const char* source, const char* target, const char* filesystemtype,
+ * unsigned long mountflags, const void *data) NOTHROW;
*/
-int mount(const char* source, const char* target, const char* filesystemtype,
- unsigned long mountflags, const void *data) NOTHROW;
EXTERN_C_END
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 cb75d73216..1f2e1bfa95 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
@@ -64,6 +64,7 @@ BEGIN_INTERFACE(MessagingInterface, PPB_Messaging, PPB_MESSAGING_INTERFACE_1_0)
END_INTERFACE(MessagingInterface, PPB_Messaging)
BEGIN_INTERFACE(VarInterface, PPB_Var, PPB_VAR_INTERFACE_1_1)
+ METHOD1(VarInterface, void, Release, struct PP_Var)
METHOD2(VarInterface, struct PP_Var, VarFromUtf8, const char *, uint32_t)
METHOD2(VarInterface, const char*, VarToUtf8, PP_Var, uint32_t*)
END_INTERFACE(VarInterface, PPB_Var)
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/accept.c b/native_client_sdk/src/libraries/nacl_io/syscalls/accept.c
new file mode 100644
index 0000000000..ff4f7df984
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/accept.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int accept(int fd, struct sockaddr* addr, socklen_t* len) {
+ return ki_accept(fd, addr, len);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/bind.c b/native_client_sdk/src/libraries/nacl_io/syscalls/bind.c
new file mode 100644
index 0000000000..2dbfb3bcd4
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/bind.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int bind(int fd, const struct sockaddr* addr, socklen_t len) {
+ return ki_bind(fd, addr, len);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/connect.c b/native_client_sdk/src/libraries/nacl_io/syscalls/connect.c
new file mode 100644
index 0000000000..8d2a10f731
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/connect.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int connect(int fd, const struct sockaddr* addr, socklen_t len) {
+ return ki_connect(fd, addr, len);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/gethostbyname.c b/native_client_sdk/src/libraries/nacl_io/syscalls/gethostbyname.c
new file mode 100644
index 0000000000..d370075e1b
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/gethostbyname.c
@@ -0,0 +1,16 @@
+/* Copyright 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/ossocket.h"
+
+#ifdef PROVIDES_SOCKET_API
+
+#include "nacl_io/kernel_intercept.h"
+#include "nacl_io/kernel_wrap.h"
+
+struct hostent* gethostbyname(const char* name) {
+ return ki_gethostbyname(name);
+}
+
+#endif /* PROVIDES_SOCKET_API */
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/getpeername.c b/native_client_sdk/src/libraries/nacl_io/syscalls/getpeername.c
new file mode 100644
index 0000000000..20d241c3f6
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/getpeername.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
+ return ki_getpeername(fd, addr, len);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/getsockname.c b/native_client_sdk/src/libraries/nacl_io/syscalls/getsockname.c
new file mode 100644
index 0000000000..79639de89f
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/getsockname.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
+ return ki_getsockname(fd, addr, len);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/getsockopt.c b/native_client_sdk/src/libraries/nacl_io/syscalls/getsockopt.c
new file mode 100644
index 0000000000..aa55f221f9
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/getsockopt.c
@@ -0,0 +1,15 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int getsockopt(int fd, int lvl, int optname, void* optval, socklen_t* len) {
+ return ki_getsockopt(fd, lvl, optname, optval, len);
+}
+
+#endif
+
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/herror.c b/native_client_sdk/src/libraries/nacl_io/syscalls/herror.c
new file mode 100644
index 0000000000..01bcd91bf1
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/herror.c
@@ -0,0 +1,19 @@
+/* Copyright 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/ossocket.h"
+
+#ifdef PROVIDES_SOCKET_API
+
+#include <stdio.h>
+
+void herror(const char* s) {
+ if (s) {
+ fprintf(stderr, "%s: ", s);
+ }
+
+ fprintf(stderr, "%s\n", hstrerror(h_errno));
+}
+
+#endif /* PROVIDES_SOCKET_API */
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc b/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc
new file mode 100644
index 0000000000..f1354d934b
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/hstrerror.cc
@@ -0,0 +1,54 @@
+// Copyright 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/ossocket.h"
+
+#ifdef PROVIDES_SOCKET_API
+
+#include <sstream>
+#include <string>
+#include "sdk_util/macros.h"
+
+EXTERN_C_BEGIN
+
+const char* hstrerror(int err) {
+ // These error message texts are taken straight from the man page
+ const char* host_not_found_msg =
+ "The specified host is unknown.";
+ const char* no_address_msg =
+ "The requested name is valid but does not have an IP address.";
+ const char* no_recovery_msg =
+ "A nonrecoverable name server error occurred.";
+ const char* try_again_msg =
+ "A temporary error occurred on an authoritative name server. "
+ "Try again later.";
+ const char* internal_msg =
+ "Internal error in gethostbyname.";
+ const char* unknown_msg_base =
+ "Unknown error in gethostbyname: ";
+
+ switch (err) {
+ case HOST_NOT_FOUND:
+ return host_not_found_msg;
+ case NO_ADDRESS:
+ return no_address_msg;
+ case NO_RECOVERY:
+ return no_recovery_msg;
+ case TRY_AGAIN:
+ return try_again_msg;
+ case NETDB_INTERNAL:
+ return internal_msg;
+ default:
+ std::stringstream msg;
+ msg << unknown_msg_base << err << ".";
+
+ static std::string unknown_msg;
+ unknown_msg.assign(msg.str());
+ return unknown_msg.c_str();
+ }
+}
+
+EXTERN_C_END
+
+#endif // PROVIDES_SOCKET_API
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/htonl.c b/native_client_sdk/src/libraries/nacl_io/syscalls/htonl.c
new file mode 100644
index 0000000000..c29386f85c
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/htonl.c
@@ -0,0 +1,23 @@
+/* Copyright 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/ossocket.h"
+
+#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
+
+#include <string.h>
+
+inline uint32_t htonl(uint32_t hostlong) {
+ uint8_t result_bytes[4];
+ result_bytes[0] = (uint8_t) ((hostlong >> 24) & 0xFF);
+ result_bytes[1] = (uint8_t) ((hostlong >> 16) & 0xFF);
+ result_bytes[2] = (uint8_t) ((hostlong >> 8) & 0xFF);
+ result_bytes[3] = (uint8_t) (hostlong & 0xFF);
+
+ uint32_t result;
+ memcpy(&result, result_bytes, 4);
+ return result;
+}
+
+#endif /* defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) */
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/htons.c b/native_client_sdk/src/libraries/nacl_io/syscalls/htons.c
new file mode 100644
index 0000000000..0bdab70027
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/htons.c
@@ -0,0 +1,21 @@
+/* Copyright 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/ossocket.h"
+
+#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
+
+#include <string.h>
+
+inline uint16_t htons(uint16_t hostshort) {
+ uint8_t result_bytes[2];
+ result_bytes[0] = (uint8_t) ((hostshort >> 8) & 0xFF);
+ result_bytes[1] = (uint8_t) (hostshort & 0xFF);
+
+ uint16_t result;
+ memcpy(&result, result_bytes, 2);
+ return result;
+}
+
+#endif /* defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) */
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc
index 93825e7d57..c6cf6107df 100644
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntoa.cc
@@ -1,6 +1,6 @@
-/* Copyright 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. */
+// Copyright 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/ossocket.h"
#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc
index 807bdfe9b7..ceabae5815 100644
--- a/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/inet_ntop.cc
@@ -1,6 +1,6 @@
-/* Copyright 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. */
+// Copyright 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/ossocket.h"
#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/listen.c b/native_client_sdk/src/libraries/nacl_io/syscalls/listen.c
new file mode 100644
index 0000000000..18c7c4f743
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/listen.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int listen(int fd, int backlog) {
+ return ki_listen(fd, backlog);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/ntohl.c b/native_client_sdk/src/libraries/nacl_io/syscalls/ntohl.c
new file mode 100644
index 0000000000..8338a6a5dc
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/ntohl.c
@@ -0,0 +1,21 @@
+/* Copyright 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/ossocket.h"
+
+#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
+
+#include <string.h>
+
+inline uint32_t ntohl(uint32_t networklong) {
+ uint8_t input[4];
+ memcpy(input, &networklong, 4);
+
+ return ((((uint32_t) input[0]) << 24) |
+ (((uint32_t) input[1]) << 16) |
+ (((uint32_t) input[2]) << 8) |
+ ((uint32_t) input[3]));
+}
+
+#endif /* defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) */
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/ntohs.c b/native_client_sdk/src/libraries/nacl_io/syscalls/ntohs.c
new file mode 100644
index 0000000000..19b6afe1bf
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/ntohs.c
@@ -0,0 +1,19 @@
+/* Copyright 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/ossocket.h"
+
+#if defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__)
+
+#include <string.h>
+
+inline uint16_t ntohs(uint16_t networkshort) {
+ uint8_t input[2];
+ memcpy(input, &networkshort, 2);
+
+ return ((((uint32_t) input[0]) << 8) |
+ ((uint32_t) input[1]));
+}
+
+#endif /* defined(PROVIDES_SOCKET_API) && !defined(__GLIBC__) */
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/recv.c b/native_client_sdk/src/libraries/nacl_io/syscalls/recv.c
new file mode 100644
index 0000000000..566798cb22
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/recv.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+ssize_t recv(int fd, void* buf, size_t len, int flags) {
+ return ki_recv(fd, buf, len, flags);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/recvfrom.c b/native_client_sdk/src/libraries/nacl_io/syscalls/recvfrom.c
new file mode 100644
index 0000000000..4032cedd80
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/recvfrom.c
@@ -0,0 +1,15 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
+ struct sockaddr* addr, socklen_t* addrlen) {
+ return ki_recvfrom(fd, buf, len, flags, addr, addrlen);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/recvmsg.c b/native_client_sdk/src/libraries/nacl_io/syscalls/recvmsg.c
new file mode 100644
index 0000000000..99cdd3a5a3
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/recvmsg.c
@@ -0,0 +1,10 @@
+/* Copyright 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"
+
+ssize_t recvmsg(int fd, struct msghdr* msg, int flags) {
+ return ki_recvmsg(fd, msg, flags);
+}
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/send.c b/native_client_sdk/src/libraries/nacl_io/syscalls/send.c
new file mode 100644
index 0000000000..eb1d53c899
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/send.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+ssize_t send(int fd, const void* buf, size_t len, int flags) {
+ return ki_send(fd, buf, len, flags);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/sendmsg.c b/native_client_sdk/src/libraries/nacl_io/syscalls/sendmsg.c
new file mode 100644
index 0000000000..64d020c300
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/sendmsg.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+ssize_t sendmsg(int fd, const struct msghdr* msg, int flags) {
+ return ki_sendmsg(fd, msg, flags);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/sendto.c b/native_client_sdk/src/libraries/nacl_io/syscalls/sendto.c
new file mode 100644
index 0000000000..f0ab62f851
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/sendto.c
@@ -0,0 +1,15 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+ssize_t sendto(int fd, const void* buf, size_t len, int flags,
+ const struct sockaddr* addr, socklen_t addrlen) {
+ return ki_sendto(fd, buf, len, flags, addr, addrlen);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/setsockopt.c b/native_client_sdk/src/libraries/nacl_io/syscalls/setsockopt.c
new file mode 100644
index 0000000000..bde469e6e1
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/setsockopt.c
@@ -0,0 +1,15 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int setsockopt(int fd, int lvl, int optname, const void* optval,
+ socklen_t len) {
+ return ki_setsockopt(fd, lvl, optname, optval, len);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/shutdown.c b/native_client_sdk/src/libraries/nacl_io/syscalls/shutdown.c
new file mode 100644
index 0000000000..985d95fcc8
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/shutdown.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int shutdown(int fd, int how) {
+ return ki_shutdown(fd, how);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/socket.c b/native_client_sdk/src/libraries/nacl_io/syscalls/socket.c
new file mode 100644
index 0000000000..d4b4b9b28f
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/socket.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int socket(int domain, int type, int protocol) {
+ return ki_socket(domain, type, protocol);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io/syscalls/socketpair.c b/native_client_sdk/src/libraries/nacl_io/syscalls/socketpair.c
new file mode 100644
index 0000000000..422b4d14e7
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/syscalls/socketpair.c
@@ -0,0 +1,14 @@
+/* Copyright 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"
+
+#ifdef PROVIDES_SOCKET_API
+
+int socketpair(int domain, int type, int protocol, int* sv) {
+ return ki_socketpair(domain, type, protocol, sv);
+}
+
+#endif
diff --git a/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.h b/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.h
index c08285692f..159e3cba1a 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.h
+++ b/native_client_sdk/src/libraries/nacl_io_test/kernel_proxy_mock.h
@@ -67,8 +67,6 @@ class KernelProxyMock : public nacl_io::KernelProxy {
MOCK_METHOD3(getpeername, int(int, struct sockaddr*, socklen_t*));
MOCK_METHOD3(getsockname, int(int, struct sockaddr*, socklen_t*));
MOCK_METHOD5(getsockopt, int(int, int, int, void*, socklen_t*));
- MOCK_METHOD1(herror, void(const char*));
- MOCK_METHOD1(hstrerror, const char*(int));
MOCK_METHOD2(listen, int(int, int));
MOCK_METHOD4(recv, ssize_t(int, void*, size_t, int));
MOCK_METHOD6(recvfrom, ssize_t(int, void*, size_t, int,
diff --git a/native_client_sdk/src/libraries/nacl_io_test/kernel_wrap_test.cc b/native_client_sdk/src/libraries/nacl_io_test/kernel_wrap_test.cc
index 6b48c88f48..34db64a746 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/kernel_wrap_test.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/kernel_wrap_test.cc
@@ -347,16 +347,6 @@ TEST_F(KernelWrapTest, getsockopt) {
getsockopt(DUMMY_FD, 456, 789, NULL, NULL);
}
-TEST_F(KernelWrapTest, herror) {
- EXPECT_CALL(mock, herror(NULL)).Times(1);
- herror(NULL);
-}
-
-TEST_F(KernelWrapTest, hstrerror) {
- EXPECT_CALL(mock, hstrerror(123)).Times(1);
- hstrerror(123);
-}
-
TEST_F(KernelWrapTest, listen) {
EXPECT_CALL(mock, listen(DUMMY_FD, 456)).Times(1);
listen(DUMMY_FD, 456);
diff --git a/native_client_sdk/src/libraries/nacl_io_test/mount_test.cc b/native_client_sdk/src/libraries/nacl_io_test/mount_test.cc
index cc1c437dbf..4829ccf076 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/mount_test.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/mount_test.cc
@@ -322,7 +322,7 @@ TEST(MountTest, DevTty) {
// Now let's try sending some data over.
// First we create the message.
- std::string content("hello, how are you?");
+ std::string content("hello, how are you?\n");
std::string message = prefix.append(content);
struct tioc_nacl_input_string packaged_message;
packaged_message.length = message.size();
diff --git a/native_client_sdk/src/libraries/nacl_io_test/socket_test.cc b/native_client_sdk/src/libraries/nacl_io_test/socket_test.cc
index ec45185ff2..e98aa7a087 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/socket_test.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/socket_test.cc
@@ -128,11 +128,6 @@ TEST_F(SocketTest, Getsockopt) {
EXPECT_EQ(errno, ENOTSOCK);
}
-TEST_F(SocketTest, Hstrerror) {
- EXPECT_STREQ(ki_hstrerror(2718),
- "Unknown error in gethostbyname: 2718.");
-}
-
TEST_F(SocketTest, Listen) {
EXPECT_LT(ki_listen(-1, 123), 0);
EXPECT_EQ(errno, EBADF);
@@ -268,6 +263,31 @@ TEST_F(SocketTest, Socketpair) {
// implementations of these functions).
#if !defined(__GLIBC__)
+TEST(SocketUtilityFunctions, Hstrerror) {
+ EXPECT_STREQ(hstrerror(2718),
+ "Unknown error in gethostbyname: 2718.");
+}
+
+TEST(SocketUtilityFunctions, Htonl) {
+ uint32_t host_long = 0x44332211;
+ uint32_t network_long = htonl(host_long);
+ uint8_t network_bytes[4];
+ memcpy(network_bytes, &network_long, 4);
+ EXPECT_EQ(network_bytes[0], 0x44);
+ EXPECT_EQ(network_bytes[1], 0x33);
+ EXPECT_EQ(network_bytes[2], 0x22);
+ EXPECT_EQ(network_bytes[3], 0x11);
+}
+
+TEST(SocketUtilityFunctions, Htons) {
+ uint16_t host_short = 0x2211;
+ uint16_t network_short = htons(host_short);
+ uint8_t network_bytes[2];
+ memcpy(network_bytes, &network_short, 2);
+ EXPECT_EQ(network_bytes[0], 0x22);
+ EXPECT_EQ(network_bytes[1], 0x11);
+}
+
static struct in_addr generate_ipv4_addr(int tuple1, int tuple2,
int tuple3, int tuple4) {
unsigned char addr[4];
@@ -275,8 +295,9 @@ static struct in_addr generate_ipv4_addr(int tuple1, int tuple2,
addr[1] = static_cast<unsigned char>(tuple2);
addr[2] = static_cast<unsigned char>(tuple3);
addr[3] = static_cast<unsigned char>(tuple4);
- struct in_addr* real_addr = reinterpret_cast<struct in_addr*>(addr);
- return *real_addr;
+ struct in_addr real_addr;
+ memcpy(&real_addr, addr, 4);
+ return real_addr;
}
static struct in6_addr generate_ipv6_addr(int* tuples) {
@@ -285,8 +306,9 @@ static struct in6_addr generate_ipv6_addr(int* tuples) {
addr[2*i] = (tuples[i] >> 8) & 0xFF;
addr[2*i+1] = tuples[i] & 0xFF;
}
- struct in6_addr* real_addr = reinterpret_cast<struct in6_addr*>(addr);
- return *real_addr;
+ struct in6_addr real_addr;
+ memcpy(&real_addr, addr, 16);
+ return real_addr;
}
TEST(SocketUtilityFunctions, Inet_ntoa) {
@@ -372,5 +394,21 @@ TEST(SocketUtilityFunctions, Inet_ntop_failure) {
EXPECT_EQ(errno, ENOSPC);
}
+TEST(SocketUtilityFunctions, Ntohs) {
+ uint8_t network_bytes[2] = { 0x22, 0x11 };
+ uint16_t network_short;
+ memcpy(&network_short, network_bytes, 2);
+ uint16_t host_short = ntohs(network_short);
+ EXPECT_EQ(host_short, 0x2211);
+}
+
+TEST(SocketUtilityFunctions, Ntohl) {
+ uint8_t network_bytes[4] = { 0x44, 0x33, 0x22, 0x11 };
+ uint32_t network_long;
+ memcpy(&network_long, network_bytes, 4);
+ uint32_t host_long = ntohl(network_long);
+ EXPECT_EQ(host_long, 0x44332211);
+}
+
#endif // !defined(__GLIBC__)
#endif // PROVIDES_SOCKETPAIR_API
diff --git a/native_client_sdk/src/libraries/third_party/newlib-extras/README.chromium b/native_client_sdk/src/libraries/third_party/newlib-extras/README.chromium
index 4d577fdb4f..3b46d4c3df 100644
--- a/native_client_sdk/src/libraries/third_party/newlib-extras/README.chromium
+++ b/native_client_sdk/src/libraries/third_party/newlib-extras/README.chromium
@@ -21,3 +21,6 @@ Local Modifications:
* Removed the revoked third clause from the licenses in the header files.
* Correctly wrapped netdb.h to allow it to be included in both C and C++ files.
* Removed faulty _BSD_SIZE_T_ typedef in arpa/inet.h
+* Removed macros in arpa/inet.h which added underbars to various functions of
+ the form inet_*, to avoid problems with forward declarations in user code.
+* Added prototypes for htonl, htons, ntohl, and ntohs to netinet/in.h
diff --git a/native_client_sdk/src/libraries/third_party/newlib-extras/arpa/inet.h b/native_client_sdk/src/libraries/third_party/newlib-extras/arpa/inet.h
index 857813728a..1d496a9742 100644
--- a/native_client_sdk/src/libraries/third_party/newlib-extras/arpa/inet.h
+++ b/native_client_sdk/src/libraries/third_party/newlib-extras/arpa/inet.h
@@ -107,21 +107,6 @@ struct in_addr {
#define _STRUCT_IN_ADDR_DECLARED
#endif
-#define inet_addr __inet_addr
-#define inet_aton __inet_aton
-#define inet_lnaof __inet_lnaof
-#define inet_makeaddr __inet_makeaddr
-#define inet_neta __inet_neta
-#define inet_netof __inet_netof
-#define inet_network __inet_network
-#define inet_net_ntop __inet_net_ntop
-#define inet_net_pton __inet_net_pton
-#define inet_ntoa __inet_ntoa
-#define inet_pton __inet_pton
-#define inet_ntop __inet_ntop
-#define inet_nsap_addr __inet_nsap_addr
-#define inet_nsap_ntoa __inet_nsap_ntoa
-
__BEGIN_DECLS
in_addr_t inet_addr(const char *);
char *inet_ntoa(struct in_addr);
diff --git a/native_client_sdk/src/libraries/third_party/newlib-extras/netinet/in.h b/native_client_sdk/src/libraries/third_party/newlib-extras/netinet/in.h
index c66ad5155b..a0cd05cdc1 100644
--- a/native_client_sdk/src/libraries/third_party/newlib-extras/netinet/in.h
+++ b/native_client_sdk/src/libraries/third_party/newlib-extras/netinet/in.h
@@ -562,4 +562,11 @@ char *inet_ntoa_r(struct in_addr ina, char *buf); /* in libkern */
#include <netinet6/in6.h>
#undef __KAME_NETINET_IN_H_INCLUDED_
+__BEGIN_DECLS
+uint32_t htonl(uint32_t hostlong);
+uint16_t htons(uint16_t hostshort);
+uint32_t ntohl(uint32_t networklong);
+uint16_t ntohs(uint16_t networkshort);
+__END_DECLS
+
#endif /* !_NETINET_IN_H_*/
diff --git a/native_client_sdk/src/libraries/third_party/newlib-extras/netinet/tcp.h b/native_client_sdk/src/libraries/third_party/newlib-extras/netinet/tcp.h
new file mode 100644
index 0000000000..04d2284a57
--- /dev/null
+++ b/native_client_sdk/src/libraries/third_party/newlib-extras/netinet/tcp.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/tcp.h,v 1.16 2001/01/09 18:26:17 rwatson Exp $
+ */
+
+#ifndef _NETINET_TCP_H_
+#define _NETINET_TCP_H_
+
+#include <sys/types.h>
+
+#if defined(__native_client__)
+/*
+ * The following section is NaCl specific and is needed to more
+ * closely match the types defined in the BSD sys/types.h.
+ * This is needed to let the RTEMS/BSD TCP/IP stack compile.
+ */
+
+/* deprecated */
+#if ___int8_t_defined
+typedef __uint8_t u_int8_t;
+#endif
+#if ___int16_t_defined
+typedef __uint16_t u_int16_t;
+#endif
+#if ___int32_t_defined
+typedef __uint32_t u_int32_t;
+#endif
+
+#if ___int64_t_defined
+typedef __uint64_t u_int64_t;
+
+/* deprecated */
+typedef __uint64_t u_quad_t;
+typedef __int64_t quad_t;
+typedef quad_t * qaddr_t;
+#endif
+#endif
+
+typedef u_int32_t tcp_seq;
+typedef u_int32_t tcp_cc; /* connection count per rfc1644 */
+
+#define tcp6_seq tcp_seq /* for KAME src sync over BSD*'s */
+#define tcp6hdr tcphdr /* for KAME src sync over BSD*'s */
+
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_short th_sport; /* source port */
+ u_short th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int th_x2:4, /* (unused) */
+ th_off:4; /* data offset */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int th_off:4, /* data offset */
+ th_x2:4; /* (unused) */
+#endif
+ u_char th_flags;
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+#define TH_ECE 0x40
+#define TH_CWR 0x80
+#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
+
+ u_short th_win; /* window */
+ u_short th_sum; /* checksum */
+ u_short th_urp; /* urgent pointer */
+};
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOLEN_MAXSEG 4
+#define TCPOPT_WINDOW 3
+#define TCPOLEN_WINDOW 3
+#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
+#define TCPOLEN_SACK_PERMITTED 2
+#define TCPOPT_SACK 5 /* Experimental */
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_TIMESTAMP 10
+#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+#define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+#define TCPOPT_CC 11 /* CC options: RFC-1644 */
+#define TCPOPT_CCNEW 12
+#define TCPOPT_CCECHO 13
+#define TCPOLEN_CC 6
+#define TCPOLEN_CC_APPA (TCPOLEN_CC+2)
+#define TCPOPT_CC_HDR(ccopt) \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC)
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MSS of 576, this is 536,
+ * but 512 is probably more convenient.
+ * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
+ */
+#define TCP_MSS 512
+
+/*
+ * Default maximum segment size for TCP6.
+ * With an IP6 MSS of 1280, this is 1220,
+ * but 1024 is probably more convenient. (xxx kazu in doubt)
+ * This should be defined as MIN(1024, IP6_MSS - sizeof (struct tcpip6hdr))
+ */
+#define TCP6_MSS 1024
+
+#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
+#define TTCP_CLIENT_SND_WND 4096 /* dflt send window for T/TCP client */
+
+#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
+
+#define TCP_MAXBURST 4 /* maximum segments in a burst */
+
+#define TCP_MAXHLEN (0xf<<2) /* max length of header in bytes */
+#define TCP_MAXOLEN (TCP_MAXHLEN - sizeof(struct tcphdr))
+ /* max space left for options */
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
+#define TCP_MAXSEG 0x02 /* set maximum segment size */
+#define TCP_NOPUSH 0x04 /* don't push last block of write */
+#define TCP_NOOPT 0x08 /* don't use TCP options */
+
+#endif
diff --git a/native_client_sdk/src/tools/common.mk b/native_client_sdk/src/tools/common.mk
index 11feea8276..3082072540 100644
--- a/native_client_sdk/src/tools/common.mk
+++ b/native_client_sdk/src/tools/common.mk
@@ -476,9 +476,9 @@ run: check_for_chrome all $(PAGE)
run_package: check_for_chrome all
$(CHROME_PATH) --load-and-launch-app=$(CURDIR) $(CHROME_ARGS)
-
-GDB_ARGS += -D $(TC_PATH)/$(OSNAME)_x86_$(TOOLCHAIN)/bin/$(SYSARCH)-nacl-gdb
-GDB_ARGS += -D $(abspath $(OUTDIR))/$(TARGET)_$(SYSARCH).nexe
+GDB_ARGS += -D $(TC_PATH)/$(OSNAME)_x86_newlib/bin/$(SYSARCH)-nacl-gdb
+GDB_ARGS += -D --eval-command="nacl-manifest $(abspath $(OUTDIR))/$(TARGET).nmf"
+GDB_ARGS += -D $(GDB_DEBUG_TARGET)
.PHONY: debug
debug: check_for_chrome all $(PAGE)
diff --git a/native_client_sdk/src/tools/nacl_gcc.mk b/native_client_sdk/src/tools/nacl_gcc.mk
index d046714429..c176d9bf47 100644
--- a/native_client_sdk/src/tools/nacl_gcc.mk
+++ b/native_client_sdk/src/tools/nacl_gcc.mk
@@ -429,3 +429,22 @@ all: $(OUTDIR)/$(1).html
$(OUTDIR)/$(1).html: $(EXECUTABLES)
$(call LOG,CREATE_HTML,$$@,$(CREATE_HTML) $(HTML_FLAGS) -o $$@ $$^)
endef
+
+
+#
+# Determine which executable to pass into the debugger. For newlib
+# this is the NEXE which will actually be used. For glibc, runnable-ld.so
+# is the "app", and the "app" is actual an .so we load.
+#
+ifeq (x86_32,$(SYSARCH))
+LIB_NAME = lib32
+else
+LIB_NAME = lib64
+endif
+
+
+ifeq (newlib,$(TOOLCHAIN))
+GDB_DEBUG_TARGET = $(abspath $(OUTDIR))/$(TARGET)_$(SYSARCH).nexe
+else
+GDB_DEBUG_TARGET = $(abspath $(OUTDIR))/$(LIB_NAME)/runnable-ld.so
+endif
diff --git a/native_client_sdk/src/tools/nacl_llvm.mk b/native_client_sdk/src/tools/nacl_llvm.mk
index 3299e4c7d7..a8a310ba22 100644
--- a/native_client_sdk/src/tools/nacl_llvm.mk
+++ b/native_client_sdk/src/tools/nacl_llvm.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Copyright (c) 2012 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.
@@ -17,6 +17,7 @@ PNACL_LINK ?= $(PNACL_BIN)/pnacl-clang++
PNACL_LIB ?= $(PNACL_BIN)/pnacl-ar
PNACL_STRIP ?= $(PNACL_BIN)/pnacl-strip
PNACL_FINALIZE ?= $(PNACL_BIN)/pnacl-finalize
+PNACL_TRANSLATE ?= $(PNACL_BIN)/pnacl-translate
#
# Compile Macro
@@ -93,11 +94,24 @@ endef
# $5 = List of lib dirs
# $6 = Other Linker Args
#
+# For debugging, we translate the pre-finalized .bc file.
+#
define LINKER_RULE
-all: $(1).pexe
-$(1).pexe: $(2) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
- $(call LOG,LINK,$(1).bc,$(PNACL_LINK) -o $(1).bc $(2) $(foreach path,$(5),-L$(path)/pnacl/$(CONFIG)) $(foreach lib,$(3),-l$(lib)) $(6))
- $(call LOG,FINALIZE,$(1).pexe,$(PNACL_FINALIZE) -o $(1).pexe $(1).bc)
+all: $(1).pexe
+$(1)_x86_32.nexe : $(1).bc
+ $(call LOG,TRANSLATE,$$@,$(PNACL_TRANSLATE) --allow-llvm-bitcode-input -arch x86-32 $$^ -o $$@)
+
+$(1)_x86_64.nexe : $(1).bc
+ $(call LOG,TRANSLATE,$$@,$(PNACL_TRANSLATE) --allow-llvm-bitcode-input -arch x86-64 $$^ -o $$@)
+
+$(1)_arm.nexe : $(1).bc
+ $(call LOG,TRANSLATE,$$@,$(PNACL_TRANSLATE) --allow-llvm-bitcode-input -arch arm $$^ -o $$@)
+
+$(1).pexe: $(1).bc
+ $(call LOG,FINALIZE,$$@,$(PNACL_FINALIZE) -o $$@ $$^)
+
+$(1).bc: $(2) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+ $(call LOG,LINK,$$@,$(PNACL_LINK) -o $$@ $(2) $(foreach path,$(5),-L$(path)/pnacl/$(CONFIG)) $(foreach lib,$(3),-l$(lib)) $(6))
endef
@@ -111,7 +125,15 @@ endef
# $5 = POSIX Linker Switches
# $6 = VC Linker Switches
#
+# NOTE: For Debug builds we translate the .bc file to a .nexe instead of
+# using the finalizing to a .pexe. This enables debugging.
+#
define LINK_RULE
+ifeq ($(CONFIG),Debug)
+EXECUTABLES=$(OUTDIR)/$(1)_x86_32.nexe $(OUTDIR)/$(1)_x86_64.nexe $(OUTDIR)/$(1)_arm.nexe
+else
+EXECUTABLES=$(OUTDIR)/$(1).pexe
+endif
$(call LINKER_RULE,$(OUTDIR)/$(1),$(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_pnacl)),$(filter-out pthread,$(3)),$(4),$(LIB_PATHS),$(5))
endef
@@ -149,7 +171,7 @@ NMF:=python $(NACL_SDK_ROOT)/tools/create_nmf.py
define NMF_RULE
all: $(OUTDIR)/$(1).nmf
-$(OUTDIR)/$(1).nmf: $(OUTDIR)/$(1).pexe
+$(OUTDIR)/$(1).nmf: $(EXECUTABLES)
$(call LOG,CREATE_NMF,$$@,$(NMF) -o $$@ $$^ -s $(OUTDIR) $(2))
endef
@@ -160,6 +182,13 @@ CREATE_HTML := python $(NACL_SDK_ROOT)/tools/create_html.py
define HTML_RULE
all: $(OUTDIR)/$(1).html
-$(OUTDIR)/$(1).html: $(OUTDIR)/$(1).pexe
+$(OUTDIR)/$(1).html: $(EXECUTABLES)
$(call LOG,CREATE_HTML,$$@,$(CREATE_HTML) -o $$@ $$^)
endef
+
+
+#
+# Determine which executable to pass into the debugger. For pnacl, this is
+# the .bc -> .nexe translated app.
+#
+GDB_DEBUG_TARGET = $(abspath $(OUTDIR))/$(TARGET)_$(SYSARCH).nexe