mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] [PATCH] add statx
@ 2020-01-19 12:12 Ben Noordhuis
  2020-01-24  8:38 ` [musl] " Ben Noordhuis
                   ` (4 more replies)
  0 siblings, 5 replies; 27+ messages in thread
From: Ben Noordhuis @ 2020-01-19 12:12 UTC (permalink / raw)
  To: musl; +Cc: Ben Noordhuis

glibc exposes a wrapper for this system call. it's inconvenient that
musl doesn't so let's add one.

ref: https://github.com/rust-lang/rust/pull/67774
---
 include/fcntl.h    | 15 +++++++++++++++
 include/sys/stat.h | 34 ++++++++++++++++++++++++++++++++++
 src/stat/fstatat.c | 27 +--------------------------
 src/stat/statx.c   |  8 ++++++++
 4 files changed, 58 insertions(+), 26 deletions(-)
 create mode 100644 src/stat/statx.c

diff --git a/include/fcntl.h b/include/fcntl.h
index b664cdc4..21050a65 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -106,6 +106,21 @@ int posix_fallocate(int, off_t, off_t);
 #define AT_STATX_DONT_SYNC 0x4000
 #define AT_RECURSIVE 0x8000
 
+#define STATX_TYPE 1U
+#define STATX_MODE 2U
+#define STATX_NLINK 4U
+#define STATX_UID 8U
+#define STATX_GID 0x10U
+#define STATX_ATIME 0x20U
+#define STATX_MTIME 0x40U
+#define STATX_CTIME 0x80U
+#define STATX_INO 0x100U
+#define STATX_SIZE 0x200U
+#define STATX_BLOCKS 0x400U
+#define STATX_BASIC_STATS 0x7ffU
+#define STATX_BTIME 0x800U
+#define STATX_ALL 0xfffU
+
 #define FAPPEND O_APPEND
 #define FFSYNC O_SYNC
 #define FASYNC O_ASYNC
