[klibc] [klibc:master] stat: Make all stat calls wrappers for statx()

klibc-bot for Ben Hutchings ben at decadent.org.uk
Sun Feb 12 14:48:10 PST 2023


Commit-ID:  e3a0f7bae41eaf18c28c6731cc4961c426d0322d
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=e3a0f7bae41eaf18c28c6731cc4961c426d0322d
Author:     Ben Hutchings <ben at decadent.org.uk>
AuthorDate: Sat, 14 Jan 2023 01:28:19 +0100
Committer:  Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sun, 12 Feb 2023 22:10:18 +0100

[klibc] stat: Make all stat calls wrappers for statx()

fstat(), fstatat(), lstat(), and stat() don't have direct replacements
that use 64-bit time fields on 32-bit architectures and on mips64.
Instead, we have to use the statx() system call which uses a different
buffer structure.

In preparation for using 64-bit time everywhere:

- Add a statx() system call wrapper
- Replace the architecture-dependent struct stat definitions
  with a sensible klibc-specific definition
- Make fstatat() call statx() and convert the returned struct statx
  to struct stat
- Make {f,l,}stat() wrappers for fstatat()

Signed-off-by: Ben Hutchings <ben at decadent.org.uk>

---
 usr/include/arch/alpha/klibc/archstat.h   | 28 ----------------
 usr/include/arch/arm/klibc/archstat.h     | 40 ----------------------
 usr/include/arch/arm64/klibc/archstat.h   | 28 ----------------
 usr/include/arch/i386/klibc/archstat.h    | 38 ---------------------
 usr/include/arch/ia64/klibc/archstat.h    | 26 --------------
 usr/include/arch/m68k/klibc/archstat.h    | 38 ---------------------
 usr/include/arch/mips/klibc/archstat.h    | 42 -----------------------
 usr/include/arch/mips64/klibc/archstat.h  | 38 ---------------------
 usr/include/arch/parisc/klibc/archstat.h  | 29 ----------------
 usr/include/arch/ppc/klibc/archstat.h     | 30 -----------------
 usr/include/arch/ppc64/klibc/archstat.h   | 28 ----------------
 usr/include/arch/riscv64/klibc/archstat.h | 28 ----------------
 usr/include/arch/s390/klibc/archstat.h    | 56 -------------------------------
 usr/include/arch/sh/klibc/archstat.h      | 38 ---------------------
 usr/include/arch/sparc/klibc/archstat.h   | 37 --------------------
 usr/include/arch/sparc64/klibc/archstat.h | 30 -----------------
 usr/include/arch/x86_64/klibc/archstat.h  | 28 ----------------
 usr/include/klibc/stathelp.h              | 24 -------------
 usr/include/sys/stat.h                    | 32 +++++++++++++-----
 usr/klibc/Kbuild                          |  4 +--
 usr/klibc/SYSCALLS.def                    |  9 +----
 usr/klibc/fstat.c                         | 10 ++++++
 usr/klibc/fstatat.c                       | 36 ++++++++++++++++++++
 usr/klibc/lstat.c                         |  4 ---
 usr/klibc/stat.c                          |  4 ---
 25 files changed, 72 insertions(+), 633 deletions(-)

