diff options
author | Ben Murdoch <benm@google.com> | 2013-08-12 14:20:17 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2013-08-12 14:20:17 +0100 |
commit | ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16 (patch) | |
tree | aa3b1013e823cb7bdee9ece936928292f57b31f4 /native_client_sdk | |
parent | f7fa989080f1e63c6a8aa24d5434922d52d9f51e (diff) | |
download | chromium_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')
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 |