[RFC] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content
Lukasz Majewski
lukma@denx.de
Thu Nov 12 10:42:12 GMT 2020
Dear Community,
> 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.
> > ---
> > 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. */
>
> Are there any other comments - despite ones from Andreas - regarding
> this patch?
>
> Joseph, is this patch providing solution which you outlined in the
> other comment?
Gentle ping regarding this review...
>
>
> 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
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/20201112/91a57705/attachment.sig>
More information about the Libc-alpha
mailing list