diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/alpha/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/alpha/kernel_stat.h new file mode 100644 index 0000000000..a292920969 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/alpha/kernel_stat.h @@ -0,0 +1,91 @@ +/* Definition of `struct stat' used in the kernel. */ +struct kernel_stat + { + unsigned int st_dev; + unsigned int st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + long int st_size; + unsigned long int st_atime_sec; + unsigned long int st_mtime_sec; + unsigned long int st_ctime_sec; + unsigned int st_blksize; + int st_blocks; + unsigned int st_flags; + unsigned int st_gen; + }; + +/* Definition of `struct stat64' used in the kernel. */ +struct kernel_stat64 + { + unsigned long st_dev; + unsigned long st_ino; + unsigned long 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; + + unsigned long st_atime_sec; + unsigned long st_atimensec; + unsigned long st_mtime_sec; + unsigned long st_mtimensec; + unsigned long st_ctime_sec; + unsigned long st_ctimensec; + long __glibc_reserved[3]; + }; + +/* Definition of `struct stat' used by glibc 2.0. */ +struct glibc2_stat + { + __dev_t st_dev; + __ino_t st_ino; + __mode_t st_mode; + __nlink_t st_nlink; + __uid_t st_uid; + __gid_t st_gid; + __dev_t st_rdev; + __off_t st_size; + __time_t st_atime_sec; + __time_t st_mtime_sec; + __time_t st_ctime_sec; + unsigned int st_blksize; + int st_blocks; + unsigned int st_flags; + unsigned int st_gen; + }; + +/* Definition of `struct stat' used by glibc 2.1. */ +struct glibc21_stat + { + __dev_t st_dev; + __ino64_t st_ino; + __mode_t st_mode; + __nlink_t st_nlink; + __uid_t st_uid; + __gid_t st_gid; + __dev_t st_rdev; + __off_t st_size; + __time_t st_atime_sec; + __time_t st_mtime_sec; + __time_t st_ctime_sec; + __blkcnt64_t st_blocks; + __blksize_t st_blksize; + unsigned int st_flags; + unsigned int st_gen; + int __pad3; + long __glibc_reserved[4]; + }; + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 1 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/arm/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/arm/kernel_stat.h new file mode 100644 index 0000000000..b1bc1459f0 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/arm/kernel_stat.h @@ -0,0 +1,40 @@ +/* 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 __glibc_reserved4; +#define _HAVE___UNUSED4 + unsigned long int __glibc_reserved5; +#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 +#define _HAVE_STAT64___ST_INO +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/io/fstat64.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/csky/kernel_stat.h similarity index 63% rename from lib/libc/glibc/io/fstat64.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/csky/kernel_stat.h index bfe2fb8128..e993021a81 100644 --- a/lib/libc/glibc/io/fstat64.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/csky/kernel_stat.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1996-2021 Free Software Foundation, Inc. +/* Internal definitions for stat functions. Linux/csky. + Copyright (C) 2011-2021 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 @@ -12,22 +13,9 @@ 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, see + License along with the GNU C Library. If not, see . */ -#include -#include -#include - -int -__fstat64 (int fd, struct stat64 *buf) -{ - if (fd < 0) - { - __set_errno (EBADF); - return -1; - } - return __fstatat64 (fd, "", buf, AT_EMPTY_PATH); -} -hidden_def (__fstat64) -weak_alias (__fstat64, fstat64) +#define STAT_IS_KERNEL_STAT 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/io/fstat.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstat.c similarity index 86% rename from lib/libc/glibc/io/fstat.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/fstat.c index 3f63046f91..31a172dcc8 100644 --- a/lib/libc/glibc/io/fstat.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstat.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1996-2021 Free Software Foundation, Inc. +/* Get file status. Linux version. + Copyright (C) 2020-2021 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 @@ -16,9 +17,11 @@ . */ #include -#include +#include #include +#include +#if !XSTAT_IS_XSTAT64 int __fstat (int fd, struct stat *buf) { @@ -31,3 +34,4 @@ __fstat (int fd, struct stat *buf) } weak_alias (__fstat, fstat) +#endif diff --git a/lib/libc/glibc/io/fstatat.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstat64.c similarity index 53% rename from lib/libc/glibc/io/fstatat.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/fstat64.c index 477b01c076..46de80b663 100644 --- a/lib/libc/glibc/io/fstatat.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstat64.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2005-2021 Free Software Foundation, Inc. +/* Get file status. Linux version. + Copyright (C) 2020-2021 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 @@ -15,28 +16,49 @@ License along with the GNU C Library; if not, see . */ +#define __fstat __redirect___fstat +#define fstat __redirect_fstat #include -#include #include +#include +#include +#include int -__fstatat (int fd, const char *file, struct stat *buf, int flag) +__fstat64_time64 (int fd, struct __stat64_t64 *buf) { - if (fd < 0 && fd != AT_FDCWD) + if (fd < 0) { __set_errno (EBADF); return -1; } - if (buf == 0 || (flag & ~AT_SYMLINK_NOFOLLOW) != 0) + return __fstatat64_time64 (fd, "", buf, AT_EMPTY_PATH); +} +#if __TIMESIZE != 64 +hidden_def (__fstat64_time64) + +int +__fstat64 (int fd, struct stat64 *buf) +{ + if (fd < 0) { - __set_errno (EINVAL); + __set_errno (EBADF); return -1; } - __set_errno (ENOSYS); - return -1; + struct __stat64_t64 st_t64; + return __fstat64_time64 (fd, &st_t64) + ?: __cp_stat64_t64_stat64 (&st_t64, buf); } +#endif -weak_alias (__fstatat, fstatat) +#undef __fstat +#undef fstat -stub_warning (fstatat) +hidden_def (__fstat64) +weak_alias (__fstat64, fstat64) + +#if XSTAT_IS_XSTAT64 +strong_alias (__fstat64, __fstat) +weak_alias (__fstat64, fstat) +#endif diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/fstatat.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstatat.c new file mode 100644 index 0000000000..8d2fed366e --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstatat.c @@ -0,0 +1,62 @@ +/* Get file status. Linux version. + Copyright (C) 2020-2021 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, see + . */ + +#include +#include +#include + +#if !XSTAT_IS_XSTAT64 +# include + +int +__fstatat (int fd, const char *file, struct stat *buf, int flag) +{ + struct __stat64_t64 st64; + int r = __fstatat64_time64 (fd, file, &st64, flag); + if (r == 0) + { + if (! in_ino_t_range (st64.st_ino) + || ! in_off_t_range (st64.st_size) + || ! in_blkcnt_t_range (st64.st_blocks) + || ! in_time_t_range (st64.st_atim.tv_sec) + || ! in_time_t_range (st64.st_mtim.tv_sec) + || ! in_time_t_range (st64.st_ctim.tv_sec)) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); + + /* Clear internal pad and reserved fields. */ + memset (buf, 0, sizeof (*buf)); + + buf->st_dev = st64.st_dev; + buf->st_ino = st64.st_ino; + buf->st_mode = st64.st_mode; + buf->st_nlink = st64.st_nlink; + buf->st_uid = st64.st_uid; + buf->st_gid = st64.st_gid; + buf->st_rdev = st64.st_rdev; + buf->st_size = st64.st_size; + buf->st_blksize = st64.st_blksize; + buf->st_blocks = st64.st_blocks; + buf->st_atim = valid_timespec64_to_timespec (st64.st_atim); + buf->st_mtim = valid_timespec64_to_timespec (st64.st_mtim); + buf->st_ctim = valid_timespec64_to_timespec (st64.st_ctim); + } + return r; +} + +weak_alias (__fstatat, fstatat) +#endif diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/fstatat64.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstatat64.c new file mode 100644 index 0000000000..f968e4ef05 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/fstatat64.c @@ -0,0 +1,188 @@ +/* Get file status. Linux version. + Copyright (C) 2020-2021 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, see + . */ + +#define __fstatat __redirect___fstatat +#define fstatat __redirect_fstatat +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __TIMESIZE == 64 \ + && (__WORDSIZE == 32 \ + && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) +/* Sanity check to avoid newer 32-bit ABI to support non-LFS calls. */ +_Static_assert (sizeof (__off_t) == sizeof (__off64_t), + "__blkcnt_t and __blkcnt64_t must match"); +_Static_assert (sizeof (__ino_t) == sizeof (__ino64_t), + "__blkcnt_t and __blkcnt64_t must match"); +_Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t), + "__blkcnt_t and __blkcnt64_t must match"); +#endif + +static inline int +fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf, + int flag) +{ + /* 32-bit kABI with default 64-bit time_t, e.g. arc, riscv32. Also + 64-bit time_t support is done through statx syscall. */ + struct statx tmp; + int r = INTERNAL_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag, + STATX_BASIC_STATS, &tmp); + if (r != 0) + return r; + + *buf = (struct __stat64_t64) { + .st_dev = __gnu_dev_makedev (tmp.stx_dev_major, tmp.stx_dev_minor), + .st_rdev = __gnu_dev_makedev (tmp.stx_rdev_major, tmp.stx_rdev_minor), + .st_ino = tmp.stx_ino, + .st_mode = tmp.stx_mode, + .st_nlink = tmp.stx_nlink, + .st_uid = tmp.stx_uid, + .st_gid = tmp.stx_gid, + .st_atime = tmp.stx_atime.tv_sec, + .st_atim.tv_nsec = tmp.stx_atime.tv_nsec, + .st_mtime = tmp.stx_mtime.tv_sec, + .st_mtim.tv_nsec = tmp.stx_mtime.tv_nsec, + .st_ctime = tmp.stx_ctime.tv_sec, + .st_ctim.tv_nsec = tmp.stx_ctime.tv_nsec, + .st_size = tmp.stx_size, + .st_blocks = tmp.stx_blocks, + .st_blksize = tmp.stx_blksize, + }; + + return r; +} + +static inline int +fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf, + int flag) +{ + int r; + +#if XSTAT_IS_XSTAT64 +# ifdef __NR_newfstatat + /* 64-bit kABI, e.g. aarch64, ia64, powerpc64*, s390x, riscv64, and + x86_64. */ + r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, buf, flag); +# elif defined __NR_fstatat64 +# if STAT64_IS_KERNEL_STAT64 + /* 64-bit kABI outlier, e.g. alpha */ + r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, buf, flag); +# else + /* 64-bit kABI outlier, e.g. sparc64. */ + struct kernel_stat64 kst64; + r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, &kst64, flag); + if (r == 0) + __cp_stat64_kstat64 (buf, &kst64); +# endif +# endif +#else +# ifdef __NR_fstatat64 + /* All kABIs with non-LFS support and with old 32-bit time_t support + e.g. arm, csky, i386, hppa, m68k, microblaze, nios2, sh, powerpc32, + and sparc32. */ + struct stat64 st64; + r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, &st64, flag); + if (r == 0) + { + /* Clear both pad and reserved fields. */ + memset (buf, 0, sizeof (*buf)); + + buf->st_dev = st64.st_dev, + buf->st_ino = st64.st_ino; + buf->st_mode = st64.st_mode; + buf->st_nlink = st64.st_nlink; + buf->st_uid = st64.st_uid; + buf->st_gid = st64.st_gid; + buf->st_rdev = st64.st_rdev; + buf->st_size = st64.st_size; + buf->st_blksize = st64.st_blksize; + buf->st_blocks = st64.st_blocks; + buf->st_atim = valid_timespec_to_timespec64 (st64.st_atim); + buf->st_mtim = valid_timespec_to_timespec64 (st64.st_mtim); + buf->st_ctim = valid_timespec_to_timespec64 (st64.st_ctim); + } +# else + /* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */ + struct kernel_stat kst; + r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag); + if (r == 0) + __cp_kstat_stat64_t64 (&kst, buf); +# endif +#endif + + return r; +} + +#if (__WORDSIZE == 32 \ + && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \ + || defined STAT_HAS_TIME32 +# define FSTATAT_USE_STATX 1 +#else +# define FSTATAT_USE_STATX 0 +#endif + +int +__fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf, + int flag) +{ + int r; + +#if FSTATAT_USE_STATX + r = fstatat64_time64_statx (fd, file, buf, flag); +# ifndef __ASSUME_STATX + if (r == -ENOSYS) + r = fstatat64_time64_stat (fd, file, buf, flag); +# endif +#else + r = fstatat64_time64_stat (fd, file, buf, flag); +#endif + + return INTERNAL_SYSCALL_ERROR_P (r) + ? INLINE_SYSCALL_ERROR_RETURN_VALUE (-r) + : 0; +} +#if __TIMESIZE != 64 +hidden_def (__fstatat64_time64) + +int +__fstatat64 (int fd, const char *file, struct stat64 *buf, int flags) +{ + struct __stat64_t64 st_t64; + return __fstatat64_time64 (fd, file, &st_t64, flags) + ?: __cp_stat64_t64_stat64 (&st_t64, buf); +} +#endif + +#undef __fstatat +#undef fstatat + +hidden_def (__fstatat64) +weak_alias (__fstatat64, fstatat64) + +#if XSTAT_IS_XSTAT64 +strong_alias (__fstatat64, __fstatat) +weak_alias (__fstatat64, fstatat) +strong_alias (__fstatat64, __GI___fstatat); +#endif diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/hppa/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/hppa/kernel_stat.h new file mode 100644 index 0000000000..e8ad135e70 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/hppa/kernel_stat.h @@ -0,0 +1,36 @@ +/* definition of "struct stat" from the kernel */ +struct kernel_stat { + unsigned long st_dev; /* dev_t is 32 bits on parisc */ + unsigned long st_ino; /* 32 bits */ + unsigned short st_mode; /* 16 bits */ + unsigned short st_nlink; /* 16 bits */ + unsigned short st_reserved1; /* old st_uid */ + unsigned short st_reserved2; /* old st_gid */ + unsigned long st_rdev; + unsigned long st_size; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + long st_blksize; + long st_blocks; + unsigned long __glibc_reserved1; /* ACL stuff */ + unsigned long __glibc_reserved2; /* network */ + unsigned long __glibc_reserved3; /* network */ + unsigned long __glibc_reserved4; /* cnodes */ + unsigned short __glibc_reserved5; /* netsite */ + short st_fstype; + unsigned long st_realdev; + unsigned short st_basemode; + unsigned short st_spareshort; + unsigned long st_uid; + unsigned long st_gid; + unsigned long st_spare4[3]; +}; + +#define _HAVE_STAT_NSEC +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/i386/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/i386/kernel_stat.h new file mode 100644 index 0000000000..b1bc1459f0 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/i386/kernel_stat.h @@ -0,0 +1,40 @@ +/* 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 __glibc_reserved4; +#define _HAVE___UNUSED4 + unsigned long int __glibc_reserved5; +#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 +#define _HAVE_STAT64___ST_INO +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/io/stat64.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/kernel_stat.h similarity index 73% rename from lib/libc/glibc/io/stat64.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/kernel_stat.h index dee30d8aa2..6c1b175cb4 100644 --- a/lib/libc/glibc/io/stat64.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/kernel_stat.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1996-2021 Free Software Foundation, Inc. +/* Internal definitions for stat functions. + Copyright (C) 2021 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 @@ -15,13 +16,7 @@ License along with the GNU C Library; if not, see . */ -#include -#include - -int -__stat64 (const char *file, struct stat64 *buf) -{ - return __fstatat64 (AT_FDCWD, file, buf, 0); -} -hidden_def (__stat64) -weak_alias (__stat64, stat64) +/* The default Linux ABI assumes only LFS support. */ +#define XSTAT_IS_XSTAT64 1 +#define STATFS_IS_STATFS64 __STATFS_MATCHES_STATFS64 +#define STAT_IS_KERNEL_STAT 1 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/kstat_cp.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/kstat_cp.h new file mode 100644 index 0000000000..69397db0d2 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/kstat_cp.h @@ -0,0 +1,2 @@ +/* Empty, it is overridden by an architecture which might require copy to or + from a kernel_stat stat struct to glibc export stat{64}. */ diff --git a/lib/libc/glibc/io/lstat.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/lstat.c similarity index 86% rename from lib/libc/glibc/io/lstat.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/lstat.c index 2ce1163ac0..b79b4cb9f4 100644 --- a/lib/libc/glibc/io/lstat.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/lstat.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1996-2021 Free Software Foundation, Inc. +/* Get file status. Linux version. + Copyright (C) 2020-2021 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 @@ -17,7 +18,9 @@ #include #include +#include +#if !XSTAT_IS_XSTAT64 int __lstat (const char *file, struct stat *buf) { @@ -25,3 +28,4 @@ __lstat (const char *file, struct stat *buf) } weak_alias (__lstat, lstat) +#endif diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/lstat64.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/lstat64.c new file mode 100644 index 0000000000..3b45187f61 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/lstat64.c @@ -0,0 +1,51 @@ +/* Get file status. + Copyright (C) 1996-2021 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, see + . */ + +#define __lstat __redirect___lstat +#define lstat __redirect_lstat +#include +#include +#include +#include + +int +__lstat64_time64 (const char *file, struct __stat64_t64 *buf) +{ + return __fstatat64_time64 (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW); +} +#if __TIMESIZE != 64 +hidden_def (__lstat64_time64) + +int +__lstat64 (const char *file, struct stat64 *buf) +{ + struct __stat64_t64 st_t64; + return __lstat64_time64 (file, &st_t64) + ?: __cp_stat64_t64_stat64 (&st_t64, buf); +} +#endif +hidden_def (__lstat64) +weak_alias (__lstat64, lstat64) + +#undef __lstat +#undef lstat + +#if XSTAT_IS_XSTAT64 +strong_alias (__lstat64, __lstat) +weak_alias (__lstat64, lstat) +#endif diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/m68k/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/m68k/kernel_stat.h new file mode 100644 index 0000000000..b1bc1459f0 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/m68k/kernel_stat.h @@ -0,0 +1,40 @@ +/* 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 __glibc_reserved4; +#define _HAVE___UNUSED4 + unsigned long int __glibc_reserved5; +#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 +#define _HAVE_STAT64___ST_INO +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h new file mode 100644 index 0000000000..af12ac60c3 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/microblaze/kernel_stat.h @@ -0,0 +1,54 @@ +/* Definition of `struct stat' used in the kernel + Copyright (C) 2013-2021 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, see + . */ + +struct kernel_stat +{ + unsigned long 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. */ + unsigned long st_rdev; /* Device number, if device. */ + unsigned long __pad2; +#define _HAVE_STAT___PAD2 +#define _HAVE_STAT64___PAD2 + long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + int __pad3; +#define _HAVE_STAT___PAD3 +#define _HAVE_STAT64___PAD3 + long st_blocks; /* Number 512-byte blocks allocated. */ + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; +#define _HAVE_STAT_NSEC +#define _HAVE_STAT64_NSEC + unsigned int __glibc_reserved4; +#define _HAVE_STAT___UNUSED4 +#define _HAVE_STAT64___UNUSED4 + unsigned int __glibc_reserved5; +#define _HAVE_STAT___UNUSED5 +#define _HAVE_STAT64___UNUSED5 +}; + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/mips/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/mips/kernel_stat.h new file mode 100644 index 0000000000..19524f7ea4 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/mips/kernel_stat.h @@ -0,0 +1,75 @@ +#ifndef _KERNEL_STAT_H +#define _KERNEL_STAT_H + +#include +/* As tempting as it is to define XSTAT_IS_XSTAT64 for n64, the + userland data structures are not identical, because of different + padding. */ +/* Definition of `struct stat' used in the kernel. */ +#if _MIPS_SIM != _ABIO32 +struct kernel_stat + { + unsigned int st_dev; + unsigned int __pad1[3]; + unsigned long long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + int st_uid; + int st_gid; + unsigned int st_rdev; + unsigned int __pad2[3]; + long long st_size; + unsigned int st_atime_sec; + unsigned int st_atime_nsec; + unsigned int st_mtime_sec; + unsigned int st_mtime_nsec; + unsigned int st_ctime_sec; + unsigned int st_ctime_nsec; + unsigned int st_blksize; + unsigned int __pad3; + unsigned long long st_blocks; + }; +#else +struct kernel_stat + { + unsigned long int st_dev; + long int __pad1[3]; /* Reserved for network id */ + unsigned long int st_ino; + unsigned long int st_mode; + unsigned long int st_nlink; + long int st_uid; + long int st_gid; + unsigned long int st_rdev; + long int __pad2[2]; + long int st_size; + long int __pad3; + unsigned int st_atime_sec; + unsigned int st_atime_nsec; + unsigned int st_mtime_sec; + unsigned int st_mtime_nsec; + unsigned int st_ctime_sec; + unsigned int st_ctime_nsec; + long int st_blksize; + long int st_blocks; + char st_fstype[16]; /* Filesystem type name, unsupported */ + long st_pad4[8]; + /* Linux specific fields */ + unsigned int st_flags; + unsigned int st_gen; + }; +#endif + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 0 +#define XSTAT_IS_XSTAT64 0 +#if _MIPS_SIM == _ABI64 +# define STATFS_IS_STATFS64 1 +#else +# define STATFS_IS_STATFS64 0 +#endif +/* MIPS64 has unsigned 32 bit timestamps fields, so use statx as well. */ +#if _MIPS_SIM == _ABI64 +# define STAT_HAS_TIME32 +#endif + +#endif diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h new file mode 100644 index 0000000000..ee853483cc --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h @@ -0,0 +1,73 @@ +/* Struct stat/stat64 to stat/stat64 conversion for Linux. + Copyright (C) 2020-2021 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, see + . */ + +#include +#include + +static inline long int +__cp_kstat_stat (const struct kernel_stat *kst, struct stat *st) +{ + if (! in_ino_t_range (kst->st_ino) + || ! in_off_t_range (kst->st_size) + || ! in_blkcnt_t_range (kst->st_blocks)) + return -EOVERFLOW; + + st->st_dev = kst->st_dev; + memset (&st->st_pad1, 0, sizeof (st->st_pad1)); + st->st_ino = kst->st_ino; + st->st_mode = kst->st_mode; + st->st_nlink = kst->st_nlink; + st->st_uid = kst->st_uid; + st->st_gid = kst->st_gid; + st->st_rdev = kst->st_rdev; + memset (&st->st_pad2, 0, sizeof (st->st_pad2)); + st->st_size = kst->st_size; + st->st_pad3 = 0; + st->st_atim.tv_sec = kst->st_atime_sec; + st->st_atim.tv_nsec = kst->st_atime_nsec; + st->st_mtim.tv_sec = kst->st_mtime_sec; + st->st_mtim.tv_nsec = kst->st_mtime_nsec; + st->st_ctim.tv_sec = kst->st_ctime_sec; + st->st_ctim.tv_nsec = kst->st_ctime_nsec; + st->st_blksize = kst->st_blksize; + st->st_blocks = kst->st_blocks; + memset (&st->st_pad5, 0, sizeof (st->st_pad5)); + + return 0; +} + +static inline void +__cp_kstat_stat64_t64 (const struct kernel_stat *kst, struct __stat64_t64 *st) +{ + st->st_dev = kst->st_dev; + st->st_ino = kst->st_ino; + st->st_mode = kst->st_mode; + st->st_nlink = kst->st_nlink; + st->st_uid = kst->st_uid; + st->st_gid = kst->st_gid; + st->st_rdev = kst->st_rdev; + st->st_size = kst->st_size; + st->st_blksize = kst->st_blksize; + st->st_blocks = kst->st_blocks; + st->st_atim.tv_sec = kst->st_atime_sec; + st->st_atim.tv_nsec = kst->st_atime_nsec; + st->st_mtim.tv_sec = kst->st_mtime_sec; + st->st_mtim.tv_nsec = kst->st_mtime_nsec; + st->st_ctim.tv_sec = kst->st_ctime_sec; + st->st_ctim.tv_nsec = kst->st_ctime_nsec; +} diff --git a/lib/libc/glibc/io/mknodat.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/mknodat.c similarity index 70% rename from lib/libc/glibc/io/mknodat.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/mknodat.c index b5fd5c5dc5..3bb2ac4263 100644 --- a/lib/libc/glibc/io/mknodat.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/mknodat.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1995-2021 Free Software Foundation, Inc. +/* Create a special or ordinary file. Linux version. + Copyright (C) 2020-2021 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 @@ -18,14 +19,18 @@ #include #include #include +#include int __mknodat (int fd, const char *path, mode_t mode, dev_t dev) { - __set_errno (ENOSYS); - return -1; + /* The user-exported dev_t is 64-bit while the kernel interface is + 32-bit. */ + unsigned int k_dev = dev; + if (k_dev != dev) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); + + return INLINE_SYSCALL_CALL (mknodat, fd, path, mode, k_dev); } libc_hidden_def (__mknodat) weak_alias (__mknodat, mknodat) - -stub_warning (mknodat) diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/nios2/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/nios2/kernel_stat.h new file mode 100644 index 0000000000..1af30dab6f --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/nios2/kernel_stat.h @@ -0,0 +1,22 @@ +/* Internal definitions for stat functions. Linux/nios2. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Chris Metcalf , 2011. + + 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, see + . */ + +#define STAT_IS_KERNEL_STAT 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h new file mode 100644 index 0000000000..e89ee5fdc8 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/powerpc/powerpc32/kernel_stat.h @@ -0,0 +1,53 @@ +/* Definition of `struct stat' used in the kernel. + Copyright (C) 1997-2021 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, see + . */ + +struct kernel_stat + { + unsigned int st_dev; + unsigned int st_ino; + unsigned int st_mode; + unsigned short st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + 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 __glibc_reserved4; +#define _HAVE___UNUSED4 + unsigned long int __glibc_reserved5; +#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___UNUSED4 +#define _HAVE_STAT64___UNUSED5 +#define _HAVE_STAT64___PAD2 +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/s390/s390-32/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/s390/s390-32/kernel_stat.h new file mode 100644 index 0000000000..b1bc1459f0 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/s390/s390-32/kernel_stat.h @@ -0,0 +1,40 @@ +/* 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 __glibc_reserved4; +#define _HAVE___UNUSED4 + unsigned long int __glibc_reserved5; +#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 +#define _HAVE_STAT64___ST_INO +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/sh/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/sh/kernel_stat.h new file mode 100644 index 0000000000..b1bc1459f0 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/sh/kernel_stat.h @@ -0,0 +1,40 @@ +/* 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 __glibc_reserved4; +#define _HAVE___UNUSED4 + unsigned long int __glibc_reserved5; +#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 +#define _HAVE_STAT64___ST_INO +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h new file mode 100644 index 0000000000..4a2df42d37 --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h @@ -0,0 +1,37 @@ +/* Definition of `struct stat' used in the kernel */ +struct kernel_stat + { + unsigned short int st_dev; + unsigned long int st_ino; + unsigned short int st_mode; + short int st_nlink; + unsigned short int st_uid; + unsigned short int st_gid; + unsigned short int st_rdev; + long int st_size; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + long int st_blksize; + long int st_blocks; + unsigned long int __glibc_reserved4; + unsigned long int __glibc_reserved5; + }; + +#define _HAVE___UNUSED4 +#define _HAVE___UNUSED5 + +#define _HAVE_STAT___UNUSED4 +#define _HAVE_STAT___UNUSED5 +#define _HAVE_STAT___PAD1 +#define _HAVE_STAT___PAD2 +#define _HAVE_STAT64___UNUSED4 +#define _HAVE_STAT64___UNUSED5 +#define _HAVE_STAT64___PAD2 +#define _HAVE_STAT_NSEC +#define _HAVE_STAT64_NSEC + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 1 +#define XSTAT_IS_XSTAT64 0 +#define STATFS_IS_STATFS64 0 diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h new file mode 100644 index 0000000000..29d18908da --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h @@ -0,0 +1,58 @@ +#ifndef _KERNEL_STAT_H +#define _KERNEL_STAT_H + +/* Definition of `struct stat' used in the kernel */ +struct kernel_stat + { + unsigned int st_dev; + unsigned long int st_ino; + unsigned int st_mode; + short int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_rdev; + long int st_size; + long int st_atime_sec; + long int st_mtime_sec; + long int st_ctime_sec; + long int st_blksize; + long int st_blocks; + unsigned long int __glibc_reserved1; + unsigned long int __glibc_reserved2; + }; + +/* Definition of `struct stat64' used in the kernel. */ +struct kernel_stat64 + { + unsigned long int st_dev; + unsigned long int st_ino; + unsigned long int st_nlink; + + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int __pad0; + + unsigned long int st_rdev; + long int st_size; + long int st_blksize; + long int st_blocks; + + unsigned long int st_atime_sec; + unsigned long int st_atime_nsec; + unsigned long int st_mtime_sec; + unsigned long int st_mtime_nsec; + unsigned long int st_ctime_sec; + unsigned long int st_ctime_nsec; + long int __glibc_reserved[3]; + }; + +#define STAT_IS_KERNEL_STAT 0 +#define STAT64_IS_KERNEL_STAT64 0 +#define XSTAT_IS_XSTAT64 1 +#ifdef __arch64__ +# define STATFS_IS_STATFS64 1 +#else +# define STATFS_IS_STATFS64 0 +#endif +#endif /* _KERNEL_STAT_H */ diff --git a/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc64/kstat_cp.h b/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc64/kstat_cp.h new file mode 100644 index 0000000000..7d7c629add --- /dev/null +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/sparc/sparc64/kstat_cp.h @@ -0,0 +1,44 @@ +/* Struct kernel_stat64 to stat64. Linux/SPARC version. + Copyright (C) 2020-2021 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, see + . */ + +#include + +static inline void +__cp_stat64_kstat64 (struct stat64 *st64, const struct kernel_stat64 *kst64) +{ + st64->st_dev = kst64->st_dev; + st64->__pad1 = 0; + st64->st_ino = kst64->st_ino; + st64->st_mode = kst64->st_mode; + st64->st_nlink = kst64->st_nlink; + st64->st_uid = kst64->st_uid; + st64->st_gid = kst64->st_gid; + st64->st_rdev = kst64->st_rdev; + st64->__pad2 = 0; + st64->st_size = kst64->st_size; + st64->st_blksize = kst64->st_blksize; + st64->st_blocks = kst64->st_blocks; + st64->st_atim.tv_sec = kst64->st_atime_sec; + st64->st_atim.tv_nsec = kst64->st_atime_nsec; + st64->st_mtim.tv_sec = kst64->st_mtime_sec; + st64->st_mtim.tv_nsec = kst64->st_mtime_nsec; + st64->st_ctim.tv_sec = kst64->st_ctime_sec; + st64->st_ctim.tv_nsec = kst64->st_ctime_nsec; + st64->__glibc_reserved4 = 0; + st64->__glibc_reserved5 = 0; +} diff --git a/lib/libc/glibc/io/stat.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/stat.c similarity index 85% rename from lib/libc/glibc/io/stat.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/stat.c index ea314941e3..95a50016fc 100644 --- a/lib/libc/glibc/io/stat.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/stat.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1996-2021 Free Software Foundation, Inc. +/* Get file status. Linux version. + Copyright (C) 2020-2021 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 @@ -17,7 +18,9 @@ #include #include +#include +#if !XSTAT_IS_XSTAT64 int __stat (const char *file, struct stat *buf) { @@ -25,3 +28,4 @@ __stat (const char *file, struct stat *buf) } weak_alias (__stat, stat) +#endif diff --git a/lib/libc/glibc/io/fstatat64.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/stat64.c similarity index 52% rename from lib/libc/glibc/io/fstatat64.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/stat64.c index e6d9c197cb..329ab11f4b 100644 --- a/lib/libc/glibc/io/fstatat64.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/stat64.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2005-2021 Free Software Foundation, Inc. +/* Get file status. Linux version. + Copyright (C) 2020-2021 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 @@ -15,28 +16,37 @@ License along with the GNU C Library; if not, see . */ +#define __stat __redirect___stat +#define stat __redirect_stat #include -#include #include +#include +#include int -__fstatat64 (int fd, const char *file, struct stat64 *buf, int flag) +__stat64_time64 (const char *file, struct __stat64_t64 *buf) { - if (fd < 0 && fd != AT_FDCWD) - { - __set_errno (EBADF); - return -1; - } - if (buf == 0 || (flag & ~AT_SYMLINK_NOFOLLOW) != 0) - { - __set_errno (EINVAL); - return -1; - } - - __set_errno (ENOSYS); - return -1; + return __fstatat64_time64 (AT_FDCWD, file, buf, 0); } -hidden_def (__fstatat64) -weak_alias (__fstatat64, fstatat64) +#if __TIMESIZE != 64 +hidden_def (__stat64_time64) -stub_warning (fstatat64) +int +__stat64 (const char *file, struct stat64 *buf) +{ + struct __stat64_t64 st_t64; + return __stat64_time64 (file, &st_t64) + ?: __cp_stat64_t64_stat64 (&st_t64, buf); +} +#endif + +#undef __stat +#undef stat + +hidden_def (__stat64) +weak_alias (__stat64, stat64) + +#if XSTAT_IS_XSTAT64 +strong_alias (__stat64, __stat) +weak_alias (__stat64, stat) +#endif diff --git a/lib/libc/glibc/io/lstat64.c b/lib/libc/glibc/sysdeps/unix/sysv/linux/stat_t64_cp.h similarity index 68% rename from lib/libc/glibc/io/lstat64.c rename to lib/libc/glibc/sysdeps/unix/sysv/linux/stat_t64_cp.h index 9a50937f10..94a8c8a60d 100644 --- a/lib/libc/glibc/io/lstat64.c +++ b/lib/libc/glibc/sysdeps/unix/sysv/linux/stat_t64_cp.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1996-2021 Free Software Foundation, Inc. +/* Copy to/from struct stat with and without 64-bit time_t support. + Copyright (C) 2020-2021 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 @@ -12,16 +13,13 @@ 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, see + License along with the GNU C Library. If not, see . */ #include -#include -int -__lstat64 (const char *file, struct stat64 *buf) -{ - return __fstatat64 (AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW); -} -hidden_def (__lstat64) -weak_alias (__lstat64, lstat64) +#if __TIMESIZE != 64 +extern int __cp_stat64_t64_stat64 (const struct __stat64_t64 *st64_t64, + struct stat64 *st64) + attribute_hidden; +#endif diff --git a/src/glibc.zig b/src/glibc.zig index b963247984..9426cf48a2 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -269,23 +269,25 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { return comp.build_crt_file("Scrt1", .Obj, &[_]Compilation.CSourceFile{ start_os, abi_note_o }); }, .libc_nonshared_a => { + const s = path.sep_str; + const linux_prefix = lib_libc_glibc ++ + "sysdeps" ++ s ++ "unix" ++ s ++ "sysv" ++ s ++ "linux" ++ s; const deps = [_][]const u8{ - lib_libc_glibc ++ "stdlib" ++ path.sep_str ++ "atexit.c", - lib_libc_glibc ++ "stdlib" ++ path.sep_str ++ "at_quick_exit.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "stat.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "fstat.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "lstat.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "stat64.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "fstat64.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "lstat64.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "fstatat.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "fstatat64.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "mknod.c", - lib_libc_glibc ++ "io" ++ path.sep_str ++ "mknodat.c", - lib_libc_glibc ++ "sysdeps" ++ path.sep_str ++ "pthread" ++ path.sep_str ++ - "pthread_atfork.c", - lib_libc_glibc ++ "debug" ++ path.sep_str ++ "stack_chk_fail_local.c", - lib_libc_glibc ++ "csu" ++ path.sep_str ++ "errno.c", + lib_libc_glibc ++ "stdlib" ++ s ++ "atexit.c", + lib_libc_glibc ++ "stdlib" ++ s ++ "at_quick_exit.c", + linux_prefix ++ "stat.c", + linux_prefix ++ "fstat.c", + linux_prefix ++ "lstat.c", + linux_prefix ++ "stat64.c", + linux_prefix ++ "fstat64.c", + linux_prefix ++ "lstat64.c", + linux_prefix ++ "fstatat.c", + linux_prefix ++ "fstatat64.c", + linux_prefix ++ "mknodat.c", + lib_libc_glibc ++ "io" ++ s ++ "mknod.c", + lib_libc_glibc ++ "sysdeps" ++ s ++ "pthread" ++ s ++ "pthread_atfork.c", + lib_libc_glibc ++ "debug" ++ s ++ "stack_chk_fail_local.c", + lib_libc_glibc ++ "csu" ++ s ++ "errno.c", }; var c_source_files: [deps.len]Compilation.CSourceFile = undefined;