Mercurial > gub
changeset 5153:df81ae7d9c8b
librestrict: Add linux-2.6-i686 stat support.
author | Jan Nieuwenhuizen <janneke@gnu.org> |
---|---|
date | Mon, 16 Feb 2009 14:49:42 +0100 |
parents | 449189cf5824 |
children | e366616c0120 8602011649e7 |
files | librestrict/GNUmakefile librestrict/TODO librestrict/kernel-features.h librestrict/kernel_stat.h librestrict/restrict-stat.c librestrict/xstatconv.c librestrict/xstatconv.h |
diffstat | 7 files changed, 838 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/librestrict/GNUmakefile Sun Feb 15 21:29:26 2009 +0100 +++ b/librestrict/GNUmakefile Mon Feb 16 14:49:42 2009 +0100 @@ -2,7 +2,7 @@ CC = gcc NM = nm -CFLAGS = -W -Wall +CFLAGS = -W -Wall -I . ALL_CFLAGS = $(CFLAGS) INSTALL = install
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librestrict/TODO Mon Feb 16 14:49:42 2009 +0100 @@ -0,0 +1,12 @@ +Fix the struct stat64/LARGEFILE/ configure mess, get rid of + + /* FIXME: CONFIG? */ + +xstat is verified to work on two linux boxes + + Linux heerbeest 2.6.28-7-generic #20-Ubuntu SMP Mon Feb 9 15:42:34 UTC 2009 x86_64 GNU/Linux + ii libc6 2.9-0ubuntu9 GNU C Library: Shared libraries + + Linux abc 2.6.26.webdev.nl #1 SMP Sat Jan 10 23:39:09 CET 2009 i686 GNU/Linux + ii libc6 2.7-18 GNU C Library: Shared libraries +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librestrict/kernel-features.h Mon Feb 16 14:49:42 2009 +0100 @@ -0,0 +1,430 @@ +/* Set flags signalling availability of kernel features based on given + kernel version number. + Copyright (C) 1999-2003, 2004 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file must not contain any C code. At least it must be protected + to allow using the file also in assembler files. */ + +#if defined __mips__ +# include <sgidefs.h> +#endif + +#ifndef __LINUX_KERNEL_VERSION +/* We assume the worst; all kernels should be supported. */ +# define __LINUX_KERNEL_VERSION 0 +#endif + +/* We assume for __LINUX_KERNEL_VERSION the same encoding used in + linux/version.h. I.e., the major, minor, and subminor all get a + byte with the major number being in the highest byte. This means + we can do numeric comparisons. + + In the following we will define certain symbols depending on + whether the describes kernel feature is available in the kernel + version given by __LINUX_KERNEL_VERSION. We are not always exactly + recording the correct versions in which the features were + introduced. If somebody cares these values can afterwards be + corrected. Most of the numbers here are set corresponding to + 2.2.0. */ + +/* `getcwd' system call. */ +#if __LINUX_KERNEL_VERSION >= 131584 +# define __ASSUME_GETCWD_SYSCALL 1 +#endif + +/* Real-time signal became usable in 2.1.70. */ +#if __LINUX_KERNEL_VERSION >= 131398 +# define __ASSUME_REALTIME_SIGNALS 1 +#endif + +/* When were the `pread'/`pwrite' syscalls introduced? */ +#if __LINUX_KERNEL_VERSION >= 131584 +# define __ASSUME_PREAD_SYSCALL 1 +# define __ASSUME_PWRITE_SYSCALL 1 +#endif + +/* When was `poll' introduced? */ +#if __LINUX_KERNEL_VERSION >= 131584 +# define __ASSUME_POLL_SYSCALL 1 +#endif + +/* The `lchown' syscall was introduced in 2.1.80. */ +#if __LINUX_KERNEL_VERSION >= 131408 +# define __ASSUME_LCHOWN_SYSCALL 1 +#endif + +/* When did the `setresuid' sysall became available? */ +#if __LINUX_KERNEL_VERSION >= 131584 && !defined __sparc__ +# define __ASSUME_SETRESUID_SYSCALL 1 +#endif + +/* The SIOCGIFNAME ioctl is available starting with 2.1.50. */ +#if __LINUX_KERNEL_VERSION >= 131408 +# define __ASSUME_SIOCGIFNAME 1 +#endif + +/* MSG_NOSIGNAL was at least available with Linux 2.2.0. */ +#if __LINUX_KERNEL_VERSION >= 131584 +# define __ASSUME_MSG_NOSIGNAL 1 +#endif + +/* On x86 another `getrlimit' syscall was added in 2.3.25. */ +#if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__ +# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 +#endif + +/* On x86 the truncate64/ftruncate64 syscalls were introduced in 2.3.31. */ +#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ +# define __ASSUME_TRUNCATE64_SYSCALL 1 +#endif + +/* On x86 the mmap2 syscall was introduced in 2.3.31. */ +#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ +# define __ASSUME_MMAP2_SYSCALL 1 +#endif + +/* On x86 the stat64/lstat64/fstat64 syscalls were introduced in 2.3.34. */ +#if __LINUX_KERNEL_VERSION >= 131874 && defined __i386__ +# define __ASSUME_STAT64_SYSCALL 1 +#endif + +/* On sparc and ARM the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64 + syscalls were introduced in 2.3.35. */ +#if __LINUX_KERNEL_VERSION >= 131875 && (defined __sparc__ || defined __arm__) +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_MMAP2_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +#endif + +/* I know for sure that getrlimit are in 2.3.35 on powerpc. */ +#if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ +# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 +#endif + +/* I know for sure that these are in 2.3.35 on powerpc. But PowerPC64 does not + support separate 64-bit syscalls, already 64-bit */ +#if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ \ + && !defined __powerpc64__ +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +#endif + +/* Linux 2.3.39 introduced 32bit UID/GIDs. Some platforms had 32 + bit type all along. */ +#if __LINUX_KERNEL_VERSION >= 131879 || defined __powerpc__ || defined __mips__ +# define __ASSUME_32BITUIDS 1 +#endif + +/* Linux 2.3.39 sparc added setresuid. */ +#if __LINUX_KERNEL_VERSION >= 131879 && defined __sparc__ +# define __ASSUME_SETRESUID_SYSCALL 1 +#endif + +#if __LINUX_KERNEL_VERSION >= 131879 +# define __ASSUME_SETRESGID_SYSCALL 1 +#endif + +/* Linux 2.3.39 introduced IPC64. Except for powerpc. */ +#if __LINUX_KERNEL_VERSION >= 131879 && !defined __powerpc__ +# define __ASSUME_IPC64 1 +#endif + +/* MIPS platforms had IPC64 all along. */ +#if defined __mips__ +# define __ASSUME_IPC64 1 +#endif + +/* We can use the LDTs for threading with Linux 2.3.99 and newer. */ +#if __LINUX_KERNEL_VERSION >= 131939 +# define __ASSUME_LDT_WORKS 1 +#endif + +/* Linux 2.4.0 on PPC introduced a correct IPC64. But PowerPC64 does not + support a separate 64-bit sys call, already 64-bit */ +#if __LINUX_KERNEL_VERSION >= 132096 && defined __powerpc__ \ + && !defined __powerpc64__ +# define __ASSUME_IPC64 1 +#endif + +/* SH kernels got stat64, mmap2, and truncate64 during 2.4.0-test. */ +#if __LINUX_KERNEL_VERSION >= 132096 && defined __sh__ +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_MMAP2_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +#endif + +/* The changed st_ino field appeared in 2.4.0-test6. But we cannot + distinguish this version from other 2.4.0 releases. Therefore play + save and assume it available is for 2.4.1 and up. However, SH is lame, + and still does not have a 64-bit inode field. */ +#if __LINUX_KERNEL_VERSION >= 132097 && !defined __alpha__ && !defined __sh__ +# define __ASSUME_ST_INO_64_BIT 1 +#endif + +/* To support locking of large files a new fcntl() syscall was introduced + in 2.4.0-test7. We test for 2.4.1 for the earliest version we know + the syscall is available. */ +#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __sparc__) +# define __ASSUME_FCNTL64 1 +#endif + +/* The AT_CLKTCK auxiliary vector entry was introduction in the 2.4.0 + series. */ +#if __LINUX_KERNEL_VERSION >= 132097 +# define __ASSUME_AT_CLKTCK 1 +#endif + +/* Arm got fcntl64 in 2.4.4, PowerPC and SH have it also in 2.4.4 (I + don't know when it got introduced). But PowerPC64 does not support + separate FCNTL64 call, FCNTL is already 64-bit */ +#if __LINUX_KERNEL_VERSION >= 132100 \ + && (defined __arm__ || defined __powerpc__ || defined __sh__) \ + && !defined __powerpc64__ +# define __ASSUME_FCNTL64 1 +#endif + +/* The getdents64 syscall was introduced in 2.4.0-test7. We test for + 2.4.1 for the earliest version we know the syscall is available. */ +#if __LINUX_KERNEL_VERSION >= 132097 +# define __ASSUME_GETDENTS64_SYSCALL 1 +#endif + +/* When did O_DIRECTORY became available? Early in 2.3 but when? + Be safe, use 2.3.99. */ +#if __LINUX_KERNEL_VERSION >= 131939 +# define __ASSUME_O_DIRECTORY 1 +#endif + +/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes + up the page size information. */ +#if __LINUX_KERNEL_VERSION >= 132097 +# define __ASSUME_AT_PAGESIZE 1 +#endif + +/* Starting with at least 2.4.0 the kernel passes the uid/gid unconditionally + up to the child. */ +#if __LINUX_KERNEL_VERSION >= 132097 +# define __ASSUME_AT_XID 1 +#endif + +/* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way + and the vfork syscall made it into the official kernel. */ +#if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__ +# define __ASSUME_STD_AUXV 1 +# define __ASSUME_VFORK_SYSCALL 1 +#endif + +/* Starting with 2.4.5 kernels the mmap2 syscall made it into the official + kernel. But PowerPC64 does not support a separate MMAP2 call. */ +#if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__ \ + && !defined __powerpc64__ +# define __ASSUME_MMAP2_SYSCALL 1 +#endif + +/* Starting with 2.4.21 PowerPC implements the new prctl syscall. + This allows applications to get/set the Floating Point Exception Mode. */ +#if __LINUX_KERNEL_VERSION >= (132096+21) && defined __powerpc__ +# define __ASSUME_NEW_PRCTL_SYSCALL 1 +#endif + +/* Starting with 2.4.21 the PowerPC32 clone syscall works as expected. */ +#if __LINUX_KERNEL_VERSION >= (132096+21) && defined __powerpc__ \ + && !defined __powerpc64__ +# define __ASSUME_FIXED_CLONE_SYSCALL 1 +#endif + +/* Starting with 2.4.21 PowerPC64 implements the new rt_sigreturn syscall. + The new rt_sigreturn takes an ucontext pointer allowing rt_sigreturn + to be used in the set/swapcontext implementation. */ +#if __LINUX_KERNEL_VERSION >= (132096+21) && defined __powerpc64__ +# define __ASSUME_NEW_RT_SIGRETURN_SYSCALL 1 +#endif + +/* On x86, the set_thread_area syscall was introduced in 2.5.29, but its + semantics was changed in 2.5.30, and again after 2.5.31. */ +#if __LINUX_KERNEL_VERSION >= 132384 && defined __i386__ +# define __ASSUME_SET_THREAD_AREA_SYSCALL 1 +#endif + +/* The vfork syscall on x86 and arm was definitely available in 2.4. */ +#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __arm__) +# define __ASSUME_VFORK_SYSCALL 1 +#endif + +/* There are an infinite number of PA-RISC kernel versions numbered + 2.4.0. But they've not really been released as such. We require + and expect the final version here. */ +#ifdef __hppa__ +# define __ASSUME_32BITUIDS 1 +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_MMAP2_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +# define __ASSUME_IPC64 1 +# define __ASSUME_ST_INO_64_BIT 1 +# define __ASSUME_FCNTL64 1 +# define __ASSUME_GETDENTS64_SYSCALL 1 +#endif + +/* Alpha switched to a 64-bit timeval sometime before 2.2.0. */ +#if __LINUX_KERNEL_VERSION >= 131584 && defined __alpha__ +# define __ASSUME_TIMEVAL64 1 +#endif + +#if defined __mips__ && _MIPS_SIM == _ABIN32 +# define __ASSUME_FCNTL64 1 +#endif + +/* The late 2.5 kernels saw a lot of new CLONE_* flags. Summarize + their availability with one define. The changes were made first + for i386 and the have to be done separately for the other archs. + For i386 we pick 2.5.50 as the first version with support. */ +#if __LINUX_KERNEL_VERSION >= 132402 && defined __i386__ +# define __ASSUME_CLONE_THREAD_FLAGS 1 +#endif + +/* These features were surely available with 2.4.12. */ +#if __LINUX_KERNEL_VERSION >= 132108 && defined __mc68000__ +# define __ASSUME_MMAP2_SYSCALL 1 +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +# define __ASSUME_FCNTL64 1 +# define __ASSUME_VFORK_SYSCALL 1 +#endif + +/* Beginning with 2.5.63 support for realtime and monotonic clocks and + timers based on them is available. */ +#if __LINUX_KERNEL_VERSION >= 132415 +# define __ASSUME_POSIX_TIMERS 1 +#endif + +/* The late 2.5 kernels saw a lot of new CLONE_* flags. Summarize + their availability with one define. The changes were made first + for i386 and the have to be done separately for the other archs. + For ia64, s390*, PPC, x86-64 we pick 2.5.64 as the first version + with support. */ +#if __LINUX_KERNEL_VERSION >= 132416 \ + && (defined __ia64__ || defined __s390__ || defined __powerpc__ \ + || defined __x86_64__ || defined __sh__) +# define __ASSUME_CLONE_THREAD_FLAGS 1 +#endif + +/* With kernel 2.4.17 we always have netlink support. */ +#if __LINUX_KERNEL_VERSION >= (132096+17) +# define __ASSUME_NETLINK_SUPPORT 1 +#endif + +/* The requeue futex functionality was introduced in 2.5.70. */ +#if __LINUX_KERNEL_VERSION >= 132422 +# define __ASSUME_FUTEX_REQUEUE 1 +#endif + +/* The statfs64 syscalls are available in 2.5.74. */ +#if __LINUX_KERNEL_VERSION >= 132426 +# define __ASSUME_STATFS64 1 +#endif + +/* Starting with at least 2.5.74 the kernel passes the setuid-like exec + flag unconditionally up to the child. */ +#if __LINUX_KERNEL_VERSION >= 132426 +# define __ASSUME_AT_SECURE 1 +#endif + +/* Starting with the 2.5.75 kernel the kernel fills in the correct value + in the si_pid field passed as part of the siginfo_t struct to signal + handlers. */ +#if __LINUX_KERNEL_VERSION >= 132427 +# define __ASSUME_CORRECT_SI_PID 1 +#endif + +/* The tgkill syscall was instroduced for i386 in 2.5.75. For Alpha + it was introduced in 2.6.0-test1 which unfortunately cannot be + distinguished from 2.6.0. On x86-64 it was introduced in + 2.6.0-test3. */ +#if (__LINUX_KERNEL_VERSION >= 132427 && defined __i386__) \ + || (__LINUX_KERNEL_VERSION >= 132609 && defined __alpha__) \ + || (__LINUX_KERNEL_VERSION >= 132609 && defined __x86_64__) \ + || (__LINUX_KERNEL_VERSION >= 132609 && defined __sh__) +# define __ASSUME_TGKILL 1 +#endif + +/* The utimes syscall has been available for some architectures + forever. For x86 it was introduced after 2.5.75, for x86-64 in + 2.6.0-test3. */ +#if defined __alpha__ || defined __ia64__ || defined __hppa__ \ + || defined __sparc__ \ + || (__LINUX_KERNEL_VERSION > 132427 && defined __i386__) \ + || (__LINUX_KERNEL_VERSION > 132609 && defined __x86_64__) \ + || (__LINUX_KERNEL_VERSION >= 132609 && defined __sh__) +# define __ASSUME_UTIMES 1 +#endif + +// XXX Disabled for now since the semantics we want is not achieved. +#if 0 +/* The CLONE_STOPPED flag was introduced in the 2.6.0-test1 series. */ +#if __LINUX_KERNEL_VERSION >= 132609 +# define __ASSUME_CLONE_STOPPED 1 +#endif +#endif + +/* The fixed version of the posix_fadvise64 syscall appeared in + 2.6.0-test3. At least for x86. */ +#if __LINUX_KERNEL_VERSION >= 132609 && defined __i386__ +# define __ASSUME_FADVISE64_64_SYSCALL 1 +#endif + +/* The PROT_GROWSDOWN/PROT_GROWSUP flags were introduced in the 2.6.0-test + series. */ +#if __LINUX_KERNEL_VERSION >= 132609 +# define __ASSUME_PROT_GROWSUPDOWN 1 +#endif + +/* Starting with 2.6.0 PowerPC adds signal/swapcontext support for Vector + SIMD (AKA Altivec, VMX) instructions and register state. This changes + the overall size of the sigcontext and adds the swapcontext syscall. */ +#if __LINUX_KERNEL_VERSION >= 132608 && defined __powerpc__ +# define __ASSUME_SWAPCONTEXT_SYSCALL 1 +#endif + +/* The CLONE_DETACHED flag is not necessary in 2.6.2 kernels, it is + implied. */ +#if __LINUX_KERNEL_VERSION >= 132610 +# define __ASSUME_NO_CLONE_DETACHED 1 +#endif + +/* Starting with version 2.6.4-rc1 the getdents syscall returns d_type + information as well. */ +#if __LINUX_KERNEL_VERSION >= 132612 +# define __ASSUME_GETDENTS32_D_TYPE 1 +#endif + +/* Starting with version 2.5.3, the initial location returned by `brk' + after exec is always rounded up to the next page. */ +#if __LINUX_KERNEL_VERSION >= 132355 +# define __ASSUME_BRK_PAGE_ROUNDED 1 +#endif + +/* Starting with version 2.6.9, the waitid system call is available. */ +#if __LINUX_KERNEL_VERSION >= 0x020609 +# define __ASSUME_WAITID_SYSCALL 1 +#endif + +/* Starting with version 2.6.9, SSI_IEEE_RAISE_EXCEPTION exists. */ +#if __LINUX_KERNEL_VERSION >= 0x020609 && defined __alpha__ +#define __ASSUME_IEEE_RAISE_EXCEPTION 1 +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librestrict/kernel_stat.h Mon Feb 16 14:49:42 2009 +0100 @@ -0,0 +1,37 @@ +/* Definition of `struct stat' used in the kernel.. */ +struct kernel_stat + { + unsigned short int st_dev; + unsigned short int __pad1; +#define _HAVE___PAD1 + unsigned long int st_ino; + unsigned short int st_mode; + unsigned short int st_nlink; + unsigned short int st_uid; + unsigned short int st_gid; + unsigned short int st_rdev; + unsigned short int __pad2; +#define _HAVE___PAD2 + unsigned long int st_size; + unsigned long int st_blksize; + unsigned long int st_blocks; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned long int __unused4; +#define _HAVE___UNUSED4 + unsigned long int __unused5; +#define _HAVE___UNUSED5 + }; + +#define _HAVE_STAT___UNUSED4 +#define _HAVE_STAT___UNUSED5 +#define _HAVE_STAT___PAD1 +#define _HAVE_STAT___PAD2 +#define _HAVE_STAT_NSEC +#define _HAVE_STAT64___PAD1 +#define _HAVE_STAT64___PAD2 +# ifdef __USE_FILE_OFFSET64 /* FIXME: CONFIG? */ +# define _HAVE_STAT64___ST_INO +# endif +#define _HAVE_STAT64_NSEC
--- a/librestrict/restrict-stat.c Sun Feb 15 21:29:26 2009 +0100 +++ b/librestrict/restrict-stat.c Mon Feb 16 14:49:42 2009 +0100 @@ -4,6 +4,7 @@ */ +#include <stddef.h> #include <sys/stat.h> #include <sys/syscall.h> @@ -83,6 +84,49 @@ int ustat (char const *file_name, struct stat *buf) __attribute__ ((alias ("__ustat"))); #endif /* SYS_ustat */ +#ifdef __linux__ + +/* + Lifted from glibc-2.3-20070416 +*/ + +#include <errno.h> +#ifndef __set_errno +#define __set_errno(e) (errno = (e)) +#endif + +#include <kernel-features.h> +#ifdef __x86_64__ +#define STAT_IS_KERNEL_STAT 1 +#define XSTAT_IS_XSTAT64 1 +#define kernel_stat stat +#define __xstat_conv(a, b, c) 0 +#else /* !__x86_64__ */ +#define stat64 kernel_stat /* FIXME: CONFIG? */ +#include <xstatconv.c> +#endif /* !__x86_64__ */ + + +static int sys_xstat (int ver, char const *file_name, struct stat *buf) +{ +#ifdef STAT_IS_KERNEL_STAT + // if (ver == _STAT_VER_KERNEL) + if (ver == _STAT_VER_LINUX) + return syscall (SYS_stat, file_name, buf); + + errno = EINVAL; + return -1; +#else /* !STAT_IS_KERNEL_STAT */ + (void) ver; + struct kernel_stat kbuf; + int result = syscall (SYS_stat, file_name, &kbuf); + if (result == 0) + result = __xstat_conv (ver, &kbuf, buf); + + return result; +#endif /* !STAT_IS_KERNEL_STAT */ +} + int __xstat (int ver, char const *file_name, struct stat *buf) { @@ -91,7 +135,9 @@ if (!is_allowed (file_name, "xstat")) abort (); - return sys_stat (file_name, buf); + return sys_xstat (ver, file_name, buf); } int xstat (int ver, char const *file_name, struct stat *buf) __attribute__ ((alias ("__xstat"))); + +#endif /* __linux__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librestrict/xstatconv.c Mon Feb 16 14:49:42 2009 +0100 @@ -0,0 +1,285 @@ +/* Convert between the kernel's `struct stat' format, and libc's. + Copyright (C) 1991,1995-1997,2000,2002,2003 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <sys/stat.h> +#include <kernel_stat.h> + +#ifdef STAT_IS_KERNEL_STAT + +/* Dummy. */ +struct kernel_stat; + +#else + +#include <string.h> + + +#if !defined __ASSUME_STAT64_SYSCALL || defined XSTAT_IS_XSTAT64 +int +__xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) +{ + switch (vers) + { + case _STAT_VER_KERNEL: + /* Nothing to do. The struct is in the form the kernel expects. + We should have short-circuted before we got here, but for + completeness... */ + *(struct kernel_stat *) ubuf = *kbuf; + break; + + case _STAT_VER_LINUX: + { + struct stat *buf = ubuf; + + /* Convert to current kernel version of `struct stat'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE_STAT___PAD1 + buf->__pad1 = 0; +#endif + buf->st_ino = kbuf->st_ino; + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; +#ifdef _HAVE_STAT___PAD2 + buf->__pad2 = 0; +#endif + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; +#ifdef _HAVE_STAT_NSEC + buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; + buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; +#else + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#endif +#ifdef _HAVE_STAT___UNUSED1 + buf->__unused1 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED2 + buf->__unused2 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED3 + buf->__unused3 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED4 + buf->__unused4 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED5 + buf->__unused5 = 0; +#endif + } + break; + + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} +#endif + +int +__xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf) +{ +#ifdef XSTAT_IS_XSTAT64 + return __xstat_conv (vers, kbuf, ubuf); +#else + switch (vers) + { + case _STAT_VER_LINUX: + { + struct stat64 *buf = ubuf; + + /* Convert to current kernel version of `struct stat64'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE_STAT64___PAD1 + buf->__pad1 = 0; +#endif + buf->st_ino = kbuf->st_ino; +#ifdef _HAVE_STAT64___ST_INO + buf->__st_ino = kbuf->st_ino; +#endif + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; +#ifdef _HAVE_STAT64___PAD2 + buf->__pad2 = 0; +#endif + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; +#ifdef _HAVE_STAT64_NSEC + buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; + buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; +#else + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#endif +#ifdef _HAVE_STAT64___UNUSED1 + buf->__unused1 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED2 + buf->__unused2 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED3 + buf->__unused3 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED4 + buf->__unused4 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED5 + buf->__unused5 = 0; +#endif + } + break; + + /* If struct stat64 is different from struct stat then + _STAT_VER_KERNEL does not make sense. */ + case _STAT_VER_KERNEL: + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +#endif +} + +int +__xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf) +{ + switch (vers) + { + case _STAT_VER_LINUX: + { + /* Convert current kernel version of `struct stat64' to + `struct stat'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE_STAT___PAD1 + buf->__pad1 = 0; +#endif +#ifdef _HAVE_STAT64___ST_INO +# if __ASSUME_ST_INO_64_BIT == 0 + if (kbuf->st_ino == 0) + buf->st_ino = kbuf->__st_ino; + else +# endif + { + buf->st_ino = kbuf->st_ino; + if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) + && buf->st_ino != kbuf->st_ino) + { + __set_errno (EOVERFLOW); + return -1; + } + } +#else + buf->st_ino = kbuf->st_ino; + if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) + && buf->st_ino != kbuf->st_ino) + { + __set_errno (EOVERFLOW); + return -1; + } +#endif + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; +#ifdef _HAVE_STAT___PAD2 + buf->__pad2 = 0; +#endif + buf->st_size = kbuf->st_size; + /* Check for overflow. */ + if (sizeof (buf->st_size) != sizeof (kbuf->st_size) + && buf->st_size != kbuf->st_size) + { + __set_errno (EOVERFLOW); + return -1; + } + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + /* Check for overflow. */ + if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks) + && buf->st_blocks != kbuf->st_blocks) + { + __set_errno (EOVERFLOW); + return -1; + } +#ifdef _HAVE_STAT_NSEC + buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; + buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; +#else + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#endif + +#ifdef _HAVE_STAT___UNUSED1 + buf->__unused1 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED2 + buf->__unused2 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED3 + buf->__unused3 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED4 + buf->__unused4 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED5 + buf->__unused5 = 0; +#endif + } + break; + + /* If struct stat64 is different from struct stat then + _STAT_VER_KERNEL does not make sense. */ + case _STAT_VER_KERNEL: + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librestrict/xstatconv.h Mon Feb 16 14:49:42 2009 +0100 @@ -0,0 +1,26 @@ +/* Convert between the kernel's `struct stat' format, and libc's. + Copyright (C) 1991,1995-1997,2000,2002,2003 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "kernel-features.h" + +#ifndef STAT_IS_KERNEL_STAT +extern int __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf); +extern int __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf); +#endif +extern int __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf);