From: Mark Seaborn Date: Tue, 2 Jun 2009 20:43:06 +0000 (+0100) Subject: Implement stat64() via NaCl RPC X-Git-Tag: nacl-dynlink-0.1~4 X-Git-Url: https://repo.or.cz/w/glibc/nacl-glibc.git/commitdiff_plain/d62c4aaa67ba795f508e1911c2ecc7a03e93c3af Implement stat64() via NaCl RPC Split some RPC-related code out of open.c into nacl_rpc.c --- diff --git a/sysdeps/nacl/Makefile b/sysdeps/nacl/Makefile new file mode 100644 index 0000000000..6f84dc4767 --- /dev/null +++ b/sysdeps/nacl/Makefile @@ -0,0 +1,5 @@ + +ifeq ($(subdir),io) +sysdep_routines += nacl_rpc +endif +libpthread-routines += nacl_rpc diff --git a/sysdeps/nacl/nacl_rpc.c b/sysdeps/nacl/nacl_rpc.c new file mode 100644 index 0000000000..41559f8220 --- /dev/null +++ b/sysdeps/nacl/nacl_rpc.c @@ -0,0 +1,30 @@ + +#include + +#include + + +int (*imc_sendmsg)(int fd, const struct NaClImcMsgHdr *msg, int flags) = + NACL_SYSCALL_ADDR(NACL_sys_imc_sendmsg); + +int (*imc_recvmsg)(int fd, struct NaClImcMsgHdr *msg, int flags) = + NACL_SYSCALL_ADDR(NACL_sys_imc_recvmsg); + +hidden_def (imc_sendmsg); +hidden_def (imc_recvmsg); + + +static int is_initialised = 0; +static int use_rpc = 0; + + +int nacl_should_use_rpc(void) +{ + if(!is_initialised) { + use_rpc = getenv("NACL_FD") != NULL; + is_initialised = 1; + } + return use_rpc; +} + +hidden_def (nacl_should_use_rpc); diff --git a/sysdeps/nacl/nacl_rpc.h b/sysdeps/nacl/nacl_rpc.h new file mode 100644 index 0000000000..684a24b145 --- /dev/null +++ b/sysdeps/nacl/nacl_rpc.h @@ -0,0 +1,22 @@ + +#ifndef _NACL_RPC_H +#define _NACL_RPC_H + +#include + +#include + + +#define NACL_COMMS_FD 3 + +int (*imc_sendmsg)(int fd, const struct NaClImcMsgHdr *msg, int flags); +int (*imc_recvmsg)(int fd, struct NaClImcMsgHdr *msg, int flags); +hidden_proto (imc_sendmsg); +hidden_proto (imc_recvmsg); + + +int nacl_should_use_rpc(void); +hidden_proto (nacl_should_use_rpc); + + +#endif diff --git a/sysdeps/nacl/open.c b/sysdeps/nacl/open.c index 36dab5d5d8..6dd430531d 100644 --- a/sysdeps/nacl/open.c +++ b/sysdeps/nacl/open.c @@ -2,33 +2,16 @@ #include #include #include +#include #include #include +#include #include -#define COMMS_FD 3 - -static int is_initialised = 0; -static int use_rpc = 0; - -static int should_use_rpc(void) -{ - if(!is_initialised) { - use_rpc = getenv("NACL_FD") != NULL; - is_initialised = 1; - } - return use_rpc; -} - static int nacl_open_rpc(const char *filename) { - int (*imc_sendmsg)(int fd, const struct NaClImcMsgHdr *msg, int flags) = - NACL_SYSCALL_ADDR(NACL_sys_imc_sendmsg); - int (*imc_recvmsg)(int fd, struct NaClImcMsgHdr *msg, int flags) = - NACL_SYSCALL_ADDR(NACL_sys_imc_recvmsg); - struct NaClImcMsgIoVec iov; struct NaClImcMsgHdr msg; int filename_len = strlen(filename); @@ -41,7 +24,7 @@ static int nacl_open_rpc(const char *filename) msg.iov_length = 1; msg.descv = NULL; msg.desc_length = 0; - if(imc_sendmsg(COMMS_FD, &msg, 0) < 0) + if(imc_sendmsg(NACL_COMMS_FD, &msg, 0) < 0) return -1; char buf[4]; @@ -50,7 +33,7 @@ static int nacl_open_rpc(const char *filename) iov.length = sizeof(buf); msg.descv = &fd; msg.desc_length = 1; - int got = imc_recvmsg(COMMS_FD, &msg, 0); + int got = imc_recvmsg(NACL_COMMS_FD, &msg, 0); if(got >= 0 && msg.desc_length == 1) return fd; else { @@ -71,7 +54,7 @@ int __open(const char *filename, int flags, ...) va_end(arg); } - if(should_use_rpc()) + if(nacl_should_use_rpc()) return nacl_open_rpc(filename); int result = nacl_open(filename, flags, mode); diff --git a/sysdeps/nacl/xstat64.c b/sysdeps/nacl/xstat64.c new file mode 100644 index 0000000000..a792d4f488 --- /dev/null +++ b/sysdeps/nacl/xstat64.c @@ -0,0 +1,74 @@ + +#include +#include +#include +#include + +#include +#include + + +int __have_no_stat64; /* Needed by fxstatat.c */ + + +int ___xstat64 (int vers, const char *filename, struct stat64 *buf) +{ + struct NaClImcMsgIoVec iov; + struct NaClImcMsgHdr msg; + int filename_len = strlen(filename); + char *msg_data = alloca(4 + filename_len); + memcpy(msg_data, "Stat", 4); + memcpy(msg_data + 4, filename, filename_len); + iov.base = msg_data; + iov.length = 4 + filename_len; + msg.iov = &iov; + msg.iov_length = 1; + msg.descv = NULL; + msg.desc_length = 0; + if(imc_sendmsg(NACL_COMMS_FD, &msg, 0) < 0) + return -1; + + int no_fields = 16; + char recv_data[4 + 4*no_fields + 10]; + iov.base = recv_data; + iov.length = sizeof(recv_data); + msg.descv = NULL; + msg.desc_length = 0; + int got = imc_recvmsg(NACL_COMMS_FD, &msg, 0); + if(got == 4 + 4*no_fields && memcmp(recv_data, "Rsta", 4) == 0) { + int *fields = (int *) (recv_data + 4); + buf->st_dev = fields[0]; + buf->st_ino = fields[1]; + buf->st_mode = fields[2]; + buf->st_nlink = fields[3]; + buf->st_uid = fields[4]; + buf->st_gid = fields[5]; + buf->st_rdev = fields[6]; + buf->st_size = fields[7]; + buf->st_blksize = fields[8]; + buf->st_blocks = fields[9]; + buf->st_atim.tv_sec = fields[10]; + buf->st_atim.tv_nsec = fields[11]; + buf->st_mtim.tv_sec = fields[12]; + buf->st_mtim.tv_nsec = fields[13]; + buf->st_ctim.tv_sec = fields[14]; + buf->st_ctim.tv_nsec = fields[15]; + return 0; + } + else { + errno = ENOENT; + return -1; + } +} + +#include + +#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) +versioned_symbol (libc, ___xstat64, __xstat64, GLIBC_2_2); +strong_alias (___xstat64, __old__xstat64) +compat_symbol (libc, __old__xstat64, __xstat64, GLIBC_2_1); +hidden_ver (___xstat64, __xstat64) +#else +strong_alias (___xstat64, __xstat64) +hidden_def (__xstat64) +#endif