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
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
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.
14 Along these lines, we need to restore the __xstat32_conv() function.
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>
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(-)
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
32 #include "xstatconv.h"
34 +/* 64bit ports tend to favor newfstatat() */
35 +#ifdef __NR_newfstatat
36 +# define __NR_fstatat64 __NR_newfstatat
40 int fstatat(int fd, const char *file, struct stat *buf, int flag)
43 - struct kernel_stat kbuf;
44 + struct kernel_stat64 kbuf;
46 ret = INLINE_SYSCALL(fstatat64, 4, fd, file, &kbuf, flag);
48 - __xstat_conv(&kbuf, buf);
49 + __xstat32_conv(&kbuf, buf);
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
59 #ifdef __UCLIBC_HAS_LFS__
61 +/* 64bit ports tend to favor newfstatat() */
62 +#ifdef __NR_newfstatat
63 +# define __NR_fstatat64 __NR_newfstatat
67 int fstatat64(int fd, const char *file, struct stat64 *buf, int flag)
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;
77 +void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf)
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;
96 #ifdef __UCLIBC_HAS_LFS__
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
104 #include <bits/kernel_stat.h>
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;