diff --git a/usr/include/arch/alpha/klibc/archstat.h b/usr/include/arch/alpha/klibc/archstat.h
deleted file mode 100644
index 66e29be3..00000000
--- a/usr/include/arch/alpha/klibc/archstat.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);
-	unsigned long	st_ino;
-	__stdev64	(st_rdev);
-	long		st_size;
-	unsigned long	st_blocks;
-
-	unsigned int	st_mode;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	st_blksize;
-	unsigned int	st_nlink;
-	unsigned int	__pad0;
-
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-  	long		__unused[3];
-};
-
-#endif
diff --git a/usr/include/arch/arm/klibc/archstat.h b/usr/include/arch/arm/klibc/archstat.h
deleted file mode 100644
index 95bbc9e8..00000000
--- a/usr/include/arch/arm/klibc/archstat.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-/* This matches struct stat64 in glibc2.1, hence the absolutely
- * insane amounts of padding around dev_t's.
- * Note: The kernel zero's the padded region because glibc might read them
- * in the hope that the kernel has stretched to using larger sizes.
- */
-
-struct stat {
-	__stdev64	(st_dev);
-	unsigned char   __pad0[4];
-
-	unsigned long	__st_ino;
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-
-	unsigned long	st_uid;
-	unsigned long	st_gid;
-
-	__stdev64	(st_rdev);
-	unsigned char   __pad3[4];
-
-	long long	st_size;
-	unsigned long	st_blksize;
-
-	unsigned long long  st_blocks;	/* Number 512-byte blocks allocated. */
-
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-
-	unsigned long long	st_ino;
-};
-
-#endif
diff --git a/usr/include/arch/arm64/klibc/archstat.h b/usr/include/arch/arm64/klibc/archstat.h
deleted file mode 100644
index f5bfa80a..00000000
--- a/usr/include/arch/arm64/klibc/archstat.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);	/* Device */
-	unsigned long	st_ino;		/* File serial number */
-	unsigned int	st_mode;	/* File mode */
-	unsigned int	st_nlink;	/* Link count */
-	unsigned int	st_uid;		/* User ID of the file's owner */
-	unsigned int	st_gid;		/* Group ID of the file's group */
-	__stdev64	(st_rdev);	/* Device number, if device */
-	unsigned long	__pad1;
-	long		st_size;	/* Size of file, in bytes */
-	int		st_blksize;	/* Optimal block size for I/O */
-	int		__pad2;
-	long		st_blocks;	/* Number 512-byte blocks allocated */
-	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 */
-	unsigned int	__unused4;
-	unsigned int	__unused5;
-};
-
-#endif
diff --git a/usr/include/arch/i386/klibc/archstat.h b/usr/include/arch/i386/klibc/archstat.h
deleted file mode 100644
index c00f955d..00000000
--- a/usr/include/arch/i386/klibc/archstat.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-/* This matches struct stat64 in glibc2.1, hence the absolutely
- * insane amounts of padding around dev_t's.
- */
-struct stat {
-	__stdev64	(st_dev);
-	unsigned char	__pad0[4];
-
-	unsigned long	__st_ino;
-
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-
-	unsigned long	st_uid;
-	unsigned long	st_gid;
-
-	__stdev64	(st_rdev);
-	unsigned char	__pad3[4];
-
-	long long	st_size;
-	unsigned long	st_blksize;
-
-	unsigned long long st_blocks;	/* Number 512-byte blocks allocated. */
-
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-
-	unsigned long long	st_ino;
-};
-
-#endif
diff --git a/usr/include/arch/ia64/klibc/archstat.h b/usr/include/arch/ia64/klibc/archstat.h
deleted file mode 100644
index ff38e418..00000000
--- a/usr/include/arch/ia64/klibc/archstat.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);
-	unsigned long	st_ino;
-	unsigned long	st_nlink;
-	unsigned int	st_mode;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	__pad0;
-	__stdev64	(st_rdev);
-	unsigned long	st_size;
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-	unsigned long	st_blksize;
-	long		st_blocks;
-	unsigned long	__unused[3];
-};
-
-#endif
diff --git a/usr/include/arch/m68k/klibc/archstat.h b/usr/include/arch/m68k/klibc/archstat.h
deleted file mode 100644
index dce25f97..00000000
--- a/usr/include/arch/m68k/klibc/archstat.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-/* This matches struct stat64 in glibc2.1, hence the absolutely
- * insane padding around dev_t's.
- */
-struct stat {
-	__stdev64	(st_dev);
-	unsigned char	__pad1[2];
-
-	unsigned long	__st_ino;
-
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-
-	unsigned long	st_uid;
-	unsigned long	st_gid;
-
-	__stdev64	(st_rdev);
-	unsigned char	__pad3[2];
-
-	long long	st_size;
-	unsigned long	st_blksize;
-
-	unsigned long long	st_blocks;	/* Number 512-byte blocks allocated. */
-
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-
-	unsigned long long	st_ino;
-};
-
-#endif
diff --git a/usr/include/arch/mips/klibc/archstat.h b/usr/include/arch/mips/klibc/archstat.h
deleted file mode 100644
index b06686f0..00000000
--- a/usr/include/arch/mips/klibc/archstat.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <sys/types.h>
-
-#define _STATBUF_ST_NSEC
-
-/*
- * This matches struct stat64 in glibc2.1, hence the absolutely insane
- * amounts of padding around dev_t's.  The memory layout is the same as of
- * struct stat of the 64-bit kernel, which makes this one of the sanest
- * 32-bit struct stats.
- */
-
-struct stat {
-	unsigned int	st_dev;
-	unsigned long	st_pad0[3];	/* Reserved for st_dev expansion  */
-
-	unsigned long long	st_ino;
-
-	mode_t		st_mode;
-	__u32		st_nlink;
-
-	uid_t		st_uid;
-	gid_t		st_gid;
-
-	unsigned int	st_rdev;
-	unsigned long	st_pad1[3];	/* Reserved for st_rdev expansion  */
-
-	long long	st_size;
-
-	struct timespec		st_atim;
-	struct timespec		st_mtim;
-	struct timespec		st_ctim;
-
-	unsigned long	st_blksize;
-	unsigned long	st_pad2;
-
-	long long	st_blocks;
-};
-
-#endif
diff --git a/usr/include/arch/mips64/klibc/archstat.h b/usr/include/arch/mips64/klibc/archstat.h
deleted file mode 100644
index 16f50c9e..00000000
--- a/usr/include/arch/mips64/klibc/archstat.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <sys/types.h>
-
-struct stat {
-	unsigned int		st_dev;
-	unsigned int		st_pad0[3]; /* Reserved for st_dev expansion */
-
-	unsigned long		st_ino;
-
-	mode_t			st_mode;
-	__u32			st_nlink;
-
-	uid_t			st_uid;
-	gid_t			st_gid;
-
-	unsigned int		st_rdev;
-	unsigned int		st_pad1[3]; /* Reserved for st_rdev expansion */
-
-	off_t			st_size;
-
-	unsigned int		st_atime;
-	unsigned int		st_atimensec;
-
-	unsigned int		st_mtime;
-	unsigned int		st_mtimensec;
-
-	unsigned int		st_ctime;
-	unsigned int		st_ctimensec;
-
-	unsigned int		st_blksize;
-	unsigned int		st_pad2;
-
-	unsigned long		st_blocks;
-};
-
-#endif
diff --git a/usr/include/arch/parisc/klibc/archstat.h b/usr/include/arch/parisc/klibc/archstat.h
deleted file mode 100644
index 0b8ef8d6..00000000
--- a/usr/include/arch/parisc/klibc/archstat.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64		(st_dev);
-	unsigned int		__pad1;
-
-	unsigned int		__st_ino;	/* Not actually filled in */
-	unsigned int		st_mode;
-	unsigned int		st_nlink;
-	unsigned int		st_uid;
-	unsigned int		st_gid;
-	__stdev64		(st_rdev);
-	unsigned int		__pad2;
-	signed long long	st_size;
-	signed int		st_blksize;
-
-	signed long long	st_blocks;
-	struct timespec		st_atim;
-	struct timespec		st_mtim;
-	struct timespec		st_ctim;
-	unsigned long long	st_ino;
-};
-
-#endif
diff --git a/usr/include/arch/ppc/klibc/archstat.h b/usr/include/arch/ppc/klibc/archstat.h
deleted file mode 100644
index 9e31f4a2..00000000
--- a/usr/include/arch/ppc/klibc/archstat.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-/* This matches struct stat64 in glibc2.1.
- */
-struct stat {
-	__stdev64 (st_dev);		/* Device. */
-	unsigned long long st_ino;	/* File serial number.  */
-	unsigned int st_mode;		/* File mode.  */
-	unsigned int st_nlink;		/* Link count.  */
-	unsigned int st_uid;		/* User ID of the file's owner.  */
-	unsigned int st_gid;		/* Group ID of the file's group. */
-	__stdev64 (st_rdev); 		/* Device number, if device.  */
-	unsigned short int __pad2;
-	long long st_size;		/* Size of file, in bytes.  */
-	long st_blksize;		/* Optimal block size for I/O.  */
-
-	long long st_blocks;		/* Number 512-byte blocks allocated. */
-	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.  */
-	unsigned long int __unused4;
-	unsigned long int __unused5;
-};
-
-#endif
diff --git a/usr/include/arch/ppc64/klibc/archstat.h b/usr/include/arch/ppc64/klibc/archstat.h
deleted file mode 100644
index 0bbbff3b..00000000
--- a/usr/include/arch/ppc64/klibc/archstat.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);
-	ino_t		st_ino;
-	unsigned long	st_nlink;
-	mode_t		st_mode;
-	uid_t 		st_uid;
-	gid_t 		st_gid;
-	unsigned int	__pad1;
-	__stdev64	(st_rdev);
-	off_t		st_size;
-	unsigned long  	st_blksize;
-	unsigned long  	st_blocks;
-	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.  */
-	unsigned long  	__unused4;
-	unsigned long  	__unused5;
-	unsigned long  	__unused6;
-};
-
-#endif
diff --git a/usr/include/arch/riscv64/klibc/archstat.h b/usr/include/arch/riscv64/klibc/archstat.h
deleted file mode 100644
index f5bfa80a..00000000
--- a/usr/include/arch/riscv64/klibc/archstat.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);	/* Device */
-	unsigned long	st_ino;		/* File serial number */
-	unsigned int	st_mode;	/* File mode */
-	unsigned int	st_nlink;	/* Link count */
-	unsigned int	st_uid;		/* User ID of the file's owner */
-	unsigned int	st_gid;		/* Group ID of the file's group */
-	__stdev64	(st_rdev);	/* Device number, if device */
-	unsigned long	__pad1;
-	long		st_size;	/* Size of file, in bytes */
-	int		st_blksize;	/* Optimal block size for I/O */
-	int		__pad2;
-	long		st_blocks;	/* Number 512-byte blocks allocated */
-	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 */
-	unsigned int	__unused4;
-	unsigned int	__unused5;
-};
-
-#endif
diff --git a/usr/include/arch/s390/klibc/archstat.h b/usr/include/arch/s390/klibc/archstat.h
deleted file mode 100644
index ca4c822e..00000000
--- a/usr/include/arch/s390/klibc/archstat.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-#ifndef __s390x__
-
-/* This matches struct stat64 in glibc2.1, hence the absolutely
- * insane amounts of padding around dev_t's.
- */
-struct stat {
-	__stdev64	(st_dev);
-	unsigned int	__pad1;
-#define STAT64_HAS_BROKEN_ST_INO	1
-	unsigned long	__st_ino;
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-	unsigned long	st_uid;
-	unsigned long	st_gid;
-	__stdev64	(st_rdev);
-	unsigned int	__pad3;
-	long long	st_size;
-	unsigned long	st_blksize;
-	unsigned char	__pad4[4];
-	unsigned long	__pad5;     /* future possible st_blocks high bits */
-	unsigned long	st_blocks;  /* Number 512-byte blocks allocated. */
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-	unsigned long long	st_ino;
-};
-
-#else /* __s390x__ */
-
-struct stat {
-	__stdev64	(st_dev);
-	unsigned long	st_ino;
-	unsigned long	st_nlink;
-	unsigned int	st_mode;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	__pad1;
-	__stdev64	(st_rdev);
-	unsigned long	st_size;
-	struct timespec	st_atim;
-	struct timespec	st_mtim;
-	struct timespec	st_ctim;
-	unsigned long	st_blksize;
-	long		st_blocks;
-	unsigned long	__unused[3];
-};
-
-#endif /* __s390x__ */
-#endif
diff --git a/usr/include/arch/sh/klibc/archstat.h b/usr/include/arch/sh/klibc/archstat.h
deleted file mode 100644
index 4f39181e..00000000
--- a/usr/include/arch/sh/klibc/archstat.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-/* This matches struct stat64 in glibc2.1, hence the absolutely
- * insane amounts of padding around dev_t's.
- */
-struct stat {
-	__stdev64	(st_dev);
-	unsigned char	__pad0[4];
-
-	unsigned long	st_ino;
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-
-	unsigned long	st_uid;
-	unsigned long	st_gid;
-
-	__stdev64	(st_rdev);
-	unsigned char	__pad3[4];
-
-	long long	st_size;
-	unsigned long	st_blksize;
-
-	unsigned long long st_blocks;
-
-	struct timespec	st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-
-	unsigned long	__unused1;
-	unsigned long	__unused2;
-};
-
-#endif
diff --git a/usr/include/arch/sparc/klibc/archstat.h b/usr/include/arch/sparc/klibc/archstat.h
deleted file mode 100644
index 203d40b5..00000000
--- a/usr/include/arch/sparc/klibc/archstat.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);
-
-	unsigned long long st_ino;
-
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-
-	__stdev64	(st_rdev);
-
-	unsigned char	__pad3[8];
-
-	long long	st_size;
-	unsigned int	st_blksize;
-
-	unsigned char	__pad4[8];
-	unsigned int	st_blocks;
-
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-
-	unsigned int	__unused4;
-	unsigned int	__unused5;
-};
-
-#endif
diff --git a/usr/include/arch/sparc64/klibc/archstat.h b/usr/include/arch/sparc64/klibc/archstat.h
deleted file mode 100644
index 56fb2a4c..00000000
--- a/usr/include/arch/sparc64/klibc/archstat.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);
-	unsigned long	st_ino;
-	unsigned long	st_nlink;
-
-	unsigned int	st_mode;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	__pad0;
-
-	__stdev64 (st_rdev);
-	long		st_size;
-	long		st_blksize;
-	long		st_blocks;
-
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-
-	unsigned long __unused[3];
-};
-
-#endif
diff --git a/usr/include/arch/x86_64/klibc/archstat.h b/usr/include/arch/x86_64/klibc/archstat.h
deleted file mode 100644
index de168ac5..00000000
--- a/usr/include/arch/x86_64/klibc/archstat.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _KLIBC_ARCHSTAT_H
-#define _KLIBC_ARCHSTAT_H
-
-#include <klibc/stathelp.h>
-
-#define _STATBUF_ST_NSEC
-
-struct stat {
-	__stdev64	(st_dev);
-	unsigned long	st_ino;
-	unsigned long	st_nlink;
-
-	unsigned int	st_mode;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	__pad0;
-	__stdev64	(st_rdev);
-	long		st_size;
-	long		st_blksize;
-	long		st_blocks;	/* Number 512-byte blocks allocated. */
-
-	struct timespec st_atim;
-	struct timespec st_mtim;
-	struct timespec st_ctim;
-  	long		__unused[3];
-};
-
-#endif
diff --git a/usr/include/klibc/stathelp.h b/usr/include/klibc/stathelp.h
deleted file mode 100644
index 9520dad2..00000000
--- a/usr/include/klibc/stathelp.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * stathelp.h
- *
- * Helper macros for <klibc/archstat.h>
- */
-
-#ifndef _KLIBC_STATHELP_H
-#define _KLIBC_STATHELP_H
-
-#include <klibc/endian.h>
-
-/*
- * Most architectures have a 64-bit field for st_dev and st_rdev,
- * but dev_t is 32 bits (uint32_t == unsigned int), so make a
- * macro we can use across all architectures.
- */
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-# define __stdev64(x)	unsigned int __##x, x;
-#else
-# define __stdev64(x)	unsigned int x, __##x;
-#endif
-
-#endif				/* _KLIBC_STATHELP_H */
diff --git a/usr/include/sys/stat.h b/usr/include/sys/stat.h
index c4b378ea..861b4623 100644
--- a/usr/include/sys/stat.h
+++ b/usr/include/sys/stat.h
@@ -8,7 +8,7 @@
 #include <klibc/extern.h>
 #include <sys/types.h>
 #include <sys/time.h>		/* For struct timespec */
