Message ID | 20201204233604.7430-4-lukma@denx.de |
---|---|
State | New |
Headers | show |
Series | y2038: Prepare glibc to be Y2038 safe for 32 bit ports | expand |
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
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. */