[RFC 3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content
Lukasz Majewski
lukma@denx.de
Tue Dec 29 10:30:49 GMT 2020
Dear Community,
> This patch exports fields of y2038 safe members of struct stat when
> -D_TIME_BITS=64 is passed as compilation flag.
>
> Such approach will allow avoiding many copies of the same structure
> for several other architectures.
>
> It was also necessary to redefine some parts of this structure for
> the glibc internal struct __stat64_t64 as the struct __timespec64
> is not exported and only used locally in the glibc.
>
> Exported, port specific (with __WORDSIZE=32 && __TIMESIZE!=64),
> struct stat has been modified to support 64 bit time as well.
I would like to ask for review on this patch, as it is crucial for 64
bit stat support on ports with __WORDSIZE != 64 && _TIMESIZE==32.
It shall not bring any issues untill __USE_TIME_BITS64 is defined.
> ---
> sysdeps/unix/sysv/linux/Makefile | 3 +-
> sysdeps/unix/sysv/linux/bits/struct_stat.h | 17 ++++-
> .../linux/bits/struct_stat_time64_helper.h | 70
> +++++++++++++++++++ .../unix/sysv/linux/m68k/bits/struct_stat.h |
> 16 +++++ .../sysv/linux/microblaze/bits/struct_stat.h | 16 +++++
> .../unix/sysv/linux/mips/bits/struct_stat.h | 16 +++++
> .../sysv/linux/powerpc/bits/struct_stat.h | 48 ++++++++-----
> sysdeps/unix/sysv/linux/struct_stat_time64.h | 60 +++-------------
> .../unix/sysv/linux/x86/bits/struct_stat.h | 16 +++++
> 9 files changed, 194 insertions(+), 68 deletions(-)
> create mode 100644
> sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
>
> diff --git a/sysdeps/unix/sysv/linux/Makefile
> b/sysdeps/unix/sysv/linux/Makefile index 09604e128b..2d5cf9bf09 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -97,7 +97,8 @@ sysdep_headers += sys/mount.h sys/acct.h \
> bits/types/struct_msqid_ds.h \
> bits/types/struct_shmid_ds.h \
> bits/ipc-perm.h \
> - bits/struct_stat.h
> + bits/struct_stat.h \
> + bits/struct_stat_time64_helper.h
>
> tests += tst-clone tst-clone2 tst-clone3 tst-fanotify
> tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max
> tst-ttyname \ diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/bits/struct_stat.h index
> 344bffece6..6dd7aeffcf 100644 ---
> a/sysdeps/unix/sysv/linux/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/bits/struct_stat.h @@ -26,6 +26,13 @@
> #include <bits/endian.h>
> #include <bits/wordsize.h>
>
> +#ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> + {
> + __STAT64_T64_CONTENT
> + };
> +#else
> struct stat
> {
> __dev_t st_dev; /* Device. */
> @@ -81,8 +88,16 @@ struct stat
> __ino64_t st_ino; /* File serial
> number. */ #endif
> };
> +#endif /* __USE_TIME_BITS64 */
>
> #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat64
> {
> __dev_t st_dev; /* Device. */
> @@ -119,6 +134,7 @@ struct stat64
> # endif
> __ino64_t st_ino; /* File serial
> number. */ };
> +# endif /* __USE_TIME_BITS64 */
> #endif
>
> /* Tell code we have these members. */
> @@ -127,5 +143,4 @@ struct stat64
> /* Nanosecond resolution time values are supported. */
> #define _STATBUF_ST_NSEC
>
> -
> #endif /* _BITS_STRUCT_STAT_H */
> diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
> b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h new file
> mode 100644 index 0000000000..3ca6258bd5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
> @@ -0,0 +1,70 @@
> +/* Definition for helper to define struct stat with 64 bit time.
> + Copyright (C) 2020 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#ifndef _BITS_STRUCT_STAT_TIME64_HELPER_H
> +#define _BITS_STRUCT_STAT_TIME64_HELPER_H 1
> +
> +#include <bits/endian.h>
> +
> +/* The definition should be equal to the 'struct __timespec64'
> internal
> + layout. */
> +#if BYTE_ORDER == BIG_ENDIAN
> +# define __fieldts64(name) \
> + __time64_t name; __int32_t :32; __int32_t name ## nsec
> +#else
> +# define __fieldts64(name) \
> + __time64_t name; __int32_t name ## nsec; __int32_t :32
> +#endif
> +
> +# ifdef __USE_XOPEN2K8
> +# define st_atime st_atim.tv_sec
> +# define st_mtime st_mtim.tv_sec
> +# define st_ctime st_ctim.tv_sec
> + /* Nanosecond resolution timestamps are stored in a format
> + equivalent to 'struct timespec'. This is the type used
> + whenever possible but the Unix namespace rules do not allow
> the
> + identifier 'timespec' to appear in the <sys/stat.h> header.
> + Therefore we have to handle the use of this header in strictly
> + standard-compliant sources special. */
> +# define __STAT64_TIME64_CONTENT \
> + struct timespec st_atim; \
> + struct timespec st_mtim; \
> + struct timespec st_ctim;
> +# else
> +# define __STAT64_TIME64_CONTENT \
> + __fieldts64 (st_atime); \
> + __fieldts64 (st_mtime); \
> + __fieldts64 (st_ctime);
> +# endif /* __USE_XOPEN2K8 */
> +
> +/* Content of internal __stat64_t64 struct. */
> +#define __STAT64_T64_CONTENT
> \
> + __dev_t st_dev; /* Device. */
> \
> + __ino64_t st_ino; /* file serial
> number. */ \
> + __mode_t st_mode; /* File mode. */
> \
> + __nlink_t st_nlink; /* Link count. */
> \
> + __uid_t st_uid; /* User ID of the file's
> owner. */ \
> + __gid_t st_gid; /* Group ID of the file's
> group.*/ \
> + __dev_t st_rdev; /* Device number, if
> device. */ \
> + __off64_t st_size; /* Size of file, in
> bytes. */ \
> + __blksize_t st_blksize; /* Optimal block size for
> I/O. */ \
> + __blkcnt64_t st_blocks; /* Number 512-byte blocks
> allocated. */\
> + __STAT64_TIME64_CONTENT
> +
> +# undef __fieldts64
> +#endif /* _BITS_STRUCT_STAT_TIME64_HELPER_H */
> diff --git a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h index
> bf457a0db7..5bf9e110fb 100644 ---
> a/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/m68k/bits/struct_stat.h @@ -23,6 +23,13 @@
> #ifndef _BITS_STRUCT_STAT_H
> #define _BITS_STRUCT_STAT_H 1
>
> +#ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> + {
> + __STAT64_T64_CONTENT
> + };
> +#else
> struct stat
> {
> __dev_t st_dev; /* Device. */
> @@ -78,8 +85,16 @@ struct stat
> __ino64_t st_ino; /* File serial
> number. */ #endif
> };
> +#endif /* __USE_TIME_BITS64 */
>
> #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat64
> {
> __dev_t st_dev; /* Device. */
> @@ -116,6 +131,7 @@ struct stat64
> # endif
> __ino64_t st_ino; /* File serial
> number. */ };
> +# endif /* __USE_TIME_BITS64 */
> #endif
>
> /* Tell code we have these members. */
> diff --git a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h index
> db81543b23..3fac74039a 100644 ---
> a/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/microblaze/bits/struct_stat.h @@ -63,6
> +63,13 @@ struct stat unsigned int __glibc_reserved5;
> };
> #else /* __USE_FILE_OFFSET64 */
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> /* MS: If __USE_FILE_OFFSET64 is setup then struct stat should match
> stat64
> * structure. Glibc has no type __dev64_t that's why I had to use
> standard
> * type for st_dev and st_rdev. Several architectures uses pads
> after st_dev @@ -106,9 +113,17 @@ struct stat
> unsigned int __glibc_reserved4;
> unsigned int __glibc_reserved5;
> };
> +# endif /* __USE_TIME_BITS64 */
> #endif /* __USE_FILE_OFFSET64 */
>
> #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat64
> {
> unsigned long long st_dev; /* Device. */
> @@ -147,6 +162,7 @@ struct stat64
> unsigned int __glibc_reserved4;
> unsigned int __glibc_reserved5;
> };
> +# endif /* __USE_TIME_BITS64 */
> #endif
>
> /* Tell code we have these members. */
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h index
> 5abd71fc23..0b88f7cba5 100644 ---
> a/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/mips/bits/struct_stat.h @@ -119,6 +119,13
> @@ struct stat64 };
> #endif
> #else
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat
> {
> __dev_t st_dev;
> @@ -171,8 +178,16 @@ struct stat
> #endif
> int st_pad5[14];
> };
> +# endif /* __USE_TIME_BITS64 */
>
> #ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat64
> {
> __dev_t st_dev;
> @@ -208,6 +223,7 @@ struct stat64
> __blkcnt64_t st_blocks;
> int st_pad4[14];
> };
> +# endif /* __USE_TIME_BITS64 */
> #endif
> #endif
>
> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h index
> cb41adc7c0..09228e046e 100644 ---
> a/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/powerpc/bits/struct_stat.h @@ -26,35 +26,41
> @@ #include <bits/wordsize.h>
>
> #if __WORDSIZE == 32
> -
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat
> {
> __dev_t st_dev; /* Device. */
> -# ifndef __USE_FILE_OFFSET64
> +# ifndef __USE_FILE_OFFSET64
> unsigned short int __pad1;
> __ino_t st_ino; /* File serial
> number. */ -# else
> +# else
> __ino64_t st_ino; /* File serial
> number. */ -# endif
> +# endif
> __mode_t st_mode; /* File mode. */
> __nlink_t st_nlink; /* Link count. */
> __uid_t st_uid; /* User ID of the file's
> owner. */ __gid_t st_gid; /* Group ID
> of the file's group.*/ __dev_t st_rdev; /*
> Device number, if device. */ unsigned short int __pad2;
> -# ifndef __USE_FILE_OFFSET64
> +# ifndef __USE_FILE_OFFSET64
> __off_t st_size; /* Size of file, in
> bytes. */ -# else
> +# else
> __off64_t st_size; /* Size of file, in
> bytes. */ -# endif
> +# endif
> __blksize_t st_blksize; /* Optimal block size for
> I/O. */
> -# ifndef __USE_FILE_OFFSET64
> +# ifndef __USE_FILE_OFFSET64
> __blkcnt_t st_blocks; /* Number 512-byte blocks
> allocated. */ -# else
> +# else
> __blkcnt64_t st_blocks; /* Number 512-byte blocks
> allocated. */ -# endif
> -# ifdef __USE_XOPEN2K8
> +# endif
> +# ifdef __USE_XOPEN2K8
> /* Nanosecond resolution timestamps are stored in a format
> equivalent to 'struct timespec'. This is the type used
> whenever possible but the Unix namespace rules do not allow
> the @@ -64,23 +70,30 @@ struct stat
> 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. */ -# define st_atime st_atim.tv_sec /*
> Backward compatibility. */ -# define st_mtime st_mtim.tv_sec
> -# define st_ctime st_ctim.tv_sec
> -# else
> +# define st_atime st_atim.tv_sec /* Backward compatibility.
> */ +# define st_mtime st_mtim.tv_sec
> +# define st_ctime st_ctim.tv_sec
> +# else
> __time_t st_atime; /* Time of last
> access. */ unsigned long int st_atimensec; /* Nscecs of last
> access. */ __time_t st_mtime; /* Time of last
> modification. */ unsigned long int st_mtimensec; /* Nsecs of
> last modification. */ __time_t st_ctime; /*
> Time of last status change. */ unsigned long int
> st_ctimensec; /* Nsecs of last status change. */ -# endif
> +# endif
> unsigned long int __glibc_reserved4;
> unsigned long int __glibc_reserved5;
> };
> -
> +# endif /* __USE_TIME_BITS64 */
>
> # ifdef __USE_LARGEFILE64
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat64
> {
> __dev_t st_dev; /* Device. */
> @@ -213,6 +226,7 @@ struct stat64
> unsigned long int __glibc_reserved5;
> unsigned long int __glibc_reserved6;
> };
> +# endif /* __USE_TIME_BITS64 */
> # endif /* __USE_LARGEFILE64 */
> #endif
>
> diff --git a/sysdeps/unix/sysv/linux/struct_stat_time64.h
> b/sysdeps/unix/sysv/linux/struct_stat_time64.h index
> b85385b6f3..5a4949000e 100644 ---
> a/sysdeps/unix/sysv/linux/struct_stat_time64.h +++
> b/sysdeps/unix/sysv/linux/struct_stat_time64.h @@ -23,63 +23,25 @@
> # define __stat64_t64 stat64
> #else
> # ifdef __USE_LARGEFILE64
> -# include <endian.h>
> -
> -/* The definition should be equal to the 'struct __timespec64'
> internal
> - layout. */
> -# if BYTE_ORDER == BIG_ENDIAN
> -# define __fieldts64(name)
> \
> - __time64_t name; __int32_t :32; __int32_t name ## nsec
> -# else
> -# define __fieldts64(name) \
> - __time64_t name; __int32_t name ## nsec; __int32_t :32
> -# endif
> -
> -/* Workaround for the definition from struct_stat.h */
> -# undef st_atime
> -# undef st_mtime
> -# undef st_ctime
> -
> +# include <struct___timespec64.h>
> +# include <bits/struct_stat_time64_helper.h>
> +# ifdef __USE_XOPEN2K8
> +# undef __STAT64_TIME64_CONTENT
> +/* Use glibc internal types for time related members */
> +# define __STAT64_TIME64_CONTENT \
> + struct __timespec64 st_atim; \
> + struct __timespec64 st_mtim; \
> + struct __timespec64 st_ctim;
> +# endif /* __USE_XOPEN2K8 */
> struct __stat64_t64
> {
> - __dev_t st_dev; /* Device. */
> - __ino64_t st_ino; /* file serial
> number. */
> - __mode_t st_mode; /* File mode. */
> - __nlink_t st_nlink; /* Link count. */
> - __uid_t st_uid; /* User ID of the file's
> owner. */
> - __gid_t st_gid; /* Group ID of the file's
> group.*/
> - __dev_t st_rdev; /* Device number, if
> device. */
> - __off64_t st_size; /* Size of file, in
> bytes. */
> - __blksize_t st_blksize; /* Optimal block size for
> I/O. */
> - __blkcnt64_t st_blocks; /* Number 512-byte blocks
> allocated. */ -# ifdef __USE_XOPEN2K8
> - /* Nanosecond resolution timestamps are stored in a format
> - equivalent to 'struct timespec'. This is the type used
> - whenever possible but the Unix namespace rules do not allow
> the
> - identifier 'timespec' to appear in the <sys/stat.h> header.
> - Therefore we have to handle the use of this header in strictly
> - standard-compliant sources special. */
> - struct __timespec64 st_atim; /* Time of last access. */
> - struct __timespec64 st_mtim; /* Time of last
> modification. */
> - struct __timespec64 st_ctim; /* Time of last status
> change. */ -# define st_atime st_atim.tv_sec /* Backward
> compatibility. */ -# define st_mtime st_mtim.tv_sec
> -# define st_ctime st_ctim.tv_sec
> -# else
> - __fieldts64 (st_atime);
> - __fieldts64 (st_mtime);
> - __fieldts64 (st_ctime);
> -# endif /* __USE_XOPEN2K8 */
> + __STAT64_T64_CONTENT
> };
>
> # define _STATBUF_ST_BLKSIZE
> # define _STATBUF_ST_RDEV
> # define _STATBUF_ST_NSEC
>
> -# undef __fieldts64
> -
> # endif /* __USE_LARGEFILE64 */
> -
> # endif /* __TIMESIZE == 64 */
> -
> #endif /* _BITS_STRUCT_STAT_TIME64_H */
> diff --git a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h
> b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h index
> dae7aa46b3..e7e87c62b4 100644 ---
> a/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h +++
> b/sysdeps/unix/sysv/linux/x86/bits/struct_stat.h @@ -23,6 +23,13 @@
> #ifndef _BITS_STRUCT_STAT_H
> #define _BITS_STRUCT_STAT_H 1
>
> +#ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat
> + {
> + __STAT64_T64_CONTENT
> + };
> +#else
> struct stat
> {
> __dev_t st_dev; /* Device. */
> @@ -93,9 +100,17 @@ struct stat
> # endif
> #endif
> };
> +#endif /* __USE_TIME_BITS64 */
>
> #ifdef __USE_LARGEFILE64
> /* Note stat64 has the same shape as stat for x86-64. */
> +# ifdef __USE_TIME_BITS64
> +# include <bits/struct_stat_time64_helper.h>
> +struct stat64
> + {
> + __STAT64_T64_CONTENT
> + };
> +# else
> struct stat64
> {
> __dev_t st_dev; /* Device. */
> @@ -146,6 +161,7 @@ struct stat64
> __ino64_t st_ino; /* File serial
> number. */ # endif
> };
> +# endif /* __USE_TIME_BITS64 */
> #endif
>
> /* Tell code we have these members. */
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20201229/47d86c10/attachment.sig>
More information about the Libc-alpha
mailing list