diff --git a/include/sys/stat.h b/include/sys/stat.h
index 10d446c4..5db71590 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -5,6 +5,7 @@ extern "C" {
 #endif
 
 #include <features.h>
+#include <stdint.h>
 
 #define __NEED_dev_t
 #define __NEED_ino_t
@@ -70,6 +71,38 @@ extern "C" {
 #define UTIME_NOW  0x3fffffff
 #define UTIME_OMIT 0x3ffffffe
 
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct statx_timestamp {
+	int64_t tv_sec;
+	uint32_t tv_nsec;
+	int32_t __pad;
+};
+
+struct statx {
+	uint32_t stx_mask;
+	uint32_t stx_blksize;
+	uint64_t stx_attributes;
+	uint32_t stx_nlink;
+	uint32_t stx_uid;
+	uint32_t stx_gid;
+	uint16_t stx_mode;
+	uint16_t __pad0[1];
+	uint64_t stx_ino;
+	uint64_t stx_size;
+	uint64_t stx_blocks;
+	uint64_t stx_attributes_mask;
+	struct statx_timestamp stx_atime;
+	struct statx_timestamp stx_btime;
+	struct statx_timestamp stx_ctime;
+	struct statx_timestamp stx_mtime;
+	uint32_t stx_rdev_major;
+	uint32_t stx_rdev_minor;
+	uint32_t stx_dev_major;
+	uint32_t stx_dev_minor;
+	uint64_t __pad1[14];
+};
+#endif
+
 int stat(const char *__restrict, struct stat *__restrict);
 int fstat(int, struct stat *);
 int lstat(const char *__restrict, struct stat *__restrict);
@@ -93,6 +126,7 @@ int utimensat(int, const char *, const struct timespec [2], int);
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 int lchmod(const char *, mode_t);
+int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
 #define S_IREAD S_IRUSR
 #define S_IWRITE S_IWUSR
 #define S_IEXEC S_IXUSR
diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
index de165b5c..ab22e4c6 100644
--- a/src/stat/fstatat.c
+++ b/src/stat/fstatat.c
@@ -8,36 +8,11 @@
 #include "syscall.h"
 #include "kstat.h"
 
-struct statx {
-	uint32_t stx_mask;
-	uint32_t stx_blksize;
-	uint64_t stx_attributes;
-	uint32_t stx_nlink;
-	uint32_t stx_uid;
-	uint32_t stx_gid;
-	uint16_t stx_mode;
-	uint16_t pad1;
-	uint64_t stx_ino;
-	uint64_t stx_size;
-	uint64_t stx_blocks;
-	uint64_t stx_attributes_mask;
-	struct {
-		int64_t tv_sec;
-		uint32_t tv_nsec;
-		int32_t pad;
-	} stx_atime, stx_btime, stx_ctime, stx_mtime;
-	uint32_t stx_rdev_major;
-	uint32_t stx_rdev_minor;
-	uint32_t stx_dev_major;
-	uint32_t stx_dev_minor;
-	uint64_t spare[14];
-};
-
 static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
 {
 	struct statx stx;
 
-	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
+	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
 	if (ret) return ret;
 
 	*st = (struct stat){
diff --git a/src/stat/statx.c b/src/stat/statx.c
new file mode 100644
index 00000000..36b45d33
--- /dev/null
+++ b/src/stat/statx.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include "syscall.h"
+
+int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
+{
+	return syscall(SYS_statx, dirfd, path, flags, mask, stx);
+}
-- 
2.23.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] Re: [PATCH] add statx
  2020-01-19 12:12 [musl] [PATCH] add statx Ben Noordhuis
@ 2020-01-24  8:38 ` Ben Noordhuis
  2020-01-24 14:01   ` Rich Felker
  2020-01-24 14:00 ` [musl] " Rich Felker
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 27+ messages in thread
From: Ben Noordhuis @ 2020-01-24  8:38 UTC (permalink / raw)
  To: musl

On Sun, Jan 19, 2020 at 1:13 PM Ben Noordhuis <info@bnoordhuis.nl> wrote:
>
> glibc exposes a wrapper for this system call. it's inconvenient that
> musl doesn't so let's add one.
>
> ref: https://github.com/rust-lang/rust/pull/67774
> ---
>  include/fcntl.h    | 15 +++++++++++++++
>  include/sys/stat.h | 34 ++++++++++++++++++++++++++++++++++
>  src/stat/fstatat.c | 27 +--------------------------
>  src/stat/statx.c   |  8 ++++++++
>  4 files changed, 58 insertions(+), 26 deletions(-)
>  create mode 100644 src/stat/statx.c
>
> diff --git a/include/fcntl.h b/include/fcntl.h
> index b664cdc4..21050a65 100644
> --- a/include/fcntl.h
> +++ b/include/fcntl.h
> @@ -106,6 +106,21 @@ int posix_fallocate(int, off_t, off_t);
>  #define AT_STATX_DONT_SYNC 0x4000
>  #define AT_RECURSIVE 0x8000
>
> +#define STATX_TYPE 1U
> +#define STATX_MODE 2U
> +#define STATX_NLINK 4U
> +#define STATX_UID 8U
> +#define STATX_GID 0x10U
> +#define STATX_ATIME 0x20U
> +#define STATX_MTIME 0x40U
> +#define STATX_CTIME 0x80U
> +#define STATX_INO 0x100U
> +#define STATX_SIZE 0x200U
> +#define STATX_BLOCKS 0x400U
> +#define STATX_BASIC_STATS 0x7ffU
> +#define STATX_BTIME 0x800U
> +#define STATX_ALL 0xfffU
> +
>  #define FAPPEND O_APPEND
>  #define FFSYNC O_SYNC
>  #define FASYNC O_ASYNC
> diff --git a/include/sys/stat.h b/include/sys/stat.h
> index 10d446c4..5db71590 100644
> --- a/include/sys/stat.h
> +++ b/include/sys/stat.h
> @@ -5,6 +5,7 @@ extern "C" {
>  #endif
>
>  #include <features.h>
> +#include <stdint.h>
>
>  #define __NEED_dev_t
>  #define __NEED_ino_t
> @@ -70,6 +71,38 @@ extern "C" {
>  #define UTIME_NOW  0x3fffffff
>  #define UTIME_OMIT 0x3ffffffe
>
> +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
> +struct statx_timestamp {
> +       int64_t tv_sec;
> +       uint32_t tv_nsec;
> +       int32_t __pad;
> +};
> +
> +struct statx {
> +       uint32_t stx_mask;
> +       uint32_t stx_blksize;
> +       uint64_t stx_attributes;
> +       uint32_t stx_nlink;
> +       uint32_t stx_uid;
> +       uint32_t stx_gid;
> +       uint16_t stx_mode;
> +       uint16_t __pad0[1];
> +       uint64_t stx_ino;
> +       uint64_t stx_size;
> +       uint64_t stx_blocks;
> +       uint64_t stx_attributes_mask;
> +       struct statx_timestamp stx_atime;
> +       struct statx_timestamp stx_btime;
> +       struct statx_timestamp stx_ctime;
> +       struct statx_timestamp stx_mtime;
> +       uint32_t stx_rdev_major;
> +       uint32_t stx_rdev_minor;
> +       uint32_t stx_dev_major;
> +       uint32_t stx_dev_minor;
> +       uint64_t __pad1[14];
> +};
> +#endif
> +
>  int stat(const char *__restrict, struct stat *__restrict);
>  int fstat(int, struct stat *);
>  int lstat(const char *__restrict, struct stat *__restrict);
> @@ -93,6 +126,7 @@ int utimensat(int, const char *, const struct timespec [2], int);
>
>  #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>  int lchmod(const char *, mode_t);
> +int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
>  #define S_IREAD S_IRUSR
>  #define S_IWRITE S_IWUSR
>  #define S_IEXEC S_IXUSR
> diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
> index de165b5c..ab22e4c6 100644
> --- a/src/stat/fstatat.c
> +++ b/src/stat/fstatat.c
> @@ -8,36 +8,11 @@
>  #include "syscall.h"
>  #include "kstat.h"
>
> -struct statx {
> -       uint32_t stx_mask;
> -       uint32_t stx_blksize;
> -       uint64_t stx_attributes;
> -       uint32_t stx_nlink;
> -       uint32_t stx_uid;
> -       uint32_t stx_gid;
> -       uint16_t stx_mode;
> -       uint16_t pad1;
> -       uint64_t stx_ino;
> -       uint64_t stx_size;
> -       uint64_t stx_blocks;
> -       uint64_t stx_attributes_mask;
> -       struct {
> -               int64_t tv_sec;
> -               uint32_t tv_nsec;
> -               int32_t pad;
> -       } stx_atime, stx_btime, stx_ctime, stx_mtime;
> -       uint32_t stx_rdev_major;
> -       uint32_t stx_rdev_minor;
> -       uint32_t stx_dev_major;
> -       uint32_t stx_dev_minor;
> -       uint64_t spare[14];
> -};
> -
>  static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
>  {
>         struct statx stx;
>
> -       int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
> +       int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
>         if (ret) return ret;
>
>         *st = (struct stat){
> diff --git a/src/stat/statx.c b/src/stat/statx.c
> new file mode 100644
> index 00000000..36b45d33
> --- /dev/null
> +++ b/src/stat/statx.c
> @@ -0,0 +1,8 @@
> +#define _GNU_SOURCE
> +#include <sys/stat.h>
> +#include "syscall.h"
> +
> +int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
> +{
> +       return syscall(SYS_statx, dirfd, path, flags, mask, stx);
> +}
> --
> 2.23.0
>

Can I get some feedback on this patch, even if it's just "no because"? Thanks.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-19 12:12 [musl] [PATCH] add statx Ben Noordhuis
  2020-01-24  8:38 ` [musl] " Ben Noordhuis
@ 2020-01-24 14:00 ` Rich Felker
  2020-01-24 15:27   ` Florian Weimer
  2022-08-27 14:57 ` [musl] [PATCH 0/1] " Duncan Bellamy
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2020-01-24 14:00 UTC (permalink / raw)
  To: musl

On Sun, Jan 19, 2020 at 01:12:47PM +0100, Ben Noordhuis wrote:
> glibc exposes a wrapper for this system call. it's inconvenient that
> musl doesn't so let's add one.
> 
> ref: https://github.com/rust-lang/rust/pull/67774
> ---
>  include/fcntl.h    | 15 +++++++++++++++
>  include/sys/stat.h | 34 ++++++++++++++++++++++++++++++++++
>  src/stat/fstatat.c | 27 +--------------------------
>  src/stat/statx.c   |  8 ++++++++
>  4 files changed, 58 insertions(+), 26 deletions(-)
>  create mode 100644 src/stat/statx.c
> 
> diff --git a/include/fcntl.h b/include/fcntl.h
> index b664cdc4..21050a65 100644
> --- a/include/fcntl.h
> +++ b/include/fcntl.h
> @@ -106,6 +106,21 @@ int posix_fallocate(int, off_t, off_t);
>  #define AT_STATX_DONT_SYNC 0x4000
>  #define AT_RECURSIVE 0x8000
>  
> +#define STATX_TYPE 1U
> +#define STATX_MODE 2U
> +#define STATX_NLINK 4U
> +#define STATX_UID 8U
> +#define STATX_GID 0x10U
> +#define STATX_ATIME 0x20U
> +#define STATX_MTIME 0x40U
> +#define STATX_CTIME 0x80U
> +#define STATX_INO 0x100U
> +#define STATX_SIZE 0x200U
> +#define STATX_BLOCKS 0x400U
> +#define STATX_BASIC_STATS 0x7ffU
> +#define STATX_BTIME 0x800U
> +#define STATX_ALL 0xfffU
> +

This is under BSD||GNU (i.e. DEFAULT||ALL) rather than just under the
latter. Is there a reason for that? Generally the extensions that are
pretty clearly Linux-only, as opposed to something that other
POSIX-based OS's are likely to adopt, are put under GNU/ALL to
discourage their use without intent and to avoid namespace clutter.

Also, I don't think it makes sense for these to be in fcntl.h at all,
and I don't think there's precedent. glibc has them exposed via
sys/stat.h not fcntl.h. And it looks like glibc exposes them (and all
the statx stuff) only under _GNU_SOURCE:

#ifdef __USE_GNU
# include <bits/statx.h>
#endif

So in summary, unless there's strong reason to do differently, move to
sys/stat.h and make _GNU_SOURCE-only.

>  #define FAPPEND O_APPEND
>  #define FFSYNC O_SYNC
>  #define FASYNC O_ASYNC
> diff --git a/include/sys/stat.h b/include/sys/stat.h
> index 10d446c4..5db71590 100644
> --- a/include/sys/stat.h
> +++ b/include/sys/stat.h
> @@ -5,6 +5,7 @@ extern "C" {
>  #endif
>  
>  #include <features.h>
> +#include <stdint.h>

Extra indirect headers can't be pulled in unconditionally beyond
what's specified for sys/stat.h. Instead you could put it under
_GNU_SOURCE (this is another reason not to put it in default), but
what would be better is putting just the __NEED_* for the types you
want under _GNU_SOURCE here, e.g.

#ifdef _GNU_SOURCE
#define __NEED_uint16_t
#define __NEED_uint32_t
#define __NEED_uint64_t
#define __NEED_int32_t
#define __NEED_int64_t
#endif

>  int stat(const char *__restrict, struct stat *__restrict);
>  int fstat(int, struct stat *);
>  int lstat(const char *__restrict, struct stat *__restrict);
> @@ -93,6 +126,7 @@ int utimensat(int, const char *, const struct timespec [2], int);
>  
>  #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>  int lchmod(const char *, mode_t);
> +int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);

Also _GNU_SOURCE-only.

>  #define S_IREAD S_IRUSR
>  #define S_IWRITE S_IWUSR
>  #define S_IEXEC S_IXUSR
> diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
> index de165b5c..ab22e4c6 100644
> --- a/src/stat/fstatat.c
> +++ b/src/stat/fstatat.c
> @@ -8,36 +8,11 @@
>  #include "syscall.h"
>  #include "kstat.h"
>  
> -struct statx {
> -	uint32_t stx_mask;
> -	uint32_t stx_blksize;
> -	uint64_t stx_attributes;
> -	uint32_t stx_nlink;
> -	uint32_t stx_uid;
> -	uint32_t stx_gid;
> -	uint16_t stx_mode;
> -	uint16_t pad1;
> -	uint64_t stx_ino;
> -	uint64_t stx_size;
> -	uint64_t stx_blocks;
> -	uint64_t stx_attributes_mask;
> -	struct {
> -		int64_t tv_sec;
> -		uint32_t tv_nsec;
> -		int32_t pad;
> -	} stx_atime, stx_btime, stx_ctime, stx_mtime;
> -	uint32_t stx_rdev_major;
> -	uint32_t stx_rdev_minor;
> -	uint32_t stx_dev_major;
> -	uint32_t stx_dev_minor;
> -	uint64_t spare[14];
> -};
> -
>  static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
>  {
>  	struct statx stx;
>  
> -	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
> +	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
>  	if (ret) return ret;

This looks ok.

>  	*st = (struct stat){
> diff --git a/src/stat/statx.c b/src/stat/statx.c
> new file mode 100644
> index 00000000..36b45d33
> --- /dev/null
> +++ b/src/stat/statx.c
> @@ -0,0 +1,8 @@
> +#define _GNU_SOURCE
> +#include <sys/stat.h>
> +#include "syscall.h"
> +
> +int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
> +{
> +	return syscall(SYS_statx, dirfd, path, flags, mask, stx);
> +}
> -- 
> 2.23.0

Should we do fallback translation from stat if SYS_statx fails with
ENOSYS? My leaning would be yes.

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] Re: [PATCH] add statx
  2020-01-24  8:38 ` [musl] " Ben Noordhuis
@ 2020-01-24 14:01   ` Rich Felker
  2020-01-28  8:59     ` Ben Noordhuis
  0 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2020-01-24 14:01 UTC (permalink / raw)
  To: musl

On Fri, Jan 24, 2020 at 09:38:49AM +0100, Ben Noordhuis wrote:
> 
> Can I get some feedback on this patch, even if it's just "no because"? Thanks.

Sorry aboout that; I'd just had my mind on other things and hadn't
taken the time to make a good review yet.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-24 14:00 ` [musl] " Rich Felker
@ 2020-01-24 15:27   ` Florian Weimer
  2020-01-24 15:54     ` Rich Felker
  0 siblings, 1 reply; 27+ messages in thread
From: Florian Weimer @ 2020-01-24 15:27 UTC (permalink / raw)
  To: Rich Felker; +Cc: musl

* Rich Felker:

> This is under BSD||GNU (i.e. DEFAULT||ALL) rather than just under the
> latter. Is there a reason for that? Generally the extensions that are
> pretty clearly Linux-only, as opposed to something that other
> POSIX-based OS's are likely to adopt, are put under GNU/ALL to
> discourage their use without intent and to avoid namespace clutter.

statx is not Linux-specific in glibc, but also available on Hurd.

We received feedback that our headers are not useful due to the
__u64/uint64_t mismatch.

  <https://sourceware.org/bugzilla/show_bug.cgi?id=25292
  <https://sourceware.org/ml/libc-alpha/2019-12/msg00631.html>

Thanks,
Florian


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-24 15:27   ` Florian Weimer
@ 2020-01-24 15:54     ` Rich Felker
  2020-01-24 16:12       ` Florian Weimer
  0 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2020-01-24 15:54 UTC (permalink / raw)
  To: Florian Weimer; +Cc: musl

On Fri, Jan 24, 2020 at 04:27:47PM +0100, Florian Weimer wrote:
> * Rich Felker:
> 
> > This is under BSD||GNU (i.e. DEFAULT||ALL) rather than just under the
> > latter. Is there a reason for that? Generally the extensions that are
> > pretty clearly Linux-only, as opposed to something that other
> > POSIX-based OS's are likely to adopt, are put under GNU/ALL to
> > discourage their use without intent and to avoid namespace clutter.
> 
> statx is not Linux-specific in glibc, but also available on Hurd.

OK, well GNU/Linux-specific. :-) Some ppl find _GNU_SOURCE odd for
stuff that comes from Linux not GNU, but in this case it seems pretty
appropriate since GNU and Linux are the two systems doing it.

> We received feedback that our headers are not useful due to the
> __u64/uint64_t mismatch.
> 
>   <https://sourceware.org/bugzilla/show_bug.cgi?id=25292
>   <https://sourceware.org/ml/libc-alpha/2019-12/msg00631.html>

Uhg. That change seems unfortunate since it's incompatible with
theoretical future archs having 128-bit long long -- an idea I'm not
much a fan of, but don't actually want to preclude. Is there a reason
to actually care about compatibility with the kernel types? It's not
like both struct definitions can be included in the same source
anyway; the tags would clash. Using the canonical uintN_t types makes
more sense from an API perspective, I think; kernel assumptions about
types should not leak into an API intended to be clean and shared with
non-Linux implementations.

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-24 15:54     ` Rich Felker
@ 2020-01-24 16:12       ` Florian Weimer
  2020-01-24 16:29         ` Rich Felker
  0 siblings, 1 reply; 27+ messages in thread
From: Florian Weimer @ 2020-01-24 16:12 UTC (permalink / raw)
  To: Rich Felker; +Cc: musl

* Rich Felker:

> On Fri, Jan 24, 2020 at 04:27:47PM +0100, Florian Weimer wrote:
>> * Rich Felker:
>> 
>> > This is under BSD||GNU (i.e. DEFAULT||ALL) rather than just under the
>> > latter. Is there a reason for that? Generally the extensions that are
>> > pretty clearly Linux-only, as opposed to something that other
>> > POSIX-based OS's are likely to adopt, are put under GNU/ALL to
>> > discourage their use without intent and to avoid namespace clutter.
>> 
>> statx is not Linux-specific in glibc, but also available on Hurd.
>
> OK, well GNU/Linux-specific. :-) Some ppl find _GNU_SOURCE odd for
> stuff that comes from Linux not GNU, but in this case it seems pretty
> appropriate since GNU and Linux are the two systems doing it.

Sorry for nit-picking, it's common to both GNU and Linux.

gettid is Linux-specific, and so is pthread_getattr_default_np.

pkey_set is something that is GNU/Linux-specific in the sense that is
something that's only part of glibc, and only on Linux.

>> We received feedback that our headers are not useful due to the
>> __u64/uint64_t mismatch.
>> 
>>   <https://sourceware.org/bugzilla/show_bug.cgi?id=25292
>>   <https://sourceware.org/ml/libc-alpha/2019-12/msg00631.html>
>
> Uhg. That change seems unfortunate since it's incompatible with
> theoretical future archs having 128-bit long long -- an idea I'm not
> much a fan of, but don't actually want to preclude. Is there a reason
> to actually care about compatibility with the kernel types?

Yes, printf format strings. 8-(

> It's not like both struct definitions can be included in the same
> source anyway; the tags would clash. Using the canonical uintN_t types
> makes more sense from an API perspective, I think; kernel assumptions
> about types should not leak into an API intended to be clean and
> shared with non-Linux implementations.

I thought so too, which is why I used them.

But it is fairly compelling to use the kernel types if the header is
available, so that we don't have to patch and rebuild glibc if someone
backports new statx features into the kernel.  That's why I added the
__has_include kludge.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-24 16:12       ` Florian Weimer
@ 2020-01-24 16:29         ` Rich Felker
  2020-01-28 10:41           ` Florian Weimer
  0 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2020-01-24 16:29 UTC (permalink / raw)
  To: Florian Weimer; +Cc: musl

On Fri, Jan 24, 2020 at 05:12:51PM +0100, Florian Weimer wrote:
> * Rich Felker:
> 
> > On Fri, Jan 24, 2020 at 04:27:47PM +0100, Florian Weimer wrote:
> >> * Rich Felker:
> >> 
> >> > This is under BSD||GNU (i.e. DEFAULT||ALL) rather than just under the
> >> > latter. Is there a reason for that? Generally the extensions that are
> >> > pretty clearly Linux-only, as opposed to something that other
> >> > POSIX-based OS's are likely to adopt, are put under GNU/ALL to
> >> > discourage their use without intent and to avoid namespace clutter.
> >> 
> >> statx is not Linux-specific in glibc, but also available on Hurd.
> >
> > OK, well GNU/Linux-specific. :-) Some ppl find _GNU_SOURCE odd for
> > stuff that comes from Linux not GNU, but in this case it seems pretty
> > appropriate since GNU and Linux are the two systems doing it.
> 
> Sorry for nit-picking, it's common to both GNU and Linux.

Yes, I was just making a bad joke about "GNU/Linux", reusing it to
mean "applies to both GNU and to Linux". Sorry for being unclear.

> >> We received feedback that our headers are not useful due to the
> >> __u64/uint64_t mismatch.
> >> 
> >>   <https://sourceware.org/bugzilla/show_bug.cgi?id=25292
> >>   <https://sourceware.org/ml/libc-alpha/2019-12/msg00631.html>
> >
> > Uhg. That change seems unfortunate since it's incompatible with
> > theoretical future archs having 128-bit long long -- an idea I'm not
> > much a fan of, but don't actually want to preclude. Is there a reason
> > to actually care about compatibility with the kernel types?
> 
> Yes, printf format strings. 8-(

Why not let ppl get the warnings and fix them by casting to an
appropriate type to print. I prefer [u]intmax_t anyway to avoid the
PRIu64 etc. mess that makes your format strings unreadable and that
interferes with translation (*).

> > It's not like both struct definitions can be included in the same
> > source anyway; the tags would clash. Using the canonical uintN_t types
> > makes more sense from an API perspective, I think; kernel assumptions
> > about types should not leak into an API intended to be clean and
> > shared with non-Linux implementations.
> 
> I thought so too, which is why I used them.
> 
> But it is fairly compelling to use the kernel types if the header is
> available, so that we don't have to patch and rebuild glibc if someone
> backports new statx features into the kernel.  That's why I added the
> __has_include kludge.

I see. This is something of a tradeoff I guess; for musl users I'd
expect folks to have libc headers newer than kernel headers in most
cases since distros are slow to follow new kernels but fast to follow
new libc, and you want compile-time support for future kernel
features even if you don't have the kernel to use them yet. But on
glibc-based dists it may be the other way around.

Rich



(*) GNU gettext has "SYSDEP" format strings that solve this problem
but do so by requiring non-shareable string memory for all the
affected strings. musl gettext does not support this, but is intended
to be used with gettext-tiny's version of msgfmt that works out the
combinatorics at .mo generation time and emits them all in shareable
form. Still I think it's better to get rid of this practice and just
use %jd etc. everywhere with suitable casts.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] Re: [PATCH] add statx
  2020-01-24 14:01   ` Rich Felker
@ 2020-01-28  8:59     ` Ben Noordhuis
  2020-01-28 13:39       ` Rich Felker
  0 siblings, 1 reply; 27+ messages in thread
From: Ben Noordhuis @ 2020-01-28  8:59 UTC (permalink / raw)
  To: musl

On Fri, Jan 24, 2020 at 3:01 PM Rich Felker <dalias@libc.org> wrote:
>
> On Fri, Jan 24, 2020 at 09:38:49AM +0100, Ben Noordhuis wrote:
> >
> > Can I get some feedback on this patch, even if it's just "no because"? Thanks.
>
> Sorry aboout that; I'd just had my mind on other things and hadn't
> taken the time to make a good review yet.

Thanks for the feedback and no worries, I'm no saint in that regard either.

Before I post a v2, did I understand the following issues correctly?

1. Switch _GNU_SOURCE || _BSD_SOURCE -> just _GNU_SOURCE? FWIW,
_BSD_SOURCE currently exposes the AT_STATX_* flags in fcntl.h.

2. uint64_t -> unsigned long long guarded by #ifdef __GNUC__
__extension__? Or just leave it as-is?

4. An ENOSYS fallback to fstatat()? glibc's fallback returns EINVAL
for AT_* flags it doesn't understand and ignores all STATX_* flags: it
sets stx_mask to STATX_BASIC_STATS, fills in stx_uid/stx_gid/etc. and
sets stx_btime to zero. Does that sound reasonable?

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-24 16:29         ` Rich Felker
@ 2020-01-28 10:41           ` Florian Weimer
  2020-01-28 13:18             ` Rich Felker
  0 siblings, 1 reply; 27+ messages in thread
From: Florian Weimer @ 2020-01-28 10:41 UTC (permalink / raw)
  To: Rich Felker; +Cc: musl

* Rich Felker:

>> >> We received feedback that our headers are not useful due to the
>> >> __u64/uint64_t mismatch.
>> >> 
>> >>   <https://sourceware.org/bugzilla/show_bug.cgi?id=25292
>> >>   <https://sourceware.org/ml/libc-alpha/2019-12/msg00631.html>
>> >
>> > Uhg. That change seems unfortunate since it's incompatible with
>> > theoretical future archs having 128-bit long long -- an idea I'm not
>> > much a fan of, but don't actually want to preclude. Is there a reason
>> > to actually care about compatibility with the kernel types?
>> 
>> Yes, printf format strings. 8-(
>
> Why not let ppl get the warnings and fix them by casting to an
> appropriate type to print. I prefer [u]intmax_t anyway to avoid the
> PRIu64 etc. mess that makes your format strings unreadable and that
> interferes with translation (*).

I'm concerned that such casts hide or even introduce bugs, like casting
tv_sec to int.

Here's an example from the MySQL sources:

  int my_timeval_to_str(const struct timeval *tm, char *to, uint dec)
  {
    int len= sprintf(to, "%d", (int) tm->tv_sec);
    if (dec)
      len+= my_useconds_to_str(to + len, tm->tv_usec, dec);
    return len;
  }

That's why the kernel always uses unsigned long long for __u64, which
seems a reasonable trade-off to me.  It will make porting to 128-bit
architectures difficult.  But I think we should focus on the
architectures we have today.

>> > It's not like both struct definitions can be included in the same
>> > source anyway; the tags would clash. Using the canonical uintN_t types
>> > makes more sense from an API perspective, I think; kernel assumptions
>> > about types should not leak into an API intended to be clean and
>> > shared with non-Linux implementations.
>> 
>> I thought so too, which is why I used them.
>> 
>> But it is fairly compelling to use the kernel types if the header is
>> available, so that we don't have to patch and rebuild glibc if someone
>> backports new statx features into the kernel.  That's why I added the
>> __has_include kludge.
>
> I see. This is something of a tradeoff I guess; for musl users I'd
> expect folks to have libc headers newer than kernel headers in most
> cases since distros are slow to follow new kernels but fast to follow
> new libc, and you want compile-time support for future kernel
> features even if you don't have the kernel to use them yet. But on
> glibc-based dists it may be the other way around.

I think it's actually the same for self-built musl on most glibc-based
distributions because for that, developers will usually pick the latest
musl release and use the distribution's kernel headers.

But for glibc itself on glibc distributions, it's likely to have newer
kernel headers.  Fedora rebase kernels (including the UAPI headers) in a
release, but not glibc.  Debian has backport kernel packages for stable
releases (but no glibc backport).  Some enterprise distributions
aggressively backport features (including new userspace APIs) and even
rebase entire kernel subsystems from time to time.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-28 10:41           ` Florian Weimer
@ 2020-01-28 13:18             ` Rich Felker
  2020-02-17  9:10               ` Florian Weimer
  0 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2020-01-28 13:18 UTC (permalink / raw)
  To: Florian Weimer; +Cc: musl

On Tue, Jan 28, 2020 at 11:41:33AM +0100, Florian Weimer wrote:
> * Rich Felker:
> 
> >> >> We received feedback that our headers are not useful due to the
> >> >> __u64/uint64_t mismatch.
> >> >> 
> >> >>   <https://sourceware.org/bugzilla/show_bug.cgi?id=25292
> >> >>   <https://sourceware.org/ml/libc-alpha/2019-12/msg00631.html>
> >> >
> >> > Uhg. That change seems unfortunate since it's incompatible with
> >> > theoretical future archs having 128-bit long long -- an idea I'm not
> >> > much a fan of, but don't actually want to preclude. Is there a reason
> >> > to actually care about compatibility with the kernel types?
> >> 
> >> Yes, printf format strings. 8-(
> >
> > Why not let ppl get the warnings and fix them by casting to an
> > appropriate type to print. I prefer [u]intmax_t anyway to avoid the
> > PRIu64 etc. mess that makes your format strings unreadable and that
> > interferes with translation (*).
> 
> I'm concerned that such casts hide or even introduce bugs, like casting
> tv_sec to int.

As you've found, people will do incorrect casts regardless, in places
where it makes a bigger difference than here, where using fixed basic
types isn't an option. I don't think the solution is throwing away
proper semantic use of types.

> Here's an example from the MySQL sources:
> 
>   int my_timeval_to_str(const struct timeval *tm, char *to, uint dec)
>   {
>     int len= sprintf(to, "%d", (int) tm->tv_sec);
>     if (dec)
>       len+= my_useconds_to_str(to + len, tm->tv_usec, dec);
>     return len;
>   }

In the particular case of time, we should probably teach GCC to issue
warnings (-Wy2038?) for casts from an expression whose type was
declared via a typedef named time_t (I know GCC tracks knowledge of
the typedef name used, since it shows it in other warnings) to a type
smaller than 64-bit.

> That's why the kernel always uses unsigned long long for __u64, which
> seems a reasonable trade-off to me.  It will make porting to 128-bit
> architectures difficult.  But I think we should focus on the
> architectures we have today.

I disagree strongly with the last sentence. Designing an *API* in a
way that's not compatible with anything but long long == 64-bit is bad
API design. Arguably you could get into having something like
k_[u]intNN_t or similar, and use these, but I feel like that's just
gratuitous ugliness. The userspace type for 64-bit fixed-size fields
is [u]int64_t and we should be promoting its consistent usage, not
fragmenting things around kernel uapi mistakes. (Perhaps kernel uapi
headers should be fixed so that, when __KERNEL__ is not defined, they
include <stdint.h> and define __u64 etc. in terms of the stdint
types?)

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] Re: [PATCH] add statx
  2020-01-28  8:59     ` Ben Noordhuis
@ 2020-01-28 13:39       ` Rich Felker
  0 siblings, 0 replies; 27+ messages in thread
From: Rich Felker @ 2020-01-28 13:39 UTC (permalink / raw)
  To: musl

On Tue, Jan 28, 2020 at 09:59:56AM +0100, Ben Noordhuis wrote:
> On Fri, Jan 24, 2020 at 3:01 PM Rich Felker <dalias@libc.org> wrote:
> >
> > On Fri, Jan 24, 2020 at 09:38:49AM +0100, Ben Noordhuis wrote:
> > >
> > > Can I get some feedback on this patch, even if it's just "no because"? Thanks.
> >
> > Sorry aboout that; I'd just had my mind on other things and hadn't
> > taken the time to make a good review yet.
> 
> Thanks for the feedback and no worries, I'm no saint in that regard either.
> 
> Before I post a v2, did I understand the following issues correctly?
> 
> 1. Switch _GNU_SOURCE || _BSD_SOURCE -> just _GNU_SOURCE?

Yes. 

> FWIW, _BSD_SOURCE currently exposes the AT_STATX_* flags in fcntl.h.

Being that they're "namespaced" under AT_*, I don't think this is a
big deal. I was generally of the opinion that AT_* flags make sense to
always expose since they might be used with standard interfaces as
extensions, rather than with nonstandard interfaces. Even though
AT_STATX_* seem statx-exclusive, maybe they make sense as extension
flags to fstatat too?

In any case I think we can leave any consideration of a change here
for later; it's separate from adding statx().

> 2. uint64_t -> unsigned long long guarded by #ifdef __GNUC__
> __extension__? Or just leave it as-is?

long long does not use __extension__ guard in musl, but I think we
should stick with the semantically correct types, [u]intNN_t.

> 4. An ENOSYS fallback to fstatat()? glibc's fallback returns EINVAL
> for AT_* flags it doesn't understand and ignores all STATX_* flags: it
> sets stx_mask to STATX_BASIC_STATS, fills in stx_uid/stx_gid/etc. and
> sets stx_btime to zero. Does that sound reasonable?

Sounds right.

Note that filling in stx_[r]dev_{major,minor} requires the
sys/sysmacros.h major()/minor()/ macros since statx oddly separated
them out of dev_t.

I don't think setting btime to 0 is strictly necessary, but since it's
in the range of the struct that's unconditionally present, it's okay
to do so, and perhaps guards against info leaks from old stack
contents.

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-01-28 13:18             ` Rich Felker
@ 2020-02-17  9:10               ` Florian Weimer
  2020-02-17 15:29                 ` Rich Felker
  0 siblings, 1 reply; 27+ messages in thread
From: Florian Weimer @ 2020-02-17  9:10 UTC (permalink / raw)
  To: Rich Felker; +Cc: musl

* Rich Felker:

>> That's why the kernel always uses unsigned long long for __u64, which
>> seems a reasonable trade-off to me.  It will make porting to 128-bit
>> architectures difficult.  But I think we should focus on the
>> architectures we have today.
>
> I disagree strongly with the last sentence. Designing an *API* in a
> way that's not compatible with anything but long long == 64-bit is bad
> API design.

We don't know what LL128 architectures will look like.  For all we know,
they might have more expressive type descriptors for variadic functions,
so the whole issue of matching integer types with precise format
specifiers becomes moot.

> Arguably you could get into having something like k_[u]intNN_t or
> similar, and use these, but I feel like that's just gratuitous
> ugliness. The userspace type for 64-bit fixed-size fields is
> [u]int64_t and we should be promoting its consistent usage, not
> fragmenting things around kernel uapi mistakes.

I'm not convinced it's a mistake.

> (Perhaps kernel uapi headers should be fixed so that, when __KERNEL__
> is not defined, they include <stdint.h> and define __u64 etc. in terms
> of the stdint types?)

This breaks the existing format specifiers.  The kernel choices have
been deliberately made in such a way that you can use %llu for printing
__u64 values.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH] add statx
  2020-02-17  9:10               ` Florian Weimer
@ 2020-02-17 15:29                 ` Rich Felker
  0 siblings, 0 replies; 27+ messages in thread
From: Rich Felker @ 2020-02-17 15:29 UTC (permalink / raw)
  To: musl

On Mon, Feb 17, 2020 at 10:10:40AM +0100, Florian Weimer wrote:
> * Rich Felker:
> 
> >> That's why the kernel always uses unsigned long long for __u64, which
> >> seems a reasonable trade-off to me.  It will make porting to 128-bit
> >> architectures difficult.  But I think we should focus on the
> >> architectures we have today.
> >
> > I disagree strongly with the last sentence. Designing an *API* in a
> > way that's not compatible with anything but long long == 64-bit is bad
> > API design.
> 
> We don't know what LL128 architectures will look like.  For all we know,
> they might have more expressive type descriptors for variadic functions,
> so the whole issue of matching integer types with precise format
> specifiers becomes moot.

I don't follow. Mechanically the wrong format for long long vs
int64_t *already works*; the problem at hand is that per the
language, it's undefined, and rightly produces warnings. None of that
would go away if LL128 archs used a fancy variadic call mechanism.

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 0/1] [musl] [PATCH] add statx
  2020-01-19 12:12 [musl] [PATCH] add statx Ben Noordhuis
  2020-01-24  8:38 ` [musl] " Ben Noordhuis
  2020-01-24 14:00 ` [musl] " Rich Felker