-#include <klibc/archstat.h>
+#include <linux/stat.h>
 
 /* 2.6.21 kernels have once again hidden a bunch of stuff... */
 #ifndef S_IFMT
@@ -48,25 +48,39 @@
 #define S_IWOTH 00002
 #define S_IXOTH 00001
 
+#endif
+
 #define S_IRWXUGO	(S_IRWXU|S_IRWXG|S_IRWXO)
 #define S_IALLUGO	(S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
 #define S_IRUGO		(S_IRUSR|S_IRGRP|S_IROTH)
 #define S_IWUGO		(S_IWUSR|S_IWGRP|S_IWOTH)
 #define S_IXUGO		(S_IXUSR|S_IXGRP|S_IXOTH)
 
-#endif
-
-#ifdef _STATBUF_ST_NSEC
-  /* struct stat has struct timespec instead of time_t */
-# define st_atime  st_atim.tv_sec
-# define st_mtime  st_mtim.tv_sec
-# define st_ctime  st_ctim.tv_sec
-#endif
+/* struct stat with 64-bit time, not used by kernel UAPI */
+struct stat {
+        dev_t		st_dev;
+        ino_t		st_ino;
+        mode_t		st_mode;
+        unsigned int	st_nlink;
+        uid_t		st_uid;
+        gid_t		st_gid;
+        dev_t		st_rdev;
+        off_t		st_size;
+        int		st_blksize;
+        off_t		st_blocks;
+        struct timespec	st_atim;
+        struct timespec	st_mtim;
+        struct timespec	st_ctim;
+};
+#define st_atime	st_atim.tv_sec
+#define st_mtime	st_mtim.tv_sec
+#define st_ctime	st_ctim.tv_sec
 
 __extern int stat(const char *, struct stat *);
 __extern int fstat(int, struct stat *);
 __extern int fstatat(int, const char *, struct stat *, int);
 __extern int lstat(const char *, struct stat *);
