about summary refs log tree commit diff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/generic/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/generic/bits/stat.h5
-rw-r--r--sysdeps/unix/sysv/linux/generic/stat-check.c29
-rw-r--r--sysdeps/unix/sysv/linux/generic/wordsize-32/overflow.h4
4 files changed, 38 insertions, 2 deletions
diff --git a/sysdeps/unix/sysv/linux/generic/Makefile b/sysdeps/unix/sysv/linux/generic/Makefile
index 7e27e79772..124f83a0ab 100644
--- a/sysdeps/unix/sysv/linux/generic/Makefile
+++ b/sysdeps/unix/sysv/linux/generic/Makefile
@@ -1,3 +1,3 @@
 ifeq ($(subdir),misc)
-sysdep_routines += epoll_create inotify_init
+sysdep_routines += epoll_create inotify_init stat-check
 endif
diff --git a/sysdeps/unix/sysv/linux/generic/bits/stat.h b/sysdeps/unix/sysv/linux/generic/bits/stat.h
index 1565f3f824..34c455ed78 100644
--- a/sysdeps/unix/sysv/linux/generic/bits/stat.h
+++ b/sysdeps/unix/sysv/linux/generic/bits/stat.h
@@ -42,7 +42,10 @@
 
 #if defined __USE_FILE_OFFSET64
 # define __field64(type, type64, name) type64 name
-#elif __WORDSIZE == 64
+#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T
+# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T
+#  error "ino_t and off_t must both be the same type"
+# endif
 # define __field64(type, type64, name) type name
 #elif __BYTE_ORDER == __LITTLE_ENDIAN
 # define __field64(type, type64, name) \
diff --git a/sysdeps/unix/sysv/linux/generic/stat-check.c b/sysdeps/unix/sysv/linux/generic/stat-check.c
new file mode 100644
index 0000000000..c3204ca7f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/generic/stat-check.c
@@ -0,0 +1,29 @@
+/* Static assert for __blkcnt64_t when __INO_T_MATCHES_INO64_T is defined.
+   Copyright (C) 2019 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/>.  */
+
+#include <sys/stat.h>
+#include <bits/typesizes.h>
+
+/* This is due to the layout code in bits/stat.h and the overflow handling in
+   wordsize-32/overflow.h, requiring either all or none of the three types
+   concerned to have padding.  */
+
+#if defined __INO_T_MATCHES_INO64_T
+_Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
+                "__blkcnt_t and __blkcnt64_t must match");
+#endif
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/overflow.h b/sysdeps/unix/sysv/linux/generic/wordsize-32/overflow.h
index 45efcd8fd3..66546b07cc 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/overflow.h
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/overflow.h
@@ -36,12 +36,16 @@ static inline off_t lseek_overflow (loff_t res)
 
 static inline int stat_overflow (struct stat *buf)
 {
+#if defined __INO_T_MATCHES_INO64_T
+  return 0;
+#else
   if (buf->__st_ino_pad == 0 && buf->__st_size_pad == 0
       && buf->__st_blocks_pad == 0)
     return 0;
 
   __set_errno (EOVERFLOW);
   return -1;
+#endif
 }
 
 /* Note that f_files and f_ffree may validly be a sign-extended -1.  */