@ 2022-08-27 14:57 ` Duncan Bellamy
  2022-08-27 14:57   ` [musl] [PATCH 1/1] resubmitting old statx patch with changes Duncan Bellamy
  2022-08-27 23:11 ` [musl] [PATCH 0/2] V2 Duncan Bellamy
  2022-08-31 19:07 ` [musl] [PATCH 0/2] V3 Duncan Bellamy
  4 siblings, 1 reply; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-27 14:57 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

Previous patch was not finished: https://inbox.vuxu.org/musl/20200119121247.37310-1-info@bnoordhuis.nl/

Duncan Bellamy (1):
  resubmitting old statx patch with changes

 include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 src/stat/fstatat.c | 27 +------------------------
 src/stat/statx.c   | 35 +++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 26 deletions(-)
 create mode 100644 src/stat/statx.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 1/1] resubmitting old statx patch with changes
  2022-08-27 14:57 ` [musl] [PATCH 0/1] " Duncan Bellamy
@ 2022-08-27 14:57   ` Duncan Bellamy
  2022-08-27 18:10     ` Rich Felker
  0 siblings, 1 reply; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-27 14:57 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

---
 include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 src/stat/fstatat.c | 27 +------------------------
 src/stat/statx.c   | 35 +++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 26 deletions(-)
 create mode 100644 src/stat/statx.c

diff --git a/include/sys/stat.h b/include/sys/stat.h
index 10d446c4..81424462 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -5,6 +5,7 @@ extern "C" {
 #endif
 
 #include <features.h>
+#include <stdint.h>
 
 #define __NEED_dev_t
 #define __NEED_ino_t
@@ -70,6 +71,54 @@ extern "C" {
 #define UTIME_NOW  0x3fffffff
 #define UTIME_OMIT 0x3ffffffe
 
+#if defined(_GNU_SOURCE)
+#define STATX_TYPE 1U
+#define STATX_MODE 2U
+#define STATX_NLINK 4U
+#define STATX_UID 8U
+#define STATX_GID 0x10U
+#define STATX_ATIME 0x20U
+#define STATX_MTIME 0x40U
+#define STATX_CTIME 0x80U
+#define STATX_INO 0x100U
+#define STATX_SIZE 0x200U
+#define STATX_BLOCKS 0x400U
+#define STATX_BASIC_STATS 0x7ffU
+#define STATX_BTIME 0x800U
+#define STATX_ALL 0xfffU
+
+struct statx_timestamp {
+	int64_t tv_sec;
+	uint32_t tv_nsec;
+	int32_t __pad;
+};
+
+struct statx {
+	uint32_t stx_mask;
+	uint32_t stx_blksize;
+	uint64_t stx_attributes;
+	uint32_t stx_nlink;
+	uint32_t stx_uid;
+	uint32_t stx_gid;
+	uint16_t stx_mode;
+	uint16_t __pad0[1];
+	uint64_t stx_ino;
+	uint64_t stx_size;
+	uint64_t stx_blocks;
+	uint64_t stx_attributes_mask;
+	struct statx_timestamp stx_atime;
+	struct statx_timestamp stx_btime;
+	struct statx_timestamp stx_ctime;
+	struct statx_timestamp stx_mtime;
+	uint32_t stx_rdev_major;
+	uint32_t stx_rdev_minor;
+	uint32_t stx_dev_major;
+	uint32_t stx_dev_minor;
+	uint64_t __pad1[14];
+};
+
+int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
+#endif
 int stat(const char *__restrict, struct stat *__restrict);
 int fstat(int, struct stat *);
 int lstat(const char *__restrict, struct stat *__restrict);
diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
index 74c51cf5..5b2248a9 100644
--- a/src/stat/fstatat.c
+++ b/src/stat/fstatat.c
@@ -7,36 +7,11 @@
 #include <sys/sysmacros.h>
 #include "syscall.h"
 
-struct statx {
-	uint32_t stx_mask;
-	uint32_t stx_blksize;
-	uint64_t stx_attributes;
-	uint32_t stx_nlink;
-	uint32_t stx_uid;
-	uint32_t stx_gid;
-	uint16_t stx_mode;
-	uint16_t pad1;
-	uint64_t stx_ino;
-	uint64_t stx_size;
-	uint64_t stx_blocks;
-	uint64_t stx_attributes_mask;
-	struct {
-		int64_t tv_sec;
-		uint32_t tv_nsec;
-		int32_t pad;
-	} stx_atime, stx_btime, stx_ctime, stx_mtime;
-	uint32_t stx_rdev_major;
-	uint32_t stx_rdev_minor;
-	uint32_t stx_dev_major;
-	uint32_t stx_dev_minor;
-	uint64_t spare[14];
-};
-
 static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
 {
 	struct statx stx;
 
-	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
+	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
 	if (ret) return ret;
 
 	*st = (struct stat){
diff --git a/src/stat/statx.c b/src/stat/statx.c
new file mode 100644
index 00000000..ff49841b
--- /dev/null
+++ b/src/stat/statx.c
@@ -0,0 +1,35 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <syscall.h>
+#include <sys/sysmacros.h>
+#include <errno.h>
+
+int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
+{
+	int ret = syscall(SYS_statx, dirfd, path, flags, mask, stx);
+	if (ret == ENOSYS) {
+		struct stat st;
+		fstatat(dir_fd, path, &st, flags);
+		stx.stx_dev_major = major(st.st_dev);
+		stx.stx_dev_minor = minor(st.st_dev);
+		stx.stx_ino = st.st_ino;
+		stx.stx_mode = st.st_mode;
+		stx.stx_nlink = st.st_nlink;
+		stx.stx_uid = st.st_uid;
+		stx.stx_gid = st.st_gid;
+		stx.stx_size = st.st_size;
+		stx.stx_blksize = st.st_blksize;
+		stx.stx_blocks = st.st_blocks;
+		stx.stx_atime.tv_sec = st.st_atim.tv_sec;
+		stx.stx_atime.tv_nsec = st.st_atim.tv_nsec;
+		stx.stx_mtime.tv_sec = st.st_mtim.tv_sec;
+		stx.stx_mtime.tv_nsec = st.st_mtim.tv_nsec;
+		stx.stx_ctime.tv_sec = st.st_ctim.tv_sec;
+		stx.stx_ctime.tv_nsec = st.st_ctim.tv_nsec;
+		stx.stx_btime = 0;
+		stx.stx_mask = STATX_BASIC_STATS;
+		ret = EINVAL;
+	}
+
+	return ret;
+}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH 1/1] resubmitting old statx patch with changes
  2022-08-27 14:57   ` [musl] [PATCH 1/1] resubmitting old statx patch with changes Duncan Bellamy
