summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@hack.frob.com>2013-05-01 09:29:44 -0700
committerRoland McGrath <roland@hack.frob.com>2013-05-01 09:29:44 -0700
commita37755b1e65ba7e1ecf27af2cad0afc20945d1ab (patch)
tree2872defb7e73582f72e01918719306aa4ba29a14
parentf5a945dc57ca51b644618743dff37ae44ac2cb4f (diff)
downloadglibc-a37755b1e65ba7e1ecf27af2cad0afc20945d1ab.tar.gz
glibc-a37755b1e65ba7e1ecf27af2cad0afc20945d1ab.tar.xz
glibc-a37755b1e65ba7e1ecf27af2cad0afc20945d1ab.zip
Handle stat, massaging irt.h
-rw-r--r--sysdeps/nacl/Makefile11
-rw-r--r--sysdeps/nacl/bits/stat.h147
-rw-r--r--sysdeps/nacl/clock.c2
-rw-r--r--sysdeps/nacl/irt.sed10
-rw-r--r--sysdeps/nacl/nacl-interfaces.h30
-rw-r--r--sysdeps/nacl/xstat.c45
-rw-r--r--sysdeps/nacl/xstatconv.c67
-rw-r--r--sysdeps/nacl/xstatconv.h35
8 files changed, 345 insertions, 2 deletions
diff --git a/sysdeps/nacl/Makefile b/sysdeps/nacl/Makefile
index 01a5fe0e3c..55e763d061 100644
--- a/sysdeps/nacl/Makefile
+++ b/sysdeps/nacl/Makefile
@@ -22,6 +22,13 @@ $(common-objpfx)stamp-errnos: $(nacl)/errnos.awk $(..)manual/errno.texi \
 common-generated += stamp-errnos bits/errno.h
 before-compile += $(bits-errno)
 
+nacl-irt.h = $(common-objpfx)nacl-irt.h
+$(nacl-irt.h): $(nacl)/irt.sed $(naclsrc)/untrusted/irt/irt.h
+	sed -f $^ > $@.new
+	mv -f $@.new $@
+common-generated += nacl-irt.h
+before-compile += $(nacl-irt.h)
+
 ifeq ($(subdir),misc)
 
 $(objpfx)nacl-interfaces.v.i: $(nacl)/nacl-interfaces.mk.in \
@@ -69,3 +76,7 @@ $(common-objpfx)bits/mman-linux.h: \
 others += hello
 
 endif
