<sys/stat.h>: Use Linux kernel UAPI header if available and useful

Message ID 87zhmwt76d.fsf@oldenburg2.str.redhat.com
State Superseded
Headers

Commit Message

Florian Weimer June 5, 2019, 2:53 p.m. UTC
  This will automatically import new STATX_* constants.  It also avoids
a conflict between <sys/stat.h> and <linux/stat.h>.

The 256 constant in the new static assert has been validated using
build-many-glibcs.py on all supported architectures.

2019-06-05  Florian Weimer  <fweimer@redhat.com>

	* io/bits/statx.h: Fix typo in error message.  Include
	<linux/stat.h> is available.  Define statx-related constants only
	if STATX_ALL is not defined by <linux/stat.h> (or the header is
	missing altogether).
	* sysdeps/unix/sysv/linux/statx.c: Add static assert for the size
	of struct statx.
  

Comments

Andreas Schwab June 5, 2019, 3:12 p.m. UTC | #1
On Jun 05 2019, Florian Weimer <fweimer@redhat.com> wrote:

> 	* io/bits/statx.h: Fix typo in error message.  Include
> 	<linux/stat.h> is available.  Define statx-related constants only

s/is/if/

> diff --git a/io/bits/statx.h b/io/bits/statx.h
> index cff14b2543..d0dcc353ba 100644
> --- a/io/bits/statx.h
> +++ b/io/bits/statx.h
> @@ -19,9 +19,14 @@
>  /* This interface is based on <linux/stat.h> in Linux.  */
>  
>  #ifndef _SYS_STAT_H
> -# error Never include <bits/stat.x.h> directly, include <sys/stat.h> instead.
> +# error Never include <bits/statx.h> directly, include <sys/stat.h> instead.
>  #endif
>  
> +#if __glibc_has_include (<linux/stat.h>)
> +# include <linux/stat.h>
> +#endif

Wouldn't it be better to add sysdeps/unix/sysv/linux/bits/statx.h where
<linux/stat.h> is included unconditionally?

Andreas.
  
Florian Weimer June 5, 2019, 3:16 p.m. UTC | #2
* Andreas Schwab:

> On Jun 05 2019, Florian Weimer <fweimer@redhat.com> wrote:
>
>> 	* io/bits/statx.h: Fix typo in error message.  Include
>> 	<linux/stat.h> is available.  Define statx-related constants only
>
> s/is/if/
>
>> diff --git a/io/bits/statx.h b/io/bits/statx.h
>> index cff14b2543..d0dcc353ba 100644
>> --- a/io/bits/statx.h
>> +++ b/io/bits/statx.h
>> @@ -19,9 +19,14 @@
>>  /* This interface is based on <linux/stat.h> in Linux.  */
>>  
>>  #ifndef _SYS_STAT_H
>> -# error Never include <bits/stat.x.h> directly, include <sys/stat.h> instead.
>> +# error Never include <bits/statx.h> directly, include <sys/stat.h> instead.
>>  #endif
>>  
>> +#if __glibc_has_include (<linux/stat.h>)
>> +# include <linux/stat.h>
>> +#endif
>
> Wouldn't it be better to add sysdeps/unix/sysv/linux/bits/statx.h where
> <linux/stat.h> is included unconditionally?

I don't think <linux/stat.h> exists as an UAPI header in Linux 3.2,
which is currently the minimum kernel version.  I think it was only
added in Linux 3.7.

Thanks,
Florian
  

Patch

diff --git a/io/bits/statx.h b/io/bits/statx.h
index cff14b2543..d0dcc353ba 100644
--- a/io/bits/statx.h
+++ b/io/bits/statx.h
@@ -19,9 +19,14 @@ 
 /* This interface is based on <linux/stat.h> in Linux.  */
 
 #ifndef _SYS_STAT_H
-# error Never include <bits/stat.x.h> directly, include <sys/stat.h> instead.
+# error Never include <bits/statx.h> directly, include <sys/stat.h> instead.
 #endif
 
+#if __glibc_has_include (<linux/stat.h>)
+# include <linux/stat.h>
+#endif
+
+#ifndef STATX_ALL
 struct statx_timestamp
 {
   __int64_t tv_sec;
@@ -58,28 +63,29 @@  struct statx
   __uint64_t __statx_pad2[14];
 };
 
-#define STATX_TYPE 0x0001U
-#define STATX_MODE 0x0002U
-#define STATX_NLINK 0x0004U
-#define STATX_UID 0x0008U
-#define STATX_GID 0x0010U
-#define STATX_ATIME 0x0020U
-#define STATX_MTIME 0x0040U
-#define STATX_CTIME 0x0080U
-#define STATX_INO 0x0100U
-#define STATX_SIZE 0x0200U
-#define STATX_BLOCKS 0x0400U
-#define STATX_BASIC_STATS 0x07ffU
-#define STATX_ALL 0x0fffU
-#define STATX_BTIME 0x0800U
-#define STATX__RESERVED 0x80000000U
+# define STATX_TYPE 0x0001U
+# define STATX_MODE 0x0002U
+# define STATX_NLINK 0x0004U
+# define STATX_UID 0x0008U
+# define STATX_GID 0x0010U
+# define STATX_ATIME 0x0020U
+# define STATX_MTIME 0x0040U
+# define STATX_CTIME 0x0080U
+# define STATX_INO 0x0100U
+# define STATX_SIZE 0x0200U
+# define STATX_BLOCKS 0x0400U
+# define STATX_BASIC_STATS 0x07ffU
+# define STATX_ALL 0x0fffU
+# define STATX_BTIME 0x0800U
+# define STATX__RESERVED 0x80000000U
 
-#define STATX_ATTR_COMPRESSED 0x0004
-#define STATX_ATTR_IMMUTABLE 0x0010
-#define STATX_ATTR_APPEND 0x0020
-#define STATX_ATTR_NODUMP 0x0040
-#define STATX_ATTR_ENCRYPTED 0x0800
-#define STATX_ATTR_AUTOMOUNT 0x1000
+# define STATX_ATTR_COMPRESSED 0x0004
+# define STATX_ATTR_IMMUTABLE 0x0010
+# define STATX_ATTR_APPEND 0x0020
+# define STATX_ATTR_NODUMP 0x0040
+# define STATX_ATTR_ENCRYPTED 0x0800
+# define STATX_ATTR_AUTOMOUNT 0x1000
+#endif /* !STATX_ALL */
 
 __BEGIN_DECLS
 
diff --git a/sysdeps/unix/sysv/linux/statx.c b/sysdeps/unix/sysv/linux/statx.c
index b99e30dc3e..5d634960a6 100644
--- a/sysdeps/unix/sysv/linux/statx.c
+++ b/sysdeps/unix/sysv/linux/statx.c
@@ -21,6 +21,11 @@ 
 
 #include "statx_generic.c"
 
+/* Ensure that the kernel headers have not changed the struct size.
+   If this ever happens, it may be necessary to introduce a new symbol
+   version.  */
+_Static_assert (sizeof (struct statx) == 256, "struct statx size changed");
+
 int
 statx (int fd, const char *path, int flags,
        unsigned int mask, struct statx *buf)