@ 2022-08-27 18:10     ` Rich Felker
  2022-08-27 23:11       ` Dunk
  0 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2022-08-27 18:10 UTC (permalink / raw)
  To: Duncan Bellamy; +Cc: info, musl

On Sat, Aug 27, 2022 at 03:57:52PM +0100, Duncan Bellamy wrote:
> ---
>  include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/stat/fstatat.c | 27 +------------------------
>  src/stat/statx.c   | 35 +++++++++++++++++++++++++++++++++
>  3 files changed, 85 insertions(+), 26 deletions(-)
>  create mode 100644 src/stat/statx.c
> 
> diff --git a/include/sys/stat.h b/include/sys/stat.h
> index 10d446c4..81424462 100644
> --- a/include/sys/stat.h
> +++ b/include/sys/stat.h
> @@ -5,6 +5,7 @@ extern "C" {
>  #endif
>  
>  #include <features.h>
> +#include <stdint.h>

This can't be done unconditionally. Either the #include directive
needs to be within the preprocessor conditional where statx is, or the
individual __NEED_uint32_t etc need to be defined conditional on the
same condition before bits/alltypes.h is included. The latter is
probably better here.

>  #define __NEED_dev_t
>  #define __NEED_ino_t
> @@ -70,6 +71,54 @@ extern "C" {
>  #define UTIME_NOW  0x3fffffff
>  #define UTIME_OMIT 0x3ffffffe
>  
> +#if defined(_GNU_SOURCE)
> +#define STATX_TYPE 1U
> +#define STATX_MODE 2U
> +#define STATX_NLINK 4U
> +#define STATX_UID 8U
> +#define STATX_GID 0x10U
> +#define STATX_ATIME 0x20U
> +#define STATX_MTIME 0x40U
> +#define STATX_CTIME 0x80U
> +#define STATX_INO 0x100U
> +#define STATX_SIZE 0x200U
> +#define STATX_BLOCKS 0x400U
> +#define STATX_BASIC_STATS 0x7ffU
> +#define STATX_BTIME 0x800U
> +#define STATX_ALL 0xfffU
> +
> +struct statx_timestamp {
> +	int64_t tv_sec;
> +	uint32_t tv_nsec;
> +	int32_t __pad;
> +};

Minor nit but this could probably just be tv_nsec, __pad (both same
type). This also eliminates the gratuitous need to expose the signed
32-bit type which is not used elsewhere.

I was looking at whether *all* of the types here could be replaced
with equivalent ones that don't require exposing extra types, but the
ones documented as uint64_t probably can't. All the uint32_t in
principle could just be unsigned, and tv_sec time_t, but...

> +
> +struct statx {
> +	uint32_t stx_mask;
> +	uint32_t stx_blksize;
> +	uint64_t stx_attributes;
> +	uint32_t stx_nlink;
> +	uint32_t stx_uid;
> +	uint32_t stx_gid;
> +	uint16_t stx_mode;
> +	uint16_t __pad0[1];
> +	uint64_t stx_ino;
> +	uint64_t stx_size;
> +	uint64_t stx_blocks;
> +	uint64_t stx_attributes_mask;
> +	struct statx_timestamp stx_atime;
> +	struct statx_timestamp stx_btime;
> +	struct statx_timestamp stx_ctime;
> +	struct statx_timestamp stx_mtime;
> +	uint32_t stx_rdev_major;
> +	uint32_t stx_rdev_minor;
> +	uint32_t stx_dev_major;
> +	uint32_t stx_dev_minor;
> +	uint64_t __pad1[14];
> +};

stx_ino etc. should not be assuming ino_t etc. are defined the same as
uint64_t rather than something like unsigned long long. So we probably
just go with writing the types as documented...

> +
> +int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
> +#endif
>  int stat(const char *__restrict, struct stat *__restrict);
>  int fstat(int, struct stat *);
>  int lstat(const char *__restrict, struct stat *__restrict);
> diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
> index 74c51cf5..5b2248a9 100644
> --- a/src/stat/fstatat.c
> +++ b/src/stat/fstatat.c
> @@ -7,36 +7,11 @@
>  #include <sys/sysmacros.h>
>  #include "syscall.h"
>  
> -struct statx {
> -	uint32_t stx_mask;
> -	uint32_t stx_blksize;
> -	uint64_t stx_attributes;
> -	uint32_t stx_nlink;
> -	uint32_t stx_uid;
> -	uint32_t stx_gid;
> -	uint16_t stx_mode;
> -	uint16_t pad1;
> -	uint64_t stx_ino;
> -	uint64_t stx_size;
> -	uint64_t stx_blocks;
> -	uint64_t stx_attributes_mask;
> -	struct {
> -		int64_t tv_sec;
> -		uint32_t tv_nsec;
> -		int32_t pad;
> -	} stx_atime, stx_btime, stx_ctime, stx_mtime;
> -	uint32_t stx_rdev_major;
> -	uint32_t stx_rdev_minor;
> -	uint32_t stx_dev_major;
> -	uint32_t stx_dev_minor;
> -	uint64_t spare[14];
> -};
> -
>  static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
>  {
>  	struct statx stx;
>  
> -	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
> +	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
>  	if (ret) return ret;
>  
>  	*st = (struct stat){

This can be a separate change from adding statx, but it's easy to
separate when merging.

> diff --git a/src/stat/statx.c b/src/stat/statx.c
> new file mode 100644
> index 00000000..ff49841b
> --- /dev/null
> +++ b/src/stat/statx.c
> @@ -0,0 +1,35 @@
> +#define _GNU_SOURCE
> +#include <sys/stat.h>
> +#include <syscall.h>
> +#include <sys/sysmacros.h>
> +#include <errno.h>
> +
> +int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
> +{
> +	int ret = syscall(SYS_statx, dirfd, path, flags, mask, stx);
> +	if (ret == ENOSYS) {
> +		struct stat st;
> +		fstatat(dir_fd, path, &st, flags);
> +		stx.stx_dev_major = major(st.st_dev);
> +		stx.stx_dev_minor = minor(st.st_dev);
> +		stx.stx_ino = st.st_ino;
> +		stx.stx_mode = st.st_mode;
> +		stx.stx_nlink = st.st_nlink;
> +		stx.stx_uid = st.st_uid;
> +		stx.stx_gid = st.st_gid;
> +		stx.stx_size = st.st_size;
> +		stx.stx_blksize = st.st_blksize;
> +		stx.stx_blocks = st.st_blocks;
> +		stx.stx_atime.tv_sec = st.st_atim.tv_sec;
> +		stx.stx_atime.tv_nsec = st.st_atim.tv_nsec;
> +		stx.stx_mtime.tv_sec = st.st_mtim.tv_sec;
> +		stx.stx_mtime.tv_nsec = st.st_mtim.tv_nsec;
> +		stx.stx_ctime.tv_sec = st.st_ctim.tv_sec;
> +		stx.stx_ctime.tv_nsec = st.st_ctim.tv_nsec;
> +		stx.stx_btime = 0;
> +		stx.stx_mask = STATX_BASIC_STATS;
> +		ret = EINVAL;
> +	}
> +
> +	return ret;
> +}
> -- 
> 2.34.1

I think this wasn't tested because it won't even compile (stx. instead
of stx->). It's also wrongly assuming syscall() returned a positive
error code rather than -1 on error and setting errno, but you should
be using the __syscall form that returns a negated error code, then
__syscall_ret at the end. I would write it as:

	int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx);
	if (ret != -ENOSYS) return __syscall_ret(ret);

then the fallback case outside a conditional. The fallback can't
assume fstatat succeeded like you're doing either. It needs to return
-1 immediately if fstatat fails.

All of this code needs to be conditional on SYS_fstatat existing, as
new archs don't have it and only have SYS_statx.

One annoying thing about this but I don't know a good fix; maybe you
have an idea: if SYS_statx fails with ENOSYS, the call to fstatat will
immediately perform SYS_statx again, only to have it fail, then
finally fall back to SYS_fstatat or other syscalls after two failures.
I'm not sure if it makes sense to expose __fstatat_kstat
libc-internally (hidden) to use here or do something else; that's
kinda getting into more complexity around this than I'd like for the
sake of optimizing old systems.

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH 1/1] resubmitting old statx patch with changes
  2022-08-27 18:10     ` Rich Felker
@ 2022-08-27 23:11       ` Dunk
  0 siblings, 0 replies; 27+ messages in thread
From: Dunk @ 2022-08-27 23:11 UTC (permalink / raw)
  To: musl; +Cc: info


> On 27 Aug 2022, at 19:10, Rich Felker <dalias@libc.org> wrote:
> 
> On Sat, Aug 27, 2022 at 03:57:52PM +0100, Duncan Bellamy wrote:
>> ---
>> include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
>> src/stat/fstatat.c | 27 +------------------------
>> src/stat/statx.c   | 35 +++++++++++++++++++++++++++++++++
>> 3 files changed, 85 insertions(+), 26 deletions(-)
>> create mode 100644 src/stat/statx.c
>> 
>> diff --git a/include/sys/stat.h b/include/sys/stat.h
>> index 10d446c4..81424462 100644
>> --- a/include/sys/stat.h
>> +++ b/include/sys/stat.h
>> @@ -5,6 +5,7 @@ extern "C" {
>> #endif
>> 
>> #include <features.h>
>> +#include <stdint.h>
> 
> This can't be done unconditionally. Either the #include directive
> needs to be within the preprocessor conditional where statx is, or the
> individual __NEED_uint32_t etc need to be defined conditional on the
> same condition before bits/alltypes.h is included. The latter is
> probably better here.

I didn’t understand the later so did the former.

>> #define __NEED_dev_t
>> #define __NEED_ino_t
>> @@ -70,6 +71,54 @@ extern "C" {
>> #define UTIME_NOW  0x3fffffff
>> #define UTIME_OMIT 0x3ffffffe
>> 
>> +#if defined(_GNU_SOURCE)
>> +#define STATX_TYPE 1U
>> +#define STATX_MODE 2U
>> +#define STATX_NLINK 4U
>> +#define STATX_UID 8U
>> +#define STATX_GID 0x10U
>> +#define STATX_ATIME 0x20U
>> +#define STATX_MTIME 0x40U
>> +#define STATX_CTIME 0x80U
>> +#define STATX_INO 0x100U
>> +#define STATX_SIZE 0x200U
>> +#define STATX_BLOCKS 0x400U
>> +#define STATX_BASIC_STATS 0x7ffU
>> +#define STATX_BTIME 0x800U
>> +#define STATX_ALL 0xfffU
>> +
>> +struct statx_timestamp {
>> +    int64_t tv_sec;
>> +    uint32_t tv_nsec;
>> +    int32_t __pad;
>> +};
> 
> Minor nit but this could probably just be tv_nsec, __pad (both same
> type). This also eliminates the gratuitous need to expose the signed
> 32-bit type which is not used elsewhere.

changed

> I was looking at whether *all* of the types here could be replaced
> with equivalent ones that don't require exposing extra types, but the
> ones documented as uint64_t probably can't. All the uint32_t in
> principle could just be unsigned, and tv_sec time_t, but...
> 
>> +
>> +struct statx {
>> +    uint32_t stx_mask;
>> +    uint32_t stx_blksize;
>> +    uint64_t stx_attributes;
>> +    uint32_t stx_nlink;
>> +    uint32_t stx_uid;
>> +    uint32_t stx_gid;
>> +    uint16_t stx_mode;
>> +    uint16_t __pad0[1];
>> +    uint64_t stx_ino;
>> +    uint64_t stx_size;
>> +    uint64_t stx_blocks;
>> +    uint64_t stx_attributes_mask;
>> +    struct statx_timestamp stx_atime;
>> +    struct statx_timestamp stx_btime;
>> +    struct statx_timestamp stx_ctime;
>> +    struct statx_timestamp stx_mtime;
>> +    uint32_t stx_rdev_major;
>> +    uint32_t stx_rdev_minor;
>> +    uint32_t stx_dev_major;
>> +    uint32_t stx_dev_minor;
>> +    uint64_t __pad1[14];
>> +};
> 
> stx_ino etc. should not be assuming ino_t etc. are defined the same as
> uint64_t rather than something like unsigned long long. So we probably
> just go with writing the types as documented...
> 
>> +
>> +int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
>> +#endif
>> int stat(const char *__restrict, struct stat *__restrict);
>> int fstat(int, struct stat *);
>> int lstat(const char *__restrict, struct stat *__restrict);
>> diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
>> index 74c51cf5..5b2248a9 100644
>> --- a/src/stat/fstatat.c
>> +++ b/src/stat/fstatat.c
>> @@ -7,36 +7,11 @@
>> #include <sys/sysmacros.h>
>> #include "syscall.h"
>> 
>> -struct statx {
>> -    uint32_t stx_mask;
>> -    uint32_t stx_blksize;
>> -    uint64_t stx_attributes;
>> -    uint32_t stx_nlink;
>> -    uint32_t stx_uid;
>> -    uint32_t stx_gid;
>> -    uint16_t stx_mode;
>> -    uint16_t pad1;
>> -    uint64_t stx_ino;
>> -    uint64_t stx_size;
>> -    uint64_t stx_blocks;
>> -    uint64_t stx_attributes_mask;
>> -    struct {
>> -        int64_t tv_sec;
>> -        uint32_t tv_nsec;
>> -        int32_t pad;
>> -    } stx_atime, stx_btime, stx_ctime, stx_mtime;
>> -    uint32_t stx_rdev_major;
>> -    uint32_t stx_rdev_minor;
>> -    uint32_t stx_dev_major;
>> -    uint32_t stx_dev_minor;
>> -    uint64_t spare[14];
>> -};
>> -
>> static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
>> {
>>    struct statx stx;
>> 
>> -    int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
>> +    int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
>>    if (ret) return ret;
>> 
>>    *st = (struct stat){
> 
> This can be a separate change from adding statx, but it's easy to
> separate when merging.

moved to separate commit

>> diff --git a/src/stat/statx.c b/src/stat/statx.c
>> new file mode 100644
>> index 00000000..ff49841b
>> --- /dev/null
>> +++ b/src/stat/statx.c
>> @@ -0,0 +1,35 @@
>> +#define _GNU_SOURCE
>> +#include <sys/stat.h>
>> +#include <syscall.h>
>> +#include <sys/sysmacros.h>
>> +#include <errno.h>
>> +
>> +int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
>> +{
>> +    int ret = syscall(SYS_statx, dirfd, path, flags, mask, stx);
>> +    if (ret == ENOSYS) {
>> +        struct stat st;
>> +        fstatat(dir_fd, path, &st, flags);
>> +        stx.stx_dev_major = major(st.st_dev);
>> +        stx.stx_dev_minor = minor(st.st_dev);
>> +        stx.stx_ino = st.st_ino;
>> +        stx.stx_mode = st.st_mode;
>> +        stx.stx_nlink = st.st_nlink;
>> +        stx.stx_uid = st.st_uid;
>> +        stx.stx_gid = st.st_gid;
>> +        stx.stx_size = st.st_size;
>> +        stx.stx_blksize = st.st_blksize;
>> +        stx.stx_blocks = st.st_blocks;
>> +        stx.stx_atime.tv_sec = st.st_atim.tv_sec;
>> +        stx.stx_atime.tv_nsec = st.st_atim.tv_nsec;
>> +        stx.stx_mtime.tv_sec = st.st_mtim.tv_sec;
>> +        stx.stx_mtime.tv_nsec = st.st_mtim.tv_nsec;
>> +        stx.stx_ctime.tv_sec = st.st_ctim.tv_sec;
>> +        stx.stx_ctime.tv_nsec = st.st_ctim.tv_nsec;
>> +        stx.stx_btime = 0;
>> +        stx.stx_mask = STATX_BASIC_STATS;
>> +        ret = EINVAL;
>> +    }
>> +
>> +    return ret;
>> +}
>> -- 
>> 2.34.1
> 
> I think this wasn't tested because it won't even compile (stx. instead
> of stx->). It's also wrongly assuming syscall() returned a positive
> error code rather than -1 on error and setting errno, but you should
> be using the __syscall form that returns a negated error code, then
> __syscall_ret at the end. I would write it as:
> 
>    int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx);
>    if (ret != -ENOSYS) return __syscall_ret(ret);
> 
> then the fallback case outside a conditional. The fallback can't
> assume fstatat succeeded like you're doing either. It needs to return
> -1 immediately if fstatat fails.

Yes it wasn’t compiled, I copied the old patch and code from `fstatat_statx` for copying the data.  Compiled it locally now.

> 
> All of this code needs to be conditional on SYS_fstatat existing, as
> new archs don't have it and only have SYS_statx.

Changed to this

> One annoying thing about this but I don't know a good fix; maybe you
> have an idea: if SYS_statx fails with ENOSYS, the call to fstatat will
> immediately perform SYS_statx again, only to have it fail, then
> finally fall back to SYS_fstatat or other syscalls after two failures.
> I'm not sure if it makes sense to expose __fstatat_kstat
> libc-internally (hidden) to use here or do something else; that's
> kinda getting into more complexity around this than I'd like for the
> sake of optimizing old systems.

I don’t really understand the fallback mechanism, or why statx would fail and fstatat work on some systems.  Maybe use defines at compile time so either one is used or the other? 

> Rich

Duncan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 0/2] V2
  2020-01-19 12:12 [musl] [PATCH] add statx Ben Noordhuis
                   ` (2 preceding siblings ...)
  2022-08-27 14:57 ` [musl] [PATCH 0/1] " Duncan Bellamy
@ 2022-08-27 23:11 ` Duncan Bellamy
  2022-08-27 23:11   ` [musl] [PATCH 1/2] V2 resubmitting old statx patch with changes Duncan Bellamy
  2022-08-27 23:11   ` [musl] [PATCH 2/2] V2 src/stat/fstatat.c use new statx define Duncan Bellamy
  2022-08-31 19:07 ` [musl] [PATCH 0/2] V3 Duncan Bellamy
  4 siblings, 2 replies; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-27 23:11 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

Version 2

Duncan Bellamy (2):
  resubmitting old statx patch with changes
  src/stat/fstatat.c use new statx define

 include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 src/stat/fstatat.c | 30 +++-------------------------
 src/stat/statx.c   | 39 ++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 27 deletions(-)
 create mode 100644 src/stat/statx.c

-- 
2.37.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 1/2] V2 resubmitting old statx patch with changes
  2022-08-27 23:11 ` [musl] [PATCH 0/2] V2 Duncan Bellamy
@ 2022-08-27 23:11   ` Duncan Bellamy
  2022-08-29 13:50     ` [musl] " Dunk
  2022-08-27 23:11   ` [musl] [PATCH 2/2] V2 src/stat/fstatat.c use new statx define Duncan Bellamy
  1 sibling, 1 reply; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-27 23:11 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

---
 include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 src/stat/statx.c   | 39 ++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)
 create mode 100644 src/stat/statx.c

diff --git a/include/sys/stat.h b/include/sys/stat.h
index 10d446c4..21668a51 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -70,6 +70,55 @@ extern "C" {
 #define UTIME_NOW  0x3fffffff
 #define UTIME_OMIT 0x3ffffffe
 
+#if defined(_GNU_SOURCE)
+#include <stdint.h>
+
+#define STATX_TYPE 1U
+#define STATX_MODE 2U
+#define STATX_NLINK 4U
+#define STATX_UID 8U
+#define STATX_GID 0x10U
+#define STATX_ATIME 0x20U
+#define STATX_MTIME 0x40U
+#define STATX_CTIME 0x80U
+#define STATX_INO 0x100U
+#define STATX_SIZE 0x200U
+#define STATX_BLOCKS 0x400U
+#define STATX_BASIC_STATS 0x7ffU
+#define STATX_BTIME 0x800U
+#define STATX_ALL 0xfffU
+
+struct statx_timestamp {
+	int64_t tv_sec;
+	uint32_t tv_nsec, __pad;
+};
+
+struct statx {
+	uint32_t stx_mask;
+	uint32_t stx_blksize;
+	uint64_t stx_attributes;
+	uint32_t stx_nlink;
+	uint32_t stx_uid;
+	uint32_t stx_gid;
+	uint16_t stx_mode;
+	uint16_t __pad0[1];
+	uint64_t stx_ino;
+	uint64_t stx_size;
+	uint64_t stx_blocks;
+	uint64_t stx_attributes_mask;
+	struct statx_timestamp stx_atime;
+	struct statx_timestamp stx_btime;
+	struct statx_timestamp stx_ctime;
+	struct statx_timestamp stx_mtime;
+	uint32_t stx_rdev_major;
+	uint32_t stx_rdev_minor;
+	uint32_t stx_dev_major;
+	uint32_t stx_dev_minor;
+	uint64_t __pad1[14];
+};
+
+int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
+#endif
 int stat(const char *__restrict, struct stat *__restrict);
 int fstat(int, struct stat *);
 int lstat(const char *__restrict, struct stat *__restrict);
diff --git a/src/stat/statx.c b/src/stat/statx.c
new file mode 100644
index 00000000..6788476a
--- /dev/null
+++ b/src/stat/statx.c
@@ -0,0 +1,39 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <syscall.h>
+#include <sys/sysmacros.h>
+#include <errno.h>
+
+int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
+{
+	int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx);
+	if (ret != -ENOSYS) return __syscall_ret(ret);
+
+	#if defined(SYS_fstatat)
+	struct stat st;
+	ret = fstatat(dirfd, path, &st, flags);
+	if (ret == -ENOSYS) return -1;
+
+	stx->stx_dev_major = major(st.st_dev);
+	stx->stx_dev_minor = minor(st.st_dev);
+	stx->stx_ino = st.st_ino;
+	stx->stx_mode = st.st_mode;
+	stx->stx_nlink = st.st_nlink;
+	stx->stx_uid = st.st_uid;
+	stx->stx_gid = st.st_gid;
+	stx->stx_size = st.st_size;
+	stx->stx_blksize = st.st_blksize;
+	stx->stx_blocks = st.st_blocks;
+	stx->stx_atime.tv_sec = st.st_atim.tv_sec;
+	stx->stx_atime.tv_nsec = st.st_atim.tv_nsec;
+	stx->stx_mtime.tv_sec = st.st_mtim.tv_sec;
+	stx->stx_mtime.tv_nsec = st.st_mtim.tv_nsec;
+	stx->stx_ctime.tv_sec = st.st_ctim.tv_sec;
+	stx->stx_ctime.tv_nsec = st.st_ctim.tv_nsec;
+	stx->stx_btime = (struct statx_timestamp){.tv_sec=0, .tv_nsec=0};
+	stx->stx_mask = STATX_BASIC_STATS;
+	ret = EINVAL;
+	#endif
+
+	return ret;
+}
-- 
2.37.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 2/2] V2 src/stat/fstatat.c use new statx define
  2022-08-27 23:11 ` [musl] [PATCH 0/2] V2 Duncan Bellamy
  2022-08-27 23:11   ` [musl] [PATCH 1/2] V2 resubmitting old statx patch with changes Duncan Bellamy
@ 2022-08-27 23:11   ` Duncan Bellamy
  1 sibling, 0 replies; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-27 23:11 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

---
 src/stat/fstatat.c | 30 +++---------------------------
 1 file changed, 3 insertions(+), 27 deletions(-)

diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
index 74c51cf5..6b44f48a 100644
--- a/src/stat/fstatat.c
+++ b/src/stat/fstatat.c
@@ -1,4 +1,5 @@
 #define _BSD_SOURCE
+#define _GNU_SOURCE
 #include <sys/stat.h>
 #include <string.h>
 #include <fcntl.h>
@@ -7,36 +8,11 @@
 #include <sys/sysmacros.h>
 #include "syscall.h"
 
-struct statx {
-	uint32_t stx_mask;
-	uint32_t stx_blksize;
-	uint64_t stx_attributes;
-	uint32_t stx_nlink;
-	uint32_t stx_uid;
-	uint32_t stx_gid;
-	uint16_t stx_mode;
-	uint16_t pad1;
-	uint64_t stx_ino;
-	uint64_t stx_size;
-	uint64_t stx_blocks;
-	uint64_t stx_attributes_mask;
-	struct {
-		int64_t tv_sec;
-		uint32_t tv_nsec;
-		int32_t pad;
-	} stx_atime, stx_btime, stx_ctime, stx_mtime;
-	uint32_t stx_rdev_major;
-	uint32_t stx_rdev_minor;
-	uint32_t stx_dev_major;
-	uint32_t stx_dev_minor;
-	uint64_t spare[14];
-};
-
 static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
 {
 	struct statx stx;
 
-	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
+	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
 	if (ret) return ret;
 
 	*st = (struct stat){
@@ -152,6 +128,6 @@ int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int f
 
 weak_alias(__fstatat, fstatat);
 
-#if !_REDIR_TIME64
+#if !_REDIR_TIME64 && !defined(_GNU_SOURCE)
 weak_alias(fstatat, fstatat64);
 #endif
-- 
2.37.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] Re: [PATCH 1/2] V2 resubmitting old statx patch with changes
  2022-08-27 23:11   ` [musl] [PATCH 1/2] V2 resubmitting old statx patch with changes Duncan Bellamy
@ 2022-08-29 13:50     ` Dunk
  0 siblings, 0 replies; 27+ messages in thread
From: Dunk @ 2022-08-29 13:50 UTC (permalink / raw)
  To: info; +Cc: musl



> On 28 Aug 2022, at 00:13, Duncan Bellamy <dunk@denkimushi.com> wrote:
> 
> ---
> include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
> src/stat/statx.c   | 39 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 88 insertions(+)
> create mode 100644 src/stat/statx.c
> 
> diff --git a/include/sys/stat.h b/include/sys/stat.h
> index 10d446c4..21668a51 100644
> --- a/include/sys/stat.h
> +++ b/include/sys/stat.h
> @@ -70,6 +70,55 @@ extern "C" {
> #define UTIME_NOW  0x3fffffff
> #define UTIME_OMIT 0x3ffffffe
> 
> +#if defined(_GNU_SOURCE)
> +#include <stdint.h>
> +
> +#define STATX_TYPE 1U
> +#define STATX_MODE 2U
> +#define STATX_NLINK 4U
> +#define STATX_UID 8U
> +#define STATX_GID 0x10U
> +#define STATX_ATIME 0x20U
> +#define STATX_MTIME 0x40U
> +#define STATX_CTIME 0x80U
> +#define STATX_INO 0x100U
> +#define STATX_SIZE 0x200U
> +#define STATX_BLOCKS 0x400U
> +#define STATX_BASIC_STATS 0x7ffU
> +#define STATX_BTIME 0x800U
> +#define STATX_ALL 0xfffU
> +
> +struct statx_timestamp {
> +    int64_t tv_sec;
> +    uint32_t tv_nsec, __pad;
> +};
> +
> +struct statx {
> +    uint32_t stx_mask;
> +    uint32_t stx_blksize;
> +    uint64_t stx_attributes;
> +    uint32_t stx_nlink;
> +    uint32_t stx_uid;
> +    uint32_t stx_gid;
> +    uint16_t stx_mode;
> +    uint16_t __pad0[1];
> +    uint64_t stx_ino;
> +    uint64_t stx_size;
> +    uint64_t stx_blocks;
> +    uint64_t stx_attributes_mask;
> +    struct statx_timestamp stx_atime;
> +    struct statx_timestamp stx_btime;
> +    struct statx_timestamp stx_ctime;
> +    struct statx_timestamp stx_mtime;
> +    uint32_t stx_rdev_major;
> +    uint32_t stx_rdev_minor;
> +    uint32_t stx_dev_major;
> +    uint32_t stx_dev_minor;
> +    uint64_t __pad1[14];
> +};
> +
> +int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
> +#endif
> int stat(const char *__restrict, struct stat *__restrict);
> int fstat(int, struct stat *);
> int lstat(const char *__restrict, struct stat *__restrict);
> diff --git a/src/stat/statx.c b/src/stat/statx.c
> new file mode 100644
> index 00000000..6788476a
> --- /dev/null
> +++ b/src/stat/statx.c
> @@ -0,0 +1,39 @@
> +#define _GNU_SOURCE
> +#include <sys/stat.h>
> +#include <syscall.h>
> +#include <sys/sysmacros.h>
> +#include <errno.h>
> +
> +int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
> +{
> +    int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx);
> +    if (ret != -ENOSYS) return __syscall_ret(ret);
> +
> +    #if defined(SYS_fstatat)
> +    struct stat st;
> +    ret = fstatat(dirfd, path, &st, flags);
> +    if (ret == -ENOSYS) return -1;
> +
> +    stx->stx_dev_major = major(st.st_dev);
> +    stx->stx_dev_minor = minor(st.st_dev);
> +    stx->stx_ino = st.st_ino;
> +    stx->stx_mode = st.st_mode;
> +    stx->stx_nlink = st.st_nlink;
> +    stx->stx_uid = st.st_uid;
> +    stx->stx_gid = st.st_gid;
> +    stx->stx_size = st.st_size;
> +    stx->stx_blksize = st.st_blksize;
> +    stx->stx_blocks = st.st_blocks;
> +    stx->stx_atime.tv_sec = st.st_atim.tv_sec;
> +    stx->stx_atime.tv_nsec = st.st_atim.tv_nsec;
> +    stx->stx_mtime.tv_sec = st.st_mtim.tv_sec;
> +    stx->stx_mtime.tv_nsec = st.st_mtim.tv_nsec;
> +    stx->stx_ctime.tv_sec = st.st_ctim.tv_sec;
> +    stx->stx_ctime.tv_nsec = st.st_ctim.tv_nsec;
> +    stx->stx_btime = (struct statx_timestamp){.tv_sec=0, .tv_nsec=0};
> +    stx->stx_mask = STATX_BASIC_STATS;
> +    ret = EINVAL;
> +    #endif
> +
> +    return ret;
> +}
> -- 
> 2.37.1

I guess this is missing `return __syscall_ret(ret)` instead of just `return ret` at the end

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 0/2] V3
  2020-01-19 12:12 [musl] [PATCH] add statx Ben Noordhuis
                   ` (3 preceding siblings ...)
  2022-08-27 23:11 ` [musl] [PATCH 0/2] V2 Duncan Bellamy
@ 2022-08-31 19:07 ` Duncan Bellamy
  2022-08-31 19:07   ` [musl] [PATCH 1/2] V3 resubmitting old statx patch with changes Duncan Bellamy
  2022-08-31 19:07   ` [musl] [PATCH 2/2] V3 src/stat/fstatat.c use new statx define Duncan Bellamy
  4 siblings, 2 replies; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-31 19:07 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

Version 3

Duncan Bellamy (2):
  resubmitting old statx patch with changes
  src/stat/fstatat.c use new statx define

 include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 src/stat/fstatat.c | 30 +++-------------------------
 src/stat/statx.c   | 40 +++++++++++++++++++++++++++++++++++++
 3 files changed, 92 insertions(+), 27 deletions(-)
 create mode 100644 src/stat/statx.c

-- 
2.32.1 (Apple Git-133)


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 1/2] V3 resubmitting old statx patch with changes
  2022-08-31 19:07 ` [musl] [PATCH 0/2] V3 Duncan Bellamy
@ 2022-08-31 19:07   ` Duncan Bellamy
  2024-02-24 16:56     ` Rich Felker
  2022-08-31 19:07   ` [musl] [PATCH 2/2] V3 src/stat/fstatat.c use new statx define Duncan Bellamy
  1 sibling, 1 reply; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-31 19:07 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