+__extern int statx(int, const char *, int, unsigned int, struct statx *);
 __extern mode_t umask(mode_t);
 __extern int mknod(const char *, mode_t, dev_t);
 __extern int mknodat(int, const char *, mode_t, dev_t);
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index eb13a70e..85ebb25a 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -60,8 +60,8 @@ klib-y += vsnprintf.o snprintf.o vsprintf.o sprintf.o \
 	  inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \
 	  accept.o send.o recv.o \
 	  access.o chmod.o chown.o dup2.o mknod.o poll.o rename.o renameat.o \
-	  stat.o \
-	  lchown.o link.o rmdir.o unlink.o utimes.o lstat.o mkdir.o \
+	  fstat.o fstatat.o lstat.o stat.o \
+	  lchown.o link.o rmdir.o unlink.o utimes.o mkdir.o \
 	  readlink.o realpath.o select.o symlink.o pipe.o \
 	  ctype/isalnum.o ctype/isalpha.o ctype/isascii.o \
 	  ctype/isblank.o ctype/iscntrl.o ctype/isdigit.o \
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index c5920159..00c52e02 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -133,14 +133,7 @@ int chroot(const char *);
 <?> int symlinkat(const char *, int, const char *);
 <?> int readlink(const char *, char *, size_t);
 <?> int readlinkat(int, const char *, char *, int);
