diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-09-06 12:12:12 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-09-06 12:12:12 -0400 |
commit | 656167d89112171b2b7672676dc413c676a186f5 (patch) | |
tree | 8d2ce21d6a1ea1ce36f5cb8344b5a1bb398dc147 /libc/sysdeps/linux/common | |
parent | 3411040a7bc9c04221c6483f36cbd85a06c3bb60 (diff) |
fstatat: fix up behavior on 32/64 bit hosts
The fstatat() syscall is a little funky in that it sometimes changes name
between 32 and 64 bit hosts, but it should always operate on a 64bit stat
structure. So for the fstatat() function, make sure we convert it from a
64bit kstat to a 32bit stat.
Along these lines, we need to restore the __xstat32_conv() function.
Reported-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libc/sysdeps/linux/common')
-rw-r--r-- | libc/sysdeps/linux/common/fstatat.c | 9 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/fstatat64.c | 5 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/xstatconv.c | 19 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/xstatconv.h | 1 |
4 files changed, 32 insertions, 2 deletions
diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c index 149c1890d..33daa7c98 100644 --- a/libc/sysdeps/linux/common/fstatat.c +++ b/libc/sysdeps/linux/common/fstatat.c @@ -10,15 +10,20 @@ #include <sys/stat.h> #include "xstatconv.h" +/* 64bit ports tend to favor newfstatat() */ +#ifdef __NR_newfstatat +# define __NR_fstatat64 __NR_newfstatat +#endif + #ifdef __NR_fstatat64 int fstatat(int fd, const char *file, struct stat *buf, int flag) { int ret; - struct kernel_stat kbuf; + struct kernel_stat64 kbuf; ret = INLINE_SYSCALL(fstatat64, 4, fd, file, &kbuf, flag); if (ret == 0) - __xstat_conv(&kbuf, buf); + __xstat32_conv(&kbuf, buf); return ret; } diff --git a/libc/sysdeps/linux/common/fstatat64.c b/libc/sysdeps/linux/common/fstatat64.c index 5ae1fadba..95627afaf 100644 --- a/libc/sysdeps/linux/common/fstatat64.c +++ b/libc/sysdeps/linux/common/fstatat64.c @@ -12,6 +12,11 @@ #ifdef __UCLIBC_HAS_LFS__ +/* 64bit ports tend to favor newfstatat() */ +#ifdef __NR_newfstatat +# define __NR_fstatat64 __NR_newfstatat +#endif + #ifdef __NR_fstatat64 int fstatat64(int fd, const char *file, struct stat64 *buf, int flag) { diff --git a/libc/sysdeps/linux/common/xstatconv.c b/libc/sysdeps/linux/common/xstatconv.c index 2a8245806..deef3929e 100644 --- a/libc/sysdeps/linux/common/xstatconv.c +++ b/libc/sysdeps/linux/common/xstatconv.c @@ -44,6 +44,25 @@ void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf) buf->st_ctim = kbuf->st_ctim; } +void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf) +{ + /* Convert to current kernel version of `struct stat64'. */ + memset(buf, 0x00, sizeof(*buf)); + buf->st_dev = kbuf->st_dev; + 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; + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + buf->st_atim = kbuf->st_atim; + buf->st_mtim = kbuf->st_mtim; + buf->st_ctim = kbuf->st_ctim; +} + #ifdef __UCLIBC_HAS_LFS__ void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf) diff --git a/libc/sysdeps/linux/common/xstatconv.h b/libc/sysdeps/linux/common/xstatconv.h index 57c8bcbe2..7568da850 100644 --- a/libc/sysdeps/linux/common/xstatconv.h +++ b/libc/sysdeps/linux/common/xstatconv.h @@ -26,6 +26,7 @@ #include <bits/kernel_stat.h> extern void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf) attribute_hidden; +extern void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf) attribute_hidden; #if defined __UCLIBC_HAS_LFS__ extern void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf) attribute_hidden; #endif |