---
 include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 src/stat/statx.c   | 40 +++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 src/stat/statx.c

diff --git a/include/sys/stat.h b/include/sys/stat.h
index 10d446c4..21668a51 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -70,6 +70,55 @@ extern "C" {
 #define UTIME_NOW  0x3fffffff
 #define UTIME_OMIT 0x3ffffffe
 
+#if defined(_GNU_SOURCE)
+#include <stdint.h>
+
+#define STATX_TYPE 1U
+#define STATX_MODE 2U
+#define STATX_NLINK 4U
+#define STATX_UID 8U
+#define STATX_GID 0x10U
+#define STATX_ATIME 0x20U
+#define STATX_MTIME 0x40U
+#define STATX_CTIME 0x80U
+#define STATX_INO 0x100U
+#define STATX_SIZE 0x200U
+#define STATX_BLOCKS 0x400U
+#define STATX_BASIC_STATS 0x7ffU
+#define STATX_BTIME 0x800U
+#define STATX_ALL 0xfffU
+
+struct statx_timestamp {
+	int64_t tv_sec;
+	uint32_t tv_nsec, __pad;
+};
+
+struct statx {
+	uint32_t stx_mask;
+	uint32_t stx_blksize;
+	uint64_t stx_attributes;
+	uint32_t stx_nlink;
+	uint32_t stx_uid;
+	uint32_t stx_gid;
+	uint16_t stx_mode;
+	uint16_t __pad0[1];
+	uint64_t stx_ino;
+	uint64_t stx_size;
+	uint64_t stx_blocks;
+	uint64_t stx_attributes_mask;
+	struct statx_timestamp stx_atime;
+	struct statx_timestamp stx_btime;
+	struct statx_timestamp stx_ctime;
+	struct statx_timestamp stx_mtime;
+	uint32_t stx_rdev_major;
+	uint32_t stx_rdev_minor;
+	uint32_t stx_dev_major;
+	uint32_t stx_dev_minor;
+	uint64_t __pad1[14];
+};
+
+int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
+#endif
 int stat(const char *__restrict, struct stat *__restrict);
 int fstat(int, struct stat *);
 int lstat(const char *__restrict, struct stat *__restrict);
diff --git a/src/stat/statx.c b/src/stat/statx.c
new file mode 100644
index 00000000..4eae0d56
--- /dev/null
+++ b/src/stat/statx.c
@@ -0,0 +1,40 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <syscall.h>
+#include <sys/sysmacros.h>
+#include <errno.h>
+
+int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
+{
+	int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx);
+
+	#if defined(SYS_fstatat)
+	if (ret != -ENOSYS) return __syscall_ret(ret);
+	struct stat st;
+	ret = fstatat(dirfd, path, &st, flags);
+	if (ret == -ENOSYS) return -1;
+
+	stx->stx_dev_major = major(st.st_dev);
+	stx->stx_dev_minor = minor(st.st_dev);
+	stx->stx_ino = st.st_ino;
+	stx->stx_mode = st.st_mode;
+	stx->stx_nlink = st.st_nlink;
+	stx->stx_uid = st.st_uid;
+	stx->stx_gid = st.st_gid;
+	stx->stx_size = st.st_size;
+	stx->stx_blksize = st.st_blksize;
+	stx->stx_blocks = st.st_blocks;
+	stx->stx_atime.tv_sec = st.st_atim.tv_sec;
+	stx->stx_atime.tv_nsec = st.st_atim.tv_nsec;
+	stx->stx_mtime.tv_sec = st.st_mtim.tv_sec;
+	stx->stx_mtime.tv_nsec = st.st_mtim.tv_nsec;
+	stx->stx_ctime.tv_sec = st.st_ctim.tv_sec;
+	stx->stx_ctime.tv_nsec = st.st_ctim.tv_nsec;
+	stx->stx_btime = (struct statx_timestamp){.tv_sec=0, .tv_nsec=0};
+	stx->stx_mask = STATX_BASIC_STATS;
+	ret = EINVAL;
+	return ret;
+	#else
+	return __syscall_ret(ret);
+	#endif
+}
-- 
2.32.1 (Apple Git-133)


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [musl] [PATCH 2/2] V3 src/stat/fstatat.c use new statx define
  2022-08-31 19:07 ` [musl] [PATCH 0/2] V3 Duncan Bellamy
  2022-08-31 19:07   ` [musl] [PATCH 1/2] V3 resubmitting old statx patch with changes Duncan Bellamy
