diff mbox series

[RFC,3/6] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content

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

Commit Message

Lukasz Majewski Dec. 4, 2020, 11:36 p.m. UTC
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

Comments

Lukasz Majewski Dec. 29, 2020, 10:30 a.m. UTC | #1
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 mbox series

Patch

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.  */