+
+ifeq ($(subdir),io)
+sysdep_routines += xstatconv
+endif
diff --git a/sysdeps/nacl/bits/stat.h b/sysdeps/nacl/bits/stat.h
new file mode 100644
index 0000000000..1fed4711ae
--- /dev/null
+++ b/sysdeps/nacl/bits/stat.h
@@ -0,0 +1,147 @@
+/* 'struct stat' and related definitions.  NaCl version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if !defined _SYS_STAT_H && !defined _FCNTL_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#ifndef _BITS_STAT_H
+#define _BITS_STAT_H	1
+
+/* Versions of the `struct stat' data structure.  */
+#define _STAT_VER_NACL		0
+#define _STAT_VER_LINUX		1
+
+#define _STAT_VER		_STAT_VER_LINUX
+
+struct stat
+  {
+    __dev_t st_dev;		/* Device.  */
+    __ino_t st_ino;		/* File serial number.	*/
+    __nlink_t st_nlink;		/* Link count.  */
+    __mode_t st_mode;		/* File mode.  */
+    __uid_t st_uid;		/* User ID of the file's owner.	*/
+    __gid_t st_gid;		/* Group ID of the file's group.*/
+    int __pad0;
+    __dev_t st_rdev;		/* Device number, if device.  */
+    __off_t st_size;		/* Size of file, in bytes.  */
+    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
+    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+#if defined __USE_MISC || defined __USE_XOPEN2K8
+    /* Nanosecond resolution timestamps are stored in a format
+       equivalent to 'struct timespec'.  This is the type used
+       whenever possible but the Unix namespace rules do not allow the
+       identifier 'timespec' to appear in the <sys/stat.h> header.
+       Therefore we have to handle the use of this header in strictly
+       standard-compliant sources special.  */
+    struct timespec st_atim;		/* Time of last access.  */
+    struct timespec st_mtim;		/* Time of last modification.  */
+    struct timespec st_ctim;		/* Time of last status change.  */
+# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+    __time_t st_atime;			/* Time of last access.  */
+    __uint64_t st_atimensec;            /* Nsecs of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    __uint64_t st_mtimensec;            /* Nsecs of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+    __uint64_t st_ctimensec;            /* Nsecs of last status change.  */
+#endif
+    __int64_t __unused[3];
+  };
+
+#ifdef __USE_LARGEFILE64
+/* Note stat64 has the same shape as stat for NaCl.  */
+struct stat64
+  {
+    __dev_t st_dev;		/* Device.  */
+    __ino_t st_ino;		/* File serial number.	*/
+    __nlink_t st_nlink;		/* Link count.  */
+    __mode_t st_mode;		/* File mode.  */
+    __uid_t st_uid;		/* User ID of the file's owner.	*/
+    __gid_t st_gid;		/* Group ID of the file's group.*/
+    int __pad0;
+    __dev_t st_rdev;		/* Device number, if device.  */
+    __off_t st_size;		/* Size of file, in bytes.  */
+    __blksize_t st_blksize;	/* Optimal block size for I/O.  */
+    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+# if defined __USE_MISC || defined __USE_XOPEN2K8
+    /* Nanosecond resolution timestamps are stored in a format
+       equivalent to 'struct timespec'.  This is the type used
+       whenever possible but the Unix namespace rules do not allow the
+       identifier 'timespec' to appear in the <sys/stat.h> header.
+       Therefore we have to handle the use of this header in strictly
+       standard-compliant sources special.  */
+    struct timespec st_atim;		/* Time of last access.  */
+    struct timespec st_mtim;		/* Time of last modification.  */
+    struct timespec st_ctim;		/* Time of last status change.  */
+#  define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+#  define st_mtime st_mtim.tv_sec
+#  define st_ctime st_ctim.tv_sec
+# else
+    __time_t st_atime;			/* Time of last access.  */
+    __uint64_t st_atimensec;            /* Nsecs of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    __uint64_t st_mtimensec;            /* Nsecs of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+    __uint64_t st_ctimensec;            /* Nsecs of last status change.  */
+# endif
+    __int64_t __unused[3];
+  };
+#endif
+
+/* Tell code we have these members.  */
+#define	_STATBUF_ST_BLKSIZE	1
+#define _STATBUF_ST_RDEV	1
+/* Nanosecond resolution time values are supported.  */
+#define _STATBUF_ST_NSEC	1
+
+/* Encoding of the file mode.  */
+
+#define	__S_IFMT	0170000	/* These bits determine file type.  */
+
+/* File types.  */
+#define	__S_IFDIR	0040000	/* Directory.  */
+#define	__S_IFCHR	0020000	/* Character device.  */
+#define	__S_IFBLK	0060000	/* Block device.  */
+#define	__S_IFREG	0100000	/* Regular file.  */
+#define	__S_IFIFO	0010000	/* FIFO.  */
+#define	__S_IFLNK	0120000	/* Symbolic link.  */
+#define	__S_IFSOCK	0140000	/* Socket.  */
+
+/* POSIX.1b objects.  Note that these macros always evaluate to zero.  But
+   they do it by enforcing the correct use of the macros.  */
+#define __S_TYPEISMQ(buf)  ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits.  */
+
+#define	__S_ISUID	04000	/* Set user ID on execution.  */
+#define	__S_ISGID	02000	/* Set group ID on execution.  */
+#define	__S_ISVTX	01000	/* Save swapped text after use (sticky).  */
+#define	__S_IREAD	0400	/* Read by owner.  */
+#define	__S_IWRITE	0200	/* Write by owner.  */
+#define	__S_IEXEC	0100	/* Execute by owner.  */
+
+#ifdef __USE_ATFILE
+/* XXX missing: UTIME_NOW, UTIME_OMIT */
+#endif
+
+#endif	/* bits/stat.h */
diff --git a/sysdeps/nacl/clock.c b/sysdeps/nacl/clock.c
index 196608f28a..35805991bf 100644
--- a/sysdeps/nacl/clock.c
+++ b/sysdeps/nacl/clock.c
@@ -24,6 +24,6 @@
 clock_t
 clock (void)
 {
-  clock_t result;
+  nacl_abi_clock_t result;
   return NACL_CALL (__nacl_irt_basic.clock (&result), result);
 }