@ 2022-08-31 19:07   ` Duncan Bellamy
  2024-02-24 16:57     ` Rich Felker
  1 sibling, 1 reply; 27+ messages in thread
From: Duncan Bellamy @ 2022-08-31 19:07 UTC (permalink / raw)
  To: info; +Cc: musl, Duncan Bellamy

---
 src/stat/fstatat.c | 30 +++---------------------------
 1 file changed, 3 insertions(+), 27 deletions(-)

diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
index 74c51cf5..6b44f48a 100644
--- a/src/stat/fstatat.c
+++ b/src/stat/fstatat.c
@@ -1,4 +1,5 @@
 #define _BSD_SOURCE
+#define _GNU_SOURCE
 #include <sys/stat.h>
 #include <string.h>
 #include <fcntl.h>
@@ -7,36 +8,11 @@
 #include <sys/sysmacros.h>
 #include "syscall.h"
 
-struct statx {
-	uint32_t stx_mask;
-	uint32_t stx_blksize;
-	uint64_t stx_attributes;
-	uint32_t stx_nlink;
-	uint32_t stx_uid;
-	uint32_t stx_gid;
-	uint16_t stx_mode;
-	uint16_t pad1;
-	uint64_t stx_ino;
-	uint64_t stx_size;
-	uint64_t stx_blocks;
-	uint64_t stx_attributes_mask;
-	struct {
-		int64_t tv_sec;
-		uint32_t tv_nsec;
-		int32_t pad;
-	} stx_atime, stx_btime, stx_ctime, stx_mtime;
-	uint32_t stx_rdev_major;
-	uint32_t stx_rdev_minor;
-	uint32_t stx_dev_major;
-	uint32_t stx_dev_minor;
-	uint64_t spare[14];
-};
-
 static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
 {
 	struct statx stx;
 
-	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
+	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
 	if (ret) return ret;
 
 	*st = (struct stat){
@@ -152,6 +128,6 @@ int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int f
 
 weak_alias(__fstatat, fstatat);
 
-#if !_REDIR_TIME64
+#if !_REDIR_TIME64 && !defined(_GNU_SOURCE)
 weak_alias(fstatat, fstatat64);
 #endif
-- 
2.32.1 (Apple Git-133)


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH 1/2] V3 resubmitting old statx patch with changes
  2022-08-31 19:07   ` [musl] [PATCH 1/2] V3 resubmitting old statx patch with changes Duncan Bellamy
@ 2024-02-24 16:56     ` Rich Felker
  0 siblings, 0 replies; 27+ messages in thread
From: Rich Felker @ 2024-02-24 16:56 UTC (permalink / raw)
  To: Duncan Bellamy; +Cc: info, musl

On Wed, Aug 31, 2022 at 08:07:34PM +0100, Duncan Bellamy wrote:
> ---
>  include/sys/stat.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/stat/statx.c   | 40 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 89 insertions(+)
>  create mode 100644 src/stat/statx.c

I'm picking back up review of this because it's been requested again.
Last time I dropped off because there continued to be unresolved
issues where it looked like this hadn't been tested.

I'll make the following changes and merge if there's no objection:

> diff --git a/include/sys/stat.h b/include/sys/stat.h
> index 10d446c4..21668a51 100644
> --- a/include/sys/stat.h
> +++ b/include/sys/stat.h
> @@ -70,6 +70,55 @@ extern "C" {
>  #define UTIME_NOW  0x3fffffff
>  #define UTIME_OMIT 0x3ffffffe
>  
> +#if defined(_GNU_SOURCE)
> +#include <stdint.h>

This should be moved above include of bits/alltypes.h as:

#ifdef _GNU_SOURCE
#define #define __NEED_int64_t
#define #define __NEED_uint62_t
#define #define __NEED_uint32_t
#endif

> +#define STATX_TYPE 1U
> +#define STATX_MODE 2U
> +#define STATX_NLINK 4U
> +#define STATX_UID 8U
> +#define STATX_GID 0x10U
> +#define STATX_ATIME 0x20U
> +#define STATX_MTIME 0x40U
> +#define STATX_CTIME 0x80U
> +#define STATX_INO 0x100U
> +#define STATX_SIZE 0x200U
> +#define STATX_BLOCKS 0x400U
> +#define STATX_BASIC_STATS 0x7ffU
> +#define STATX_BTIME 0x800U
> +#define STATX_ALL 0xfffU
> +
> +struct statx_timestamp {
> +	int64_t tv_sec;
> +	uint32_t tv_nsec, __pad;
> +};
> +
> +struct statx {
> +	uint32_t stx_mask;
> +	uint32_t stx_blksize;
> +	uint64_t stx_attributes;
> +	uint32_t stx_nlink;
> +	uint32_t stx_uid;
> +	uint32_t stx_gid;
> +	uint16_t stx_mode;
> +	uint16_t __pad0[1];
> +	uint64_t stx_ino;
> +	uint64_t stx_size;
> +	uint64_t stx_blocks;
> +	uint64_t stx_attributes_mask;
> +	struct statx_timestamp stx_atime;
> +	struct statx_timestamp stx_btime;
> +	struct statx_timestamp stx_ctime;
> +	struct statx_timestamp stx_mtime;
> +	uint32_t stx_rdev_major;
> +	uint32_t stx_rdev_minor;
> +	uint32_t stx_dev_major;
> +	uint32_t stx_dev_minor;
> +	uint64_t __pad1[14];
> +};
> +
> +int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
> +#endif

This should probably be reordered to go with the other extensions, but
it's not really a big deal, that's just usually how the headers are
organized.

>  int stat(const char *__restrict, struct stat *__restrict);
>  int fstat(int, struct stat *);
>  int lstat(const char *__restrict, struct stat *__restrict);
> diff --git a/src/stat/statx.c b/src/stat/statx.c
> new file mode 100644
> index 00000000..4eae0d56
> --- /dev/null
> +++ b/src/stat/statx.c
> @@ -0,0 +1,40 @@
> +#define _GNU_SOURCE
> +#include <sys/stat.h>
> +#include <syscall.h>
> +#include <sys/sysmacros.h>
> +#include <errno.h>
> +
> +int statx(int dirfd, const char *restrict path, int flags, unsigned mask, struct statx *restrict stx)
> +{
> +	int ret = __syscall(SYS_statx, dirfd, path, flags, mask, stx);
> +
> +	#if defined(SYS_fstatat)
> +	if (ret != -ENOSYS) return __syscall_ret(ret);
> +	struct stat st;
> +	ret = fstatat(dirfd, path, &st, flags);
> +	if (ret == -ENOSYS) return -1;

fstatat returns -1 on error and sets errno. The condition also makes
no sense. The intent here is to return without writing to *stx when
fstatat failed. This is not specific to ENOSYS (which can't happen, at
least not without bogus seccomp meddling) but could happen for lots of
reasons. I think it should just be:

	if (ret) return ret;

> +	stx->stx_dev_major = major(st.st_dev);
> +	stx->stx_dev_minor = minor(st.st_dev);
> +	stx->stx_ino = st.st_ino;
> +	stx->stx_mode = st.st_mode;
> +	stx->stx_nlink = st.st_nlink;
> +	stx->stx_uid = st.st_uid;
> +	stx->stx_gid = st.st_gid;
> +	stx->stx_size = st.st_size;
> +	stx->stx_blksize = st.st_blksize;
> +	stx->stx_blocks = st.st_blocks;
> +	stx->stx_atime.tv_sec = st.st_atim.tv_sec;
> +	stx->stx_atime.tv_nsec = st.st_atim.tv_nsec;
> +	stx->stx_mtime.tv_sec = st.st_mtim.tv_sec;
> +	stx->stx_mtime.tv_nsec = st.st_mtim.tv_nsec;
> +	stx->stx_ctime.tv_sec = st.st_ctim.tv_sec;
> +	stx->stx_ctime.tv_nsec = st.st_ctim.tv_nsec;
> +	stx->stx_btime = (struct statx_timestamp){.tv_sec=0, .tv_nsec=0};
> +	stx->stx_mask = STATX_BASIC_STATS;

This is probably all fine. Rather than explicitly filling btime with
zeros, it might make sense to memset the whole struct zero first so
there's no stack data leak in unsupported extension fields.

> +	ret = EINVAL;
> +	return ret;

This is definitely wrong. statx returns 0 on success or -1 on failure,
never a positive value like EINVAL. I'm not even sure what the intent
was here..?

> +	#else
> +	return __syscall_ret(ret);
> +	#endif
> +}

This looks ok, but it would probably make sense to reverse the #ifdef
to #ifndef and flip the order in the file, so the return code using
negated error number like this is up with the __syscall it goes with
rather than separated. As written it's hard to see that the right
thing is being done in the path that uses errno vs the one using
negated error codes. (Admittedly, this being mishandled and needing to
review it in more detail is probably what made me think of this.)

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [musl] [PATCH 2/2] V3 src/stat/fstatat.c use new statx define
  2022-08-31 19:07   ` [musl] [PATCH 2/2] V3 src/stat/fstatat.c use new statx define Duncan Bellamy
@ 2024-02-24 16:57     ` Rich Felker
  0 siblings, 0 replies; 27+ messages in thread
From: Rich Felker @ 2024-02-24 16:57 UTC (permalink / raw)
  To: Duncan Bellamy; +Cc: info, musl

On Wed, Aug 31, 2022 at 08:07:35PM +0100, Duncan Bellamy wrote:
> ---
>  src/stat/fstatat.c | 30 +++---------------------------
>  1 file changed, 3 insertions(+), 27 deletions(-)
> 
> diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
> index 74c51cf5..6b44f48a 100644
> --- a/src/stat/fstatat.c
> +++ b/src/stat/fstatat.c
> @@ -1,4 +1,5 @@
>  #define _BSD_SOURCE
> +#define _GNU_SOURCE
>  #include <sys/stat.h>
>  #include <string.h>
>  #include <fcntl.h>
> @@ -7,36 +8,11 @@
>  #include <sys/sysmacros.h>
>  #include "syscall.h"
>  
> -struct statx {
> -	uint32_t stx_mask;
> -	uint32_t stx_blksize;
> -	uint64_t stx_attributes;
> -	uint32_t stx_nlink;
> -	uint32_t stx_uid;
> -	uint32_t stx_gid;
> -	uint16_t stx_mode;
> -	uint16_t pad1;
> -	uint64_t stx_ino;
> -	uint64_t stx_size;
> -	uint64_t stx_blocks;
> -	uint64_t stx_attributes_mask;
> -	struct {
> -		int64_t tv_sec;
> -		uint32_t tv_nsec;
> -		int32_t pad;
> -	} stx_atime, stx_btime, stx_ctime, stx_mtime;
> -	uint32_t stx_rdev_major;
> -	uint32_t stx_rdev_minor;
> -	uint32_t stx_dev_major;
> -	uint32_t stx_dev_minor;
> -	uint64_t spare[14];
> -};
> -
>  static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
>  {
>  	struct statx stx;
>  
> -	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
> +	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
>  	if (ret) return ret;
>  
>  	*st = (struct stat){
> @@ -152,6 +128,6 @@ int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int f
>  
>  weak_alias(__fstatat, fstatat);
>  
> -#if !_REDIR_TIME64
> +#if !_REDIR_TIME64 && !defined(_GNU_SOURCE)
>  weak_alias(fstatat, fstatat64);
>  #endif
> -- 
> 2.32.1 (Apple Git-133)

I don't understand why the condition for the glibc-compat alias was
changed here. It seems like an unrelated and unmotivated change that
slipped in...

Rich

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2024-02-24 16:57 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-19 12:12 [musl] [PATCH] add statx Ben Noordhuis
2020-01-24  8:38 ` [musl] " Ben Noordhuis
2020-01-24 14:01   ` Rich Felker
2020-01-28  8:59     ` Ben Noordhuis
2020-01-28 13:39       ` Rich Felker
2020-01-24 14:00 ` [musl] " Rich Felker
2020-01-24 15:27   ` Florian Weimer
2020-01-24 15:54     ` Rich Felker
2020-01-24 16:12       ` Florian Weimer
2020-01-24 16:29         ` Rich Felker
2020-01-28 10:41           ` Florian Weimer
2020-01-28 13:18             ` Rich Felker
2020-02-17  9:10               ` Florian Weimer
2020-02-17 15:29                 ` Rich Felker
2022-08-27 14:57 ` [musl] [PATCH 0/1] " Duncan Bellamy
2022-08-27 14:57   ` [musl] [PATCH 1/1] resubmitting old statx patch with changes Duncan Bellamy
2022-08-27 18:10     ` Rich Felker
2022-08-27 23:11       ` Dunk
2022-08-27 23:11 ` [musl] [PATCH 0/2] V2 Duncan Bellamy
2022-08-27 23:11   ` [musl] [PATCH 1/2] V2 resubmitting old statx patch with changes Duncan Bellamy
2022-08-29 13:50     ` [musl] " Dunk
2022-08-27 23:11   ` [musl] [PATCH 2/2] V2 src/stat/fstatat.c use new statx define Duncan Bellamy
2022-08-31 19:07 ` [musl] [PATCH 0/2] V3 Duncan Bellamy
2022-08-31 19:07   ` [musl] [PATCH 1/2] V3 resubmitting old statx patch with changes Duncan Bellamy
2024-02-24 16:56     ` Rich Felker
2022-08-31 19:07   ` [musl] [PATCH 2/2] V3 src/stat/fstatat.c use new statx define Duncan Bellamy
2024-02-24 16:57     ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).