-<?!ppc64> int stat64,stat::stat(const char *, struct stat *);
-<?!ppc64> int lstat64,lstat::lstat(const char *, struct stat *);
-<!ppc64> int fstat64,fstat::fstat(int, struct stat *);
-<ppc64> int stat::stat(const char *, struct stat *);
-<ppc64> int lstat::lstat(const char *, struct stat *);
-<ppc64> int fstat::fstat(int, struct stat *);
-/* XXX: Is this right?! */
-<?> int fstatat64,newfstatat,fstatat::fstatat(int, const char *, struct stat *, int);
+int statx(int, const char *, int, unsigned int, struct statx *);
 int getdents64,getdents::getdents(unsigned int, struct dirent *, unsigned int);
 <?> int chown32,chown::chown(const char *, uid_t, gid_t);
 int fchown32,fchown::fchown(int, uid_t, gid_t);
diff --git a/usr/klibc/fstat.c b/usr/klibc/fstat.c
new file mode 100644
index 00000000..36dd6617
--- /dev/null
+++ b/usr/klibc/fstat.c
@@ -0,0 +1,10 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+int fstat(int fd, struct stat *buf)
+{
+	return fstatat(fd, "", buf, AT_EMPTY_PATH);
+}
diff --git a/usr/klibc/fstatat.c b/usr/klibc/fstatat.c
new file mode 100644
index 00000000..12b5093e
--- /dev/null
+++ b/usr/klibc/fstatat.c
@@ -0,0 +1,36 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+static void timespec_from_statx(struct timespec *ts,
+				const struct statx_timestamp *xts)
+{
+	ts->tv_sec = xts->tv_sec;
+	ts->tv_nsec = xts->tv_nsec;
+}
+
+int fstatat(int dirfd, const char *path, struct stat *buf, int flags)
+{
+	struct statx xbuf;
+
+	if (statx(dirfd, path, flags | AT_NO_AUTOMOUNT, STATX_BASIC_STATS,
+		  &xbuf))
+		return -1;
+
+	buf->st_dev = makedev(xbuf.stx_dev_major, xbuf.stx_dev_minor);
+	buf->st_ino = xbuf.stx_ino;
+	buf->st_nlink = xbuf.stx_nlink;
+	buf->st_mode = xbuf.stx_mode;
+	buf->st_uid = xbuf.stx_uid;
+	buf->st_gid = xbuf.stx_gid;
+	buf->st_rdev = makedev(xbuf.stx_rdev_major, xbuf.stx_rdev_minor);
+	buf->st_size = xbuf.stx_size;
+	buf->st_blksize = xbuf.stx_blksize;
+	buf->st_blocks = xbuf.stx_blocks;
+	timespec_from_statx(&buf->st_atim, &xbuf.stx_atime);
+	timespec_from_statx(&buf->st_ctim, &xbuf.stx_ctime);
+	timespec_from_statx(&buf->st_mtim, &xbuf.stx_mtime);
+	return 0;
+}
diff --git a/usr/klibc/lstat.c b/usr/klibc/lstat.c
index 3288a332..3e8146f9 100644
--- a/usr/klibc/lstat.c
+++ b/usr/klibc/lstat.c
@@ -4,11 +4,7 @@
 #include <sys/stat.h>
 #include <sys/syscall.h>
 
-#ifndef __NR_lstat
-
 int lstat(const char *path, struct stat *buf)
 {
 	return fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
 }
-
-#endif  /* __NR_lstat  */
diff --git a/usr/klibc/stat.c b/usr/klibc/stat.c
index 65063b09..673fb066 100644
--- a/usr/klibc/stat.c
+++ b/usr/klibc/stat.c
@@ -4,11 +4,7 @@
 #include <sys/stat.h>
 #include <sys/syscall.h>
 
-#ifndef __NR_stat
-
 int stat(const char *path, struct stat *buf)
 {
 	return fstatat(AT_FDCWD, path, buf, 0);
 }
-
-#endif /* __NR_stat */


More information about the klibc mailing list