From patchwork Tue Oct 20 11:01:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 40758 X-Patchwork-Delegate: l.majewski@majess.pl Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E2378386101D; Tue, 20 Oct 2020 11:02:58 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by sourceware.org (Postfix) with ESMTPS id 2708C386101D for ; Tue, 20 Oct 2020 11:02:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2708C386101D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: sourceware.org; spf=none smtp.mailfrom=lukma@denx.de Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 4CFrLz3sxlz1qs39; Tue, 20 Oct 2020 13:02:51 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 4CFrLz2MbZz1r56l; Tue, 20 Oct 2020 13:02:51 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id rHmgb1MP9V6n; Tue, 20 Oct 2020 13:02:48 +0200 (CEST) X-Auth-Info: d0y8uPck/SOMLG+pK+wteS3WfKW7XpiPBiPQK1OyxSs= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Tue, 20 Oct 2020 13:02:48 +0200 (CEST) From: Lukasz Majewski To: Joseph Myers , Paul Eggert , Adhemerval Zanella Subject: [RFC] y2038: Export struct_stat_time64_helper.h with Y2038 safe stat{64} content Date: Tue, 20 Oct 2020 13:01:54 +0200 Message-Id: <20201020110154.10586-1-lukma@denx.de> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Spam-Status: No, score=-16.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Florian Weimer , GNU C Library , Andreas Schwab , Stepan Golosunov , Alistair Francis Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" 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 #include +#ifdef __USE_TIME_BITS64 +# include +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 +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 + . */ + +#ifndef _BITS_STRUCT_STAT_TIME64_HELPER_H +#define _BITS_STRUCT_STAT_TIME64_HELPER_H 1 + +#include + +/* 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 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 +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 +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 +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 +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 +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 +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 #if __WORDSIZE == 32 - +# ifdef __USE_TIME_BITS64 +# include +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 +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 - -/* 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 +# include +# 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 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 +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 +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. */