diff --git a/sysdeps/nacl/irt.sed b/sysdeps/nacl/irt.sed
new file mode 100644
index 0000000000..ff9f642eec
--- /dev/null
+++ b/sysdeps/nacl/irt.sed
@@ -0,0 +1,10 @@
+# This sed script massages native_client/src/untrusted/irt/irt.h into
+# the nacl-irt.h used to build libc, by rewriting foo_t and struct bar
+# to nacl_abi_foo_t and nacl_abi_bar_t (and eliding forward declarations).
+# It doesn't perturb any struct CamelCaps cases, since such names will
+# be used only in NaCl-specific interfaces.
+/^struct \([a-z][a-z]*\);$/d
+/(/!b
+s/\([a-z0-9_][a-z0-9_]*\)_t\>/nacl_abi_\1_t/g
+s/struct \([a-z0-9_][a-z0-9_]*\)/nacl_abi_\1_t/g
+s/nacl_abi_\(u*int[3264]*_t\)/\1/g
diff --git a/sysdeps/nacl/nacl-interfaces.h b/sysdeps/nacl/nacl-interfaces.h
index c4461f8e7d..04545a5275 100644
--- a/sysdeps/nacl/nacl-interfaces.h
+++ b/sysdeps/nacl/nacl-interfaces.h
@@ -23,8 +23,36 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <ldsodefs.h>
+#include <sys/types.h>
 
-#include <native_client/src/untrusted/irt/irt.h>
+/* <nacl-irt.h> is massaged from native_client/src/untrusted/irt/irt.h so
+   that it uses nacl_abi_*_t type names.  We must define those types first.  */
+
+/* These are the same in the IRT ABI as in the libc ABI.  */
+typedef blksize_t nacl_abi_blksize_t;
+typedef clockid_t nacl_abi_clockid_t;
+typedef dev_t nacl_abi_dev_t;
+typedef gid_t nacl_abi_gid_t;
+typedef ino_t nacl_abi_ino_t;
+typedef mode_t nacl_abi_mode_t;
+typedef nlink_t nacl_abi_nlink_t;
+typedef off_t nacl_abi_off_t;
+typedef size_t nacl_abi_size_t;
+typedef time_t nacl_abi_time_t;
+typedef uid_t nacl_abi_uid_t;
+typedef struct dirent nacl_abi_dirent_t;
+typedef struct timeval nacl_abi_timeval_t;
+typedef struct timespec nacl_abi_timespec_t;
+
+/* XXX change clock_t? */
+typedef uint32_t nacl_abi_clock_t;
+
+typedef int32_t nacl_abi_blkcnt_t;
+
+/* This is different by design.  */
+typedef struct nacl_abi_stat nacl_abi_stat_t;
+
+#include <nacl-irt.h>
 
 /* This is how we access the IRT interface-query function.
    This formulation makes it usable as if it were a function name.  */
diff --git a/sysdeps/nacl/xstat.c b/sysdeps/nacl/xstat.c
new file mode 100644
index 0000000000..d4c0045aba
--- /dev/null
+++ b/sysdeps/nacl/xstat.c
@@ -0,0 +1,45 @@
+/* Get stat information from a file name.  NaCl version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Avoid the declaration so the compiler doesn't complain about the alias
+   with a different type signature.  It doesn't know that 'struct stat'
+   and 'struct stat64' are ABI-compatible.  */
+#define __xstat64 __xstat64_avoid
+#include <sys/stat.h>
+#undef  __xstat64
+
+#include <errno.h>
+#include <stddef.h>
+
+#include <xstatconv.h>
+
+#undef  stat
+
+/* Get file information about FILE in BUF.  */
+int
+__xstat (int vers, const char *file, struct stat *buf)
+{
+  nacl_abi_stat_t abi_buf;
+  return NACL_CALL (__nacl_irt_filename.stat (file, &abi_buf),
+                    __xstat_conv (vers, &abi_buf, buf));
+}
+hidden_def (__xstat)
+weak_alias (__xstat, _xstat)
+
+strong_alias (__xstat, __xstat64)
+hidden_def (__xstat64)
diff --git a/sysdeps/nacl/xstatconv.c b/sysdeps/nacl/xstatconv.c
new file mode 100644
index 0000000000..6f4cceed78
--- /dev/null
+++ b/sysdeps/nacl/xstatconv.c
@@ -0,0 +1,67 @@
+/* Convert between the NaCl ABI's `struct stat' format, and libc's.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+#include <sys/stat.h>
+#include <xstatconv.h>
+
+internal_function
+int
+__xstat_conv (int vers, const struct nacl_abi_stat *kbuf, void *ubuf)
+{
+  switch (vers)
+    {
+    case _STAT_VER_NACL:
+      /* Nothing to do.  The struct is in the form the NaCl ABI expects.  */
+      *(struct nacl_abi_stat *) ubuf = *kbuf;
+      break;
+
+    case _STAT_VER_LINUX:
+      {
+        struct stat *buf = ubuf;
+
+        /* Zero-fill the pad/unused fields.  */
+        memset (buf, 0, sizeof *buf);
+
+        /* Convert from NaCl IRT ABI `struct stat'.  */
+        buf->st_dev = kbuf->nacl_abi_st_dev;
+        buf->st_ino = kbuf->nacl_abi_st_ino;
+        buf->st_mode = kbuf->nacl_abi_st_mode;
+        buf->st_nlink = kbuf->nacl_abi_st_nlink;
+        buf->st_uid = kbuf->nacl_abi_st_uid;
+        buf->st_gid = kbuf->nacl_abi_st_gid;
+        buf->st_rdev = kbuf->nacl_abi_st_rdev;
+        buf->st_size = kbuf->nacl_abi_st_size;
+        buf->st_blksize = kbuf->nacl_abi_st_blksize;
+        buf->st_blocks = kbuf->nacl_abi_st_blocks;
+        buf->st_atim.tv_sec = kbuf->nacl_abi_st_atime;
+        buf->st_atim.tv_nsec = kbuf->nacl_abi_st_atimensec;
+        buf->st_mtim.tv_sec = kbuf->nacl_abi_st_mtime;
+        buf->st_mtim.tv_nsec = kbuf->nacl_abi_st_mtimensec;
+        buf->st_ctim.tv_sec = kbuf->nacl_abi_st_ctime;
+        buf->st_ctim.tv_nsec = kbuf->nacl_abi_st_ctimensec;
+      }
+      break;
+
+    default:
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  return 0;
+}
diff --git a/sysdeps/nacl/xstatconv.h b/sysdeps/nacl/xstatconv.h
new file mode 100644
index 0000000000..06ab66a64f
--- /dev/null
+++ b/sysdeps/nacl/xstatconv.h
@@ -0,0 +1,35 @@
+/* Convert between the NaCl ABI's `struct stat' format, and libc's.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <nacl-interfaces.h>
+
+struct stat;
+
+/* We use this header to define struct nacl_abi_stat.  But we must avoid
+   its excess declarations, and defining these names away is (marginally)
+   cleaner than #undef'ing __native_client__.  */
+#undef  stat
+#define stat    __avoid_nacl_stat
+#undef  fstat
+#define fstat   __avoid_nacl_fstat
+#include <native_client/src/trusted/service_runtime/include/sys/stat.h>
+#undef  stat
+#undef  fstat
+
+extern int __xstat_conv (int vers, const struct nacl_abi_stat *, void *)
+  internal_function attribute_hidden;