patches/uClibc/0.9.30.2/220-fstatat-fix-up-behavior-on-32-64-bit-hosts.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Wed Jul 28 21:32:42 2010 +0200 (2010-07-28)
changeset 2040 c0162f201864
permissions -rw-r--r--
config: allow unconditional usage of tristates
     1 From d43f068e84513ed88392df4ca27d49ad01145fd2 Mon Sep 17 00:00:00 2001
     2 From: Mike Frysinger <vapier@gentoo.org>
     3 Date: Sun, 6 Sep 2009 12:12:12 -0400
     4 Subject: [PATCH 07/15] fstatat: fix up behavior on 32/64 bit hosts
     5 MIME-Version: 1.0
     6 Content-Type: text/plain; charset=UTF-8
     7 Content-Transfer-Encoding: 8bit
     8 
     9 The fstatat() syscall is a little funky in that it sometimes changes name
    10 between 32 and 64 bit hosts, but it should always operate on a 64bit stat
    11 structure.  So for the fstatat() function, make sure we convert it from a
    12 64bit kstat to a 32bit stat.
    13 
    14 Along these lines, we need to restore the __xstat32_conv() function.
    15 
    16 Reported-by: Timo Teräs <timo.teras@iki.fi>
    17 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
    18 Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
    19 ---
    20  libc/sysdeps/linux/common/fstatat.c   |    9 +++++++--
    21  libc/sysdeps/linux/common/fstatat64.c |    5 +++++
    22  libc/sysdeps/linux/common/xstatconv.c |   19 +++++++++++++++++++
    23  libc/sysdeps/linux/common/xstatconv.h |    1 +
    24  4 files changed, 32 insertions(+), 2 deletions(-)
    25 
    26 diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c
    27 index 149c189..33daa7c 100644
    28 --- a/libc/sysdeps/linux/common/fstatat.c
    29 +++ b/libc/sysdeps/linux/common/fstatat.c
    30 @@ -10,15 +10,20 @@
    31  #include <sys/stat.h>
    32  #include "xstatconv.h"
    33  
    34 +/* 64bit ports tend to favor newfstatat() */
    35 +#ifdef __NR_newfstatat
    36 +# define __NR_fstatat64 __NR_newfstatat
    37 +#endif
    38 +
    39  #ifdef __NR_fstatat64
    40  int fstatat(int fd, const char *file, struct stat *buf, int flag)
    41  {
    42  	int ret;
    43 -	struct kernel_stat kbuf;
    44 +	struct kernel_stat64 kbuf;
    45  
    46  	ret = INLINE_SYSCALL(fstatat64, 4, fd, file, &kbuf, flag);
    47  	if (ret == 0)
    48 -		__xstat_conv(&kbuf, buf);
    49 +		__xstat32_conv(&kbuf, buf);
    50  
    51  	return ret;
    52  }
    53 diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c
    54 index 5ae1fad..95627af 100644
    55 --- a/libc/sysdeps/linux/common/fstatat64.c
    56 +++ b/libc/sysdeps/linux/common/fstatat64.c
    57 @@ -12,6 +12,11 @@
    58  
    59  #ifdef __UCLIBC_HAS_LFS__
    60  
    61 +/* 64bit ports tend to favor newfstatat() */
    62 +#ifdef __NR_newfstatat
    63 +# define __NR_fstatat64 __NR_newfstatat
    64 +#endif
    65 +
    66  #ifdef __NR_fstatat64
    67  int fstatat64(int fd, const char *file, struct stat64 *buf, int flag)
    68  {
    69 diff --git a/libc/sysdeps/linux/common/xstatconv.c b/libc/sysdeps/linux/common/xstatconv.c
    70 index e575b26..50455c6 100644
    71 --- a/libc/sysdeps/linux/common/xstatconv.c
    72 +++ b/libc/sysdeps/linux/common/xstatconv.c
    73 @@ -46,6 +46,25 @@ void attribute_hidden __xstat_conv(struct kernel_stat *kbuf, struct stat *buf)
    74  	buf->st_ctim = kbuf->st_ctim;
    75  }
    76  
    77 +void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf)
    78 +{
    79 +	/* Convert to current kernel version of `struct stat64'. */
    80 +	memset(buf, 0x00, sizeof(*buf));
    81 +	buf->st_dev = kbuf->st_dev;
    82 +	buf->st_ino = kbuf->st_ino;
    83 +	buf->st_mode = kbuf->st_mode;
    84 +	buf->st_nlink = kbuf->st_nlink;
    85 +	buf->st_uid = kbuf->st_uid;
    86 +	buf->st_gid = kbuf->st_gid;
    87 +	buf->st_rdev = kbuf->st_rdev;
    88 +	buf->st_size = kbuf->st_size;
    89 +	buf->st_blksize = kbuf->st_blksize;
    90 +	buf->st_blocks = kbuf->st_blocks;
    91 +	buf->st_atim = kbuf->st_atim;
    92 +	buf->st_mtim = kbuf->st_mtim;
    93 +	buf->st_ctim = kbuf->st_ctim;
    94 +}
    95 +
    96  #ifdef __UCLIBC_HAS_LFS__
    97  
    98  void attribute_hidden __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf)
    99 diff --git a/libc/sysdeps/linux/common/xstatconv.h b/libc/sysdeps/linux/common/xstatconv.h
   100 index 57c8bcb..7568da8 100644
   101 --- a/libc/sysdeps/linux/common/xstatconv.h
   102 +++ b/libc/sysdeps/linux/common/xstatconv.h
   103 @@ -26,6 +26,7 @@
   104  #include <bits/kernel_stat.h>
   105  
   106  extern void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf) attribute_hidden;
   107 +extern void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf) attribute_hidden;
   108  #if defined __UCLIBC_HAS_LFS__
   109  extern void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf) attribute_hidden;
   110  #endif
   111 -- 
   112 1.6.6.1
   113