Implement stat64() via NaCl RPC
authorMark Seaborn <mrs@mythic-beasts.com>
Tue, 2 Jun 2009 20:43:06 +0000 (2 21:43 +0100)
committerMark Seaborn <mrs@mythic-beasts.com>
Tue, 2 Jun 2009 20:43:06 +0000 (2 21:43 +0100)
Split some RPC-related code out of open.c into nacl_rpc.c

sysdeps/nacl/Makefile [new file with mode: 0644]
sysdeps/nacl/nacl_rpc.c [new file with mode: 0644]
sysdeps/nacl/nacl_rpc.h [new file with mode: 0644]
sysdeps/nacl/open.c
sysdeps/nacl/xstat64.c [new file with mode: 0644]

diff --git a/sysdeps/nacl/Makefile b/sysdeps/nacl/Makefile
new file mode 100644 (file)
index 0000000..6f84dc4
--- /dev/null
@@ -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 (file)
index 0000000..41559f8
--- /dev/null
@@ -0,0 +1,30 @@
+
+#include <stdlib.h>
+
+#include <nacl_rpc.h>
+
+
+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 (file)
index 0000000..684a24b
--- /dev/null
@@ -0,0 +1,22 @@
+
+#ifndef _NACL_RPC_H
+#define _NACL_RPC_H
+
+#include <libc-symbols.h>
+
+#include <nacl_syscalls.h>
+
+
+#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
index 36dab5d..6dd4305 100644 (file)
@@ -2,33 +2,16 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
+#include <string.h>
 #include <sysdep.h>
 #include <unistd.h>
 
+#include <nacl_rpc.h>
 #include <nacl_syscalls.h>
 
 
-#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 (file)
index 0000000..a792d4f
--- /dev/null
@@ -0,0 +1,74 @@
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <nacl_rpc.h>
+#include <nacl_syscalls.h>
+
+
+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 <shlib-compat.h>
+
+#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