All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range
@ 2021-11-28 18:17 наб
  2021-11-28 18:17 ` [PATCH 2/4] poll.2, sigwaitinfo.2: fix struct timespec::tv_sec to be time_t, not long наб
                   ` (3 more replies)
  0 siblings, 4 replies; 31+ messages in thread
From: наб @ 2021-11-28 18:17 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 7709 bytes --]

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man2/clock_getres.2          | 4 ++--
 man2/clock_nanosleep.2       | 4 ++--
 man2/io_getevents.2          | 4 ++--
 man2/nanosleep.2             | 4 ++--
 man2/poll.2                  | 4 ++--
 man2/sched_rr_get_interval.2 | 4 ++--
 man2/select.2                | 6 +++---
 man2/sigwaitinfo.2           | 4 ++--
 man2/timer_settime.2         | 2 +-
 man2/timerfd_create.2        | 2 +-
 man2/utimensat.2             | 4 ++--
 man3/mq_receive.3            | 4 ++--
 man3/mq_send.3               | 4 ++--
 man3/pthread_tryjoin_np.3    | 4 ++--
 man7/system_data_types.7     | 2 +-
 15 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/man2/clock_getres.2 b/man2/clock_getres.2
index c2bb492b9..f94b69d3c 100644
--- a/man2/clock_getres.2
+++ b/man2/clock_getres.2
@@ -93,8 +93,8 @@ structures, as specified in
 .in +4n
 .EX
 struct timespec {
-    time_t   tv_sec;        /* seconds */
-    long     tv_nsec;       /* nanoseconds */
+    time_t   tv_sec;        /* Seconds */
+    long     tv_nsec;       /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man2/clock_nanosleep.2 b/man2/clock_nanosleep.2
index b8c4afc2c..e6386e6a5 100644
--- a/man2/clock_nanosleep.2
+++ b/man2/clock_nanosleep.2
@@ -64,8 +64,8 @@ structures, defined as follows:
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds [0 .. 999999999] */
+    time_t tv_sec;        /* Seconds */
+    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man2/io_getevents.2 b/man2/io_getevents.2
index 7c7e625bf..08738e413 100644
--- a/man2/io_getevents.2
+++ b/man2/io_getevents.2
@@ -46,8 +46,8 @@ and is specified as a relative timeout in a structure of the following form:
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;      /* seconds */
-    long   tv_nsec;     /* nanoseconds [0 .. 999999999] */
+    time_t tv_sec;      /* Seconds */
+    long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man2/nanosleep.2 b/man2/nanosleep.2
index 89d8577db..993007e92 100644
--- a/man2/nanosleep.2
+++ b/man2/nanosleep.2
@@ -84,8 +84,8 @@ It is defined as follows:
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
+    time_t tv_sec;        /* Seconds */
+    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man2/poll.2 b/man2/poll.2
index 205468f3e..620528ec7 100644
--- a/man2/poll.2
+++ b/man2/poll.2
@@ -329,8 +329,8 @@ This argument is a pointer to a structure of the following form:
 .in +4n
 .EX
 struct timespec {
-    long    tv_sec;         /* seconds */
-    long    tv_nsec;        /* nanoseconds */
+    long    tv_sec;         /* Seconds */
+    long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man2/sched_rr_get_interval.2 b/man2/sched_rr_get_interval.2
index 93db938df..1f249572b 100644
--- a/man2/sched_rr_get_interval.2
+++ b/man2/sched_rr_get_interval.2
@@ -54,8 +54,8 @@ structure has the following form:
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;    /* seconds */
-    long   tv_nsec;   /* nanoseconds */
+    time_t tv_sec;    /* Seconds */
+    long   tv_nsec;   /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man2/select.2 b/man2/select.2
index aee25c52c..fd9a994eb 100644
--- a/man2/select.2
+++ b/man2/select.2
@@ -345,7 +345,7 @@ is a structure of the following type:
 .in +4n
 .EX
 struct timeval {
-    time_t      tv_sec;         /* seconds */
+    time_t      tv_sec;         /* Seconds */
     suseconds_t tv_usec;        /* microseconds */
 };
 .EE
@@ -358,8 +358,8 @@ has the following type:
 .in +4n
 .EX
 struct timespec {
-    time_t      tv_sec;         /* seconds */
-    long        tv_nsec;        /* nanoseconds */
+    time_t      tv_sec;         /* Seconds */
+    long        tv_nsec;        /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
index 00bc50485..716661479 100644
--- a/man2/sigwaitinfo.2
+++ b/man2/sigwaitinfo.2
@@ -93,8 +93,8 @@ This argument is of the following type:
 .in +4n
 .EX
 struct timespec {
-    long    tv_sec;         /* seconds */
-    long    tv_nsec;        /* nanoseconds */
+    long    tv_sec;         /* Seconds */
+    long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
 }
 .EE
 .in
diff --git a/man2/timer_settime.2 b/man2/timer_settime.2
index 10687b211..1c8d7fa17 100644
--- a/man2/timer_settime.2
+++ b/man2/timer_settime.2
@@ -67,7 +67,7 @@ structure is defined as follows:
 .EX
 struct timespec {
     time_t tv_sec;                /* Seconds */
-    long   tv_nsec;               /* Nanoseconds */
+    long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
 };
 
 struct itimerspec {
diff --git a/man2/timerfd_create.2 b/man2/timerfd_create.2
index 65fdfcc45..832ec4b68 100644
--- a/man2/timerfd_create.2
+++ b/man2/timerfd_create.2
@@ -159,7 +159,7 @@ each of which is in turn a structure of type
 .EX
 struct timespec {
     time_t tv_sec;                /* Seconds */
-    long   tv_nsec;               /* Nanoseconds */
+    long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
 };
 
 struct itimerspec {
diff --git a/man2/utimensat.2 b/man2/utimensat.2
index cb5f6b693..19fa8c677 100644
--- a/man2/utimensat.2
+++ b/man2/utimensat.2
@@ -93,8 +93,8 @@ This information is conveyed in a structure of the following form:
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
+    time_t tv_sec;        /* Seconds */
+    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man3/mq_receive.3 b/man3/mq_receive.3
index df463297d..4dac43643 100644
--- a/man3/mq_receive.3
+++ b/man3/mq_receive.3
@@ -97,8 +97,8 @@ specified in the following structure:
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
+    time_t tv_sec;        /* Seconds */
+    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man3/mq_send.3 b/man3/mq_send.3
index 54999f440..6b3fbe98a 100644
--- a/man3/mq_send.3
+++ b/man3/mq_send.3
@@ -106,8 +106,8 @@ specified in the following structure:
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
+    time_t tv_sec;        /* Seconds */
+    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man3/pthread_tryjoin_np.3 b/man3/pthread_tryjoin_np.3
index e912f8e3b..10b498c80 100644
--- a/man3/pthread_tryjoin_np.3
+++ b/man3/pthread_tryjoin_np.3
@@ -79,8 +79,8 @@ specifying an absolute time measured since the Epoch (see
 .in +4n
 .EX
 struct timespec {
-    time_t tv_sec;     /* seconds */
-    long   tv_nsec;    /* nanoseconds */
+    time_t tv_sec;     /* Seconds */
+    long   tv_nsec;    /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .in
diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index d117b1d2b..1e6a3f74c 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1544,7 +1544,7 @@ or
 .EX
 struct timespec {
     time_t  tv_sec;  /* Seconds */
-    long    tv_nsec; /* Nanoseconds */
+    long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .PP
-- 
2.30.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [PATCH 2/4] poll.2, sigwaitinfo.2: fix struct timespec::tv_sec to be time_t, not long
  2021-11-28 18:17 [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
@ 2021-11-28 18:17 ` наб
  2021-11-29 12:27   ` Alejandro Colomar (man-pages)
  2021-11-28 18:17 ` [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 31+ messages in thread
From: наб @ 2021-11-28 18:17 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 1000 bytes --]

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man2/poll.2        | 2 +-
 man2/sigwaitinfo.2 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/man2/poll.2 b/man2/poll.2
index 620528ec7..a278efbcc 100644
--- a/man2/poll.2
+++ b/man2/poll.2
@@ -329,7 +329,7 @@ This argument is a pointer to a structure of the following form:
 .in +4n
 .EX
 struct timespec {
-    long    tv_sec;         /* Seconds */
+    time_t  tv_sec;         /* Seconds */
     long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
 };
 .EE
diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
index 716661479..226625e4e 100644
--- a/man2/sigwaitinfo.2
+++ b/man2/sigwaitinfo.2
@@ -93,7 +93,7 @@ This argument is of the following type:
 .in +4n
 .EX
 struct timespec {
-    long    tv_sec;         /* Seconds */
+    time_t  tv_sec;         /* Seconds */
     long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
 }
 .EE
-- 
2.30.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-11-28 18:17 [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
  2021-11-28 18:17 ` [PATCH 2/4] poll.2, sigwaitinfo.2: fix struct timespec::tv_sec to be time_t, not long наб
@ 2021-11-28 18:17 ` наб
  2021-11-29  9:45   ` Jakub Wilk
  2021-11-29 12:31   ` Alejandro Colomar (man-pages)
  2021-11-28 18:17 ` [PATCH " наб
  2021-11-29 12:26 ` [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range Alejandro Colomar (man-pages)
  3 siblings, 2 replies; 31+ messages in thread
From: наб @ 2021-11-28 18:17 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 9258 bytes --]

There are three files that govern userspace struct timespec on glibc:
1. bits/wordsize.h, defining:
   (a) __WORDSIZE to 32 on ILP32 and 64 on LP64
   (b) on x32: __SYSCALL_WORDSIZE to 64
2. bits/timesize.h, defining
   (a) __TIMESIZE to __WORDSIZE, except on x32 where it's 64
3. bits/types/struct_timespec.h, declaring struct timespec as:
     struct timespec
     {
      __time_t tv_sec;      /* Seconds.  */
     #if __WORDSIZE == 64 \
      || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
      || __TIMESIZE == 32
      __syscall_slong_t tv_nsec;    /* Nanoseconds.  */
     #else
     # if __BYTE_ORDER == __BIG_ENDIAN
      int: 32;           /* Padding.  */
      long int tv_nsec;  /* Nanoseconds.  */
     # else
      long int tv_nsec;  /* Nanoseconds.  */
      int: 32;           /* Padding.  */
     # endif
     #endif
     };
   this has two side-effects: struct timespec
   (a) is always sizeof==time_t+8, and
   (b) has tv_nsec as __syscall_slong_t
       *and* !is_same<__syscall_slong_t, long>
       if using ILP64 syscalls on an LP32 system, i.e. on x32.

This means, that the simplified
  struct timespec {
      time_t  tv_sec;  /* Seconds */
      long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
  };
declaration is *invalid* for x32,
where struct timespec::tv_nsec is an int64_t (long long).

Transformation snippet:
  sed -i -e '/Nanoseconds \[0/i#if !(__x86_64__ && __ILP32__ /* == x32 */)' -e '/Nanoseconds \[0/a#else\
      long long tv_nsec;\
  #endif' man2/clock_getres.2 man2/clock_nanosleep.2 man2/io_getevents.2 man2/nanosleep.2 man2/poll.2 man2/sched_rr_get_interval.2 man2/select.2 man2/sigwaitinfo.2 man2/timer_settime.2 man2/timerfd_create.2 man2/utimensat.2 man3/mq_receive.3 man3/mq_send.3 man3/pthread_tryjoin_np.3 man7/system_data_types.7

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man2/clock_getres.2          | 4 ++++
 man2/clock_nanosleep.2       | 4 ++++
 man2/io_getevents.2          | 4 ++++
 man2/nanosleep.2             | 4 ++++
 man2/poll.2                  | 4 ++++
 man2/sched_rr_get_interval.2 | 4 ++++
 man2/select.2                | 4 ++++
 man2/sigwaitinfo.2           | 4 ++++
 man2/timer_settime.2         | 4 ++++
 man2/timerfd_create.2        | 4 ++++
 man2/utimensat.2             | 4 ++++
 man3/mq_receive.3            | 4 ++++
 man3/mq_send.3               | 4 ++++
 man3/pthread_tryjoin_np.3    | 4 ++++
 man7/system_data_types.7     | 4 ++++
 15 files changed, 60 insertions(+)

diff --git a/man2/clock_getres.2 b/man2/clock_getres.2
index f94b69d3c..0d9326b84 100644
--- a/man2/clock_getres.2
+++ b/man2/clock_getres.2
@@ -94,7 +94,11 @@ structures, as specified in
 .EX
 struct timespec {
     time_t   tv_sec;        /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long     tv_nsec;       /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man2/clock_nanosleep.2 b/man2/clock_nanosleep.2
index e6386e6a5..06ad6acf3 100644
--- a/man2/clock_nanosleep.2
+++ b/man2/clock_nanosleep.2
@@ -65,7 +65,11 @@ structures, defined as follows:
 .EX
 struct timespec {
     time_t tv_sec;        /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man2/io_getevents.2 b/man2/io_getevents.2
index 08738e413..020cb5882 100644
--- a/man2/io_getevents.2
+++ b/man2/io_getevents.2
@@ -47,7 +47,11 @@ and is specified as a relative timeout in a structure of the following form:
 .EX
 struct timespec {
     time_t tv_sec;      /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man2/nanosleep.2 b/man2/nanosleep.2
index 993007e92..81f5d93a5 100644
--- a/man2/nanosleep.2
+++ b/man2/nanosleep.2
@@ -85,7 +85,11 @@ It is defined as follows:
 .EX
 struct timespec {
     time_t tv_sec;        /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man2/poll.2 b/man2/poll.2
index a278efbcc..1bdd06ded 100644
--- a/man2/poll.2
+++ b/man2/poll.2
@@ -330,7 +330,11 @@ This argument is a pointer to a structure of the following form:
 .EX
 struct timespec {
     time_t  tv_sec;         /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man2/sched_rr_get_interval.2 b/man2/sched_rr_get_interval.2
index 1f249572b..ee9067c20 100644
--- a/man2/sched_rr_get_interval.2
+++ b/man2/sched_rr_get_interval.2
@@ -55,7 +55,11 @@ structure has the following form:
 .EX
 struct timespec {
     time_t tv_sec;    /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;   /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man2/select.2 b/man2/select.2
index fd9a994eb..dad9e8937 100644
--- a/man2/select.2
+++ b/man2/select.2
@@ -359,7 +359,11 @@ has the following type:
 .EX
 struct timespec {
     time_t      tv_sec;         /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long        tv_nsec;        /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
index 226625e4e..e2dcb5eef 100644
--- a/man2/sigwaitinfo.2
+++ b/man2/sigwaitinfo.2
@@ -94,7 +94,11 @@ This argument is of the following type:
 .EX
 struct timespec {
     time_t  tv_sec;         /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 }
 .EE
 .in
diff --git a/man2/timer_settime.2 b/man2/timer_settime.2
index 1c8d7fa17..a76fb9b10 100644
--- a/man2/timer_settime.2
+++ b/man2/timer_settime.2
@@ -67,7 +67,11 @@ structure is defined as follows:
 .EX
 struct timespec {
     time_t tv_sec;                /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 
 struct itimerspec {
diff --git a/man2/timerfd_create.2 b/man2/timerfd_create.2
index 832ec4b68..4bf8a3a4b 100644
--- a/man2/timerfd_create.2
+++ b/man2/timerfd_create.2
@@ -159,7 +159,11 @@ each of which is in turn a structure of type
 .EX
 struct timespec {
     time_t tv_sec;                /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 
 struct itimerspec {
diff --git a/man2/utimensat.2 b/man2/utimensat.2
index 19fa8c677..c806c51a5 100644
--- a/man2/utimensat.2
+++ b/man2/utimensat.2
@@ -94,7 +94,11 @@ This information is conveyed in a structure of the following form:
 .EX
 struct timespec {
     time_t tv_sec;        /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man3/mq_receive.3 b/man3/mq_receive.3
index 4dac43643..deda2d452 100644
--- a/man3/mq_receive.3
+++ b/man3/mq_receive.3
@@ -98,7 +98,11 @@ specified in the following structure:
 .EX
 struct timespec {
     time_t tv_sec;        /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man3/mq_send.3 b/man3/mq_send.3
index 6b3fbe98a..c0e67df34 100644
--- a/man3/mq_send.3
+++ b/man3/mq_send.3
@@ -107,7 +107,11 @@ specified in the following structure:
 .EX
 struct timespec {
     time_t tv_sec;        /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man3/pthread_tryjoin_np.3 b/man3/pthread_tryjoin_np.3
index 10b498c80..d68c2bbba 100644
--- a/man3/pthread_tryjoin_np.3
+++ b/man3/pthread_tryjoin_np.3
@@ -80,7 +80,11 @@ specifying an absolute time measured since the Epoch (see
 .EX
 struct timespec {
     time_t tv_sec;     /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long   tv_nsec;    /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .in
diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index 1e6a3f74c..80679b180 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1544,7 +1544,11 @@ or
 .EX
 struct timespec {
     time_t  tv_sec;  /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .PP
-- 
2.30.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [PATCH 4/4] system_data_types.7: note that struct timespec::tv_nsec being long long on x32 is an extension
  2021-11-28 18:17 [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
  2021-11-28 18:17 ` [PATCH 2/4] poll.2, sigwaitinfo.2: fix struct timespec::tv_sec to be time_t, not long наб
  2021-11-28 18:17 ` [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
@ 2021-11-28 18:17 ` наб
  2021-11-29 12:26 ` [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range Alejandro Colomar (man-pages)
  3 siblings, 0 replies; 31+ messages in thread
From: наб @ 2021-11-28 18:17 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 557 bytes --]

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man7/system_data_types.7 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index 80679b180..10b3bd13c 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1556,6 +1556,7 @@ Describes times in seconds and nanoseconds.
 .PP
 .IR "Conforming to" :
 C11 and later; POSIX.1-2001 and later.
+The 64-bit tv_nsec on x32 is an extension.
 .PP
 .IR "See also" :
 .BR clock_gettime (2),
-- 
2.30.2

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-11-28 18:17 ` [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
@ 2021-11-29  9:45   ` Jakub Wilk
  2021-11-29 12:31   ` Alejandro Colomar (man-pages)
  1 sibling, 0 replies; 31+ messages in thread
From: Jakub Wilk @ 2021-11-29  9:45 UTC (permalink / raw)
  To: наб; +Cc: Alejandro Colomar, linux-man

* наб <nabijaczleweli@nabijaczleweli.xyz>, 2021-11-28, 19:17:
>This means, that the simplified
>  struct timespec {
>      time_t  tv_sec;  /* Seconds */
>      long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
>  };
>declaration is *invalid* for x32,
>where struct timespec::tv_nsec is an int64_t (long long).

Indeed, it's a long standing bug in glibc (or in the kernel, depending 
on your point of view):
https://sourceware.org/bugzilla/show_bug.cgi?id=16437

It's worth documenting, but IMHO this information should be in the BUGS 
sections.

-- 
Jakub Wilk

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

* Re: [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range
  2021-11-28 18:17 [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
                   ` (2 preceding siblings ...)
  2021-11-28 18:17 ` [PATCH " наб
@ 2021-11-29 12:26 ` Alejandro Colomar (man-pages)
  3 siblings, 0 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-11-29 12:26 UTC (permalink / raw)
  To: наб; +Cc: linux-man

Hi наб,

On 11/28/21 19:17, наб wrote:
> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>

Regarding the addition of the range in the comments, I like it.

However, instead of repeating the information in all pages that repeat 
the definition of 'struct timespec', I'd go one step further: remove all 
of those redefinitions, and instead add a reference to timespec(3).  If 
any of those redefinitions contains any information that is not in 
timespec(3) (a.k.a. system_data_types(7)), then add it to timespec(3).

That way we can control the accurateness of that info by having it 
centralized, and save electronic ink :)


Cheers,

Alex

> ---
>   man2/clock_getres.2          | 4 ++--
>   man2/clock_nanosleep.2       | 4 ++--
>   man2/io_getevents.2          | 4 ++--
>   man2/nanosleep.2             | 4 ++--
>   man2/poll.2                  | 4 ++--
>   man2/sched_rr_get_interval.2 | 4 ++--
>   man2/select.2                | 6 +++---
>   man2/sigwaitinfo.2           | 4 ++--
>   man2/timer_settime.2         | 2 +-
>   man2/timerfd_create.2        | 2 +-
>   man2/utimensat.2             | 4 ++--
>   man3/mq_receive.3            | 4 ++--
>   man3/mq_send.3               | 4 ++--
>   man3/pthread_tryjoin_np.3    | 4 ++--
>   man7/system_data_types.7     | 2 +-
>   15 files changed, 28 insertions(+), 28 deletions(-)
> 
> diff --git a/man2/clock_getres.2 b/man2/clock_getres.2
> index c2bb492b9..f94b69d3c 100644
> --- a/man2/clock_getres.2
> +++ b/man2/clock_getres.2
> @@ -93,8 +93,8 @@ structures, as specified in
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t   tv_sec;        /* seconds */
> -    long     tv_nsec;       /* nanoseconds */
> +    time_t   tv_sec;        /* Seconds */
> +    long     tv_nsec;       /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man2/clock_nanosleep.2 b/man2/clock_nanosleep.2
> index b8c4afc2c..e6386e6a5 100644
> --- a/man2/clock_nanosleep.2
> +++ b/man2/clock_nanosleep.2
> @@ -64,8 +64,8 @@ structures, defined as follows:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds [0 .. 999999999] */
> +    time_t tv_sec;        /* Seconds */
> +    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man2/io_getevents.2 b/man2/io_getevents.2
> index 7c7e625bf..08738e413 100644
> --- a/man2/io_getevents.2
> +++ b/man2/io_getevents.2
> @@ -46,8 +46,8 @@ and is specified as a relative timeout in a structure of the following form:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;      /* seconds */
> -    long   tv_nsec;     /* nanoseconds [0 .. 999999999] */
> +    time_t tv_sec;      /* Seconds */
> +    long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man2/nanosleep.2 b/man2/nanosleep.2
> index 89d8577db..993007e92 100644
> --- a/man2/nanosleep.2
> +++ b/man2/nanosleep.2
> @@ -84,8 +84,8 @@ It is defined as follows:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> +    time_t tv_sec;        /* Seconds */
> +    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man2/poll.2 b/man2/poll.2
> index 205468f3e..620528ec7 100644
> --- a/man2/poll.2
> +++ b/man2/poll.2
> @@ -329,8 +329,8 @@ This argument is a pointer to a structure of the following form:
>   .in +4n
>   .EX
>   struct timespec {
> -    long    tv_sec;         /* seconds */
> -    long    tv_nsec;        /* nanoseconds */
> +    long    tv_sec;         /* Seconds */
> +    long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man2/sched_rr_get_interval.2 b/man2/sched_rr_get_interval.2
> index 93db938df..1f249572b 100644
> --- a/man2/sched_rr_get_interval.2
> +++ b/man2/sched_rr_get_interval.2
> @@ -54,8 +54,8 @@ structure has the following form:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;    /* seconds */
> -    long   tv_nsec;   /* nanoseconds */
> +    time_t tv_sec;    /* Seconds */
> +    long   tv_nsec;   /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man2/select.2 b/man2/select.2
> index aee25c52c..fd9a994eb 100644
> --- a/man2/select.2
> +++ b/man2/select.2
> @@ -345,7 +345,7 @@ is a structure of the following type:
>   .in +4n
>   .EX
>   struct timeval {
> -    time_t      tv_sec;         /* seconds */
> +    time_t      tv_sec;         /* Seconds */
>       suseconds_t tv_usec;        /* microseconds */
>   };
>   .EE
> @@ -358,8 +358,8 @@ has the following type:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t      tv_sec;         /* seconds */
> -    long        tv_nsec;        /* nanoseconds */
> +    time_t      tv_sec;         /* Seconds */
> +    long        tv_nsec;        /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
> index 00bc50485..716661479 100644
> --- a/man2/sigwaitinfo.2
> +++ b/man2/sigwaitinfo.2
> @@ -93,8 +93,8 @@ This argument is of the following type:
>   .in +4n
>   .EX
>   struct timespec {
> -    long    tv_sec;         /* seconds */
> -    long    tv_nsec;        /* nanoseconds */
> +    long    tv_sec;         /* Seconds */
> +    long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
>   }
>   .EE
>   .in
> diff --git a/man2/timer_settime.2 b/man2/timer_settime.2
> index 10687b211..1c8d7fa17 100644
> --- a/man2/timer_settime.2
> +++ b/man2/timer_settime.2
> @@ -67,7 +67,7 @@ structure is defined as follows:
>   .EX
>   struct timespec {
>       time_t tv_sec;                /* Seconds */
> -    long   tv_nsec;               /* Nanoseconds */
> +    long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
>   };
>   
>   struct itimerspec {
> diff --git a/man2/timerfd_create.2 b/man2/timerfd_create.2
> index 65fdfcc45..832ec4b68 100644
> --- a/man2/timerfd_create.2
> +++ b/man2/timerfd_create.2
> @@ -159,7 +159,7 @@ each of which is in turn a structure of type
>   .EX
>   struct timespec {
>       time_t tv_sec;                /* Seconds */
> -    long   tv_nsec;               /* Nanoseconds */
> +    long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
>   };
>   
>   struct itimerspec {
> diff --git a/man2/utimensat.2 b/man2/utimensat.2
> index cb5f6b693..19fa8c677 100644
> --- a/man2/utimensat.2
> +++ b/man2/utimensat.2
> @@ -93,8 +93,8 @@ This information is conveyed in a structure of the following form:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> +    time_t tv_sec;        /* Seconds */
> +    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man3/mq_receive.3 b/man3/mq_receive.3
> index df463297d..4dac43643 100644
> --- a/man3/mq_receive.3
> +++ b/man3/mq_receive.3
> @@ -97,8 +97,8 @@ specified in the following structure:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> +    time_t tv_sec;        /* Seconds */
> +    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man3/mq_send.3 b/man3/mq_send.3
> index 54999f440..6b3fbe98a 100644
> --- a/man3/mq_send.3
> +++ b/man3/mq_send.3
> @@ -106,8 +106,8 @@ specified in the following structure:
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> +    time_t tv_sec;        /* Seconds */
> +    long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man3/pthread_tryjoin_np.3 b/man3/pthread_tryjoin_np.3
> index e912f8e3b..10b498c80 100644
> --- a/man3/pthread_tryjoin_np.3
> +++ b/man3/pthread_tryjoin_np.3
> @@ -79,8 +79,8 @@ specifying an absolute time measured since the Epoch (see
>   .in +4n
>   .EX
>   struct timespec {
> -    time_t tv_sec;     /* seconds */
> -    long   tv_nsec;    /* nanoseconds */
> +    time_t tv_sec;     /* Seconds */
> +    long   tv_nsec;    /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .in
> diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
> index d117b1d2b..1e6a3f74c 100644
> --- a/man7/system_data_types.7
> +++ b/man7/system_data_types.7
> @@ -1544,7 +1544,7 @@ or
>   .EX
>   struct timespec {
>       time_t  tv_sec;  /* Seconds */
> -    long    tv_nsec; /* Nanoseconds */
> +    long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .PP
> 

-- 
Alejandro Colomar
Linux man-pages comaintainer; http://www.kernel.org/doc/man-pages/

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

* Re: [PATCH 2/4] poll.2, sigwaitinfo.2: fix struct timespec::tv_sec to be time_t, not long
  2021-11-28 18:17 ` [PATCH 2/4] poll.2, sigwaitinfo.2: fix struct timespec::tv_sec to be time_t, not long наб
@ 2021-11-29 12:27   ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-11-29 12:27 UTC (permalink / raw)
  To: наб; +Cc: linux-man

As I said, I'd just replace those redefinitions by referencces to 
timespec(3).  The fact that these contained different types for tv_sec 
confirms my guess that not all of the repeated definitions were correct.

On 11/28/21 19:17, наб wrote:
> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
> ---
>   man2/poll.2        | 2 +-
>   man2/sigwaitinfo.2 | 2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/man2/poll.2 b/man2/poll.2
> index 620528ec7..a278efbcc 100644
> --- a/man2/poll.2
> +++ b/man2/poll.2
> @@ -329,7 +329,7 @@ This argument is a pointer to a structure of the following form:
>   .in +4n
>   .EX
>   struct timespec {
> -    long    tv_sec;         /* Seconds */
> +    time_t  tv_sec;         /* Seconds */
>       long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
> diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
> index 716661479..226625e4e 100644
> --- a/man2/sigwaitinfo.2
> +++ b/man2/sigwaitinfo.2
> @@ -93,7 +93,7 @@ This argument is of the following type:
>   .in +4n
>   .EX
>   struct timespec {
> -    long    tv_sec;         /* Seconds */
> +    time_t  tv_sec;         /* Seconds */
>       long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
>   }
>   .EE
> 

-- 
Alejandro Colomar
Linux man-pages comaintainer; http://www.kernel.org/doc/man-pages/

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

* Re: [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-11-28 18:17 ` [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
  2021-11-29  9:45   ` Jakub Wilk
@ 2021-11-29 12:31   ` Alejandro Colomar (man-pages)
  2021-12-03 23:46     ` наб
  1 sibling, 1 reply; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-11-29 12:31 UTC (permalink / raw)
  To: наб; +Cc: linux-man

Hi наб,

On 11/28/21 19:17, наб wrote:
> There are three files that govern userspace struct timespec on glibc:
> 1. bits/wordsize.h, defining:
>     (a) __WORDSIZE to 32 on ILP32 and 64 on LP64
>     (b) on x32: __SYSCALL_WORDSIZE to 64
> 2. bits/timesize.h, defining
>     (a) __TIMESIZE to __WORDSIZE, except on x32 where it's 64
> 3. bits/types/struct_timespec.h, declaring struct timespec as:
>       struct timespec
>       {
>        __time_t tv_sec;      /* Seconds.  */
>       #if __WORDSIZE == 64 \
>        || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
>        || __TIMESIZE == 32
>        __syscall_slong_t tv_nsec;    /* Nanoseconds.  */
>       #else
>       # if __BYTE_ORDER == __BIG_ENDIAN
>        int: 32;           /* Padding.  */
>        long int tv_nsec;  /* Nanoseconds.  */
>       # else
>        long int tv_nsec;  /* Nanoseconds.  */
>        int: 32;           /* Padding.  */
>       # endif
>       #endif
>       };
>     this has two side-effects: struct timespec
>     (a) is always sizeof==time_t+8, and
>     (b) has tv_nsec as __syscall_slong_t
>         *and* !is_same<__syscall_slong_t, long>
>         if using ILP64 syscalls on an LP32 system, i.e. on x32.

I guess you meant LP64, not ILP64?
AFAIK, glibc doesn't support ILP64.

Other than that, the commit looks good to me.

But this would be a simpler commit if we only had one definition.  Do 
you agree in changing the whole patch set in that (IMO simpler) way?


Thanks,

Alex

> 
> This means, that the simplified
>    struct timespec {
>        time_t  tv_sec;  /* Seconds */
>        long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
>    };
> declaration is *invalid* for x32,
> where struct timespec::tv_nsec is an int64_t (long long).
> 
> Transformation snippet:
>    sed -i -e '/Nanoseconds \[0/i#if !(__x86_64__ && __ILP32__ /* == x32 */)' -e '/Nanoseconds \[0/a#else\
>        long long tv_nsec;\
>    #endif' man2/clock_getres.2 man2/clock_nanosleep.2 man2/io_getevents.2 man2/nanosleep.2 man2/poll.2 man2/sched_rr_get_interval.2 man2/select.2 man2/sigwaitinfo.2 man2/timer_settime.2 man2/timerfd_create.2 man2/utimensat.2 man3/mq_receive.3 man3/mq_send.3 man3/pthread_tryjoin_np.3 man7/system_data_types.7
> 
> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
> ---
>   man2/clock_getres.2          | 4 ++++
>   man2/clock_nanosleep.2       | 4 ++++
>   man2/io_getevents.2          | 4 ++++
>   man2/nanosleep.2             | 4 ++++
>   man2/poll.2                  | 4 ++++
>   man2/sched_rr_get_interval.2 | 4 ++++
>   man2/select.2                | 4 ++++
>   man2/sigwaitinfo.2           | 4 ++++
>   man2/timer_settime.2         | 4 ++++
>   man2/timerfd_create.2        | 4 ++++
>   man2/utimensat.2             | 4 ++++
>   man3/mq_receive.3            | 4 ++++
>   man3/mq_send.3               | 4 ++++
>   man3/pthread_tryjoin_np.3    | 4 ++++
>   man7/system_data_types.7     | 4 ++++
>   15 files changed, 60 insertions(+)
> 
> diff --git a/man2/clock_getres.2 b/man2/clock_getres.2
> index f94b69d3c..0d9326b84 100644
> --- a/man2/clock_getres.2
> +++ b/man2/clock_getres.2
> @@ -94,7 +94,11 @@ structures, as specified in
>   .EX
>   struct timespec {
>       time_t   tv_sec;        /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long     tv_nsec;       /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man2/clock_nanosleep.2 b/man2/clock_nanosleep.2
> index e6386e6a5..06ad6acf3 100644
> --- a/man2/clock_nanosleep.2
> +++ b/man2/clock_nanosleep.2
> @@ -65,7 +65,11 @@ structures, defined as follows:
>   .EX
>   struct timespec {
>       time_t tv_sec;        /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man2/io_getevents.2 b/man2/io_getevents.2
> index 08738e413..020cb5882 100644
> --- a/man2/io_getevents.2
> +++ b/man2/io_getevents.2
> @@ -47,7 +47,11 @@ and is specified as a relative timeout in a structure of the following form:
>   .EX
>   struct timespec {
>       time_t tv_sec;      /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man2/nanosleep.2 b/man2/nanosleep.2
> index 993007e92..81f5d93a5 100644
> --- a/man2/nanosleep.2
> +++ b/man2/nanosleep.2
> @@ -85,7 +85,11 @@ It is defined as follows:
>   .EX
>   struct timespec {
>       time_t tv_sec;        /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man2/poll.2 b/man2/poll.2
> index a278efbcc..1bdd06ded 100644
> --- a/man2/poll.2
> +++ b/man2/poll.2
> @@ -330,7 +330,11 @@ This argument is a pointer to a structure of the following form:
>   .EX
>   struct timespec {
>       time_t  tv_sec;         /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man2/sched_rr_get_interval.2 b/man2/sched_rr_get_interval.2
> index 1f249572b..ee9067c20 100644
> --- a/man2/sched_rr_get_interval.2
> +++ b/man2/sched_rr_get_interval.2
> @@ -55,7 +55,11 @@ structure has the following form:
>   .EX
>   struct timespec {
>       time_t tv_sec;    /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;   /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man2/select.2 b/man2/select.2
> index fd9a994eb..dad9e8937 100644
> --- a/man2/select.2
> +++ b/man2/select.2
> @@ -359,7 +359,11 @@ has the following type:
>   .EX
>   struct timespec {
>       time_t      tv_sec;         /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long        tv_nsec;        /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
> index 226625e4e..e2dcb5eef 100644
> --- a/man2/sigwaitinfo.2
> +++ b/man2/sigwaitinfo.2
> @@ -94,7 +94,11 @@ This argument is of the following type:
>   .EX
>   struct timespec {
>       time_t  tv_sec;         /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long    tv_nsec;        /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   }
>   .EE
>   .in
> diff --git a/man2/timer_settime.2 b/man2/timer_settime.2
> index 1c8d7fa17..a76fb9b10 100644
> --- a/man2/timer_settime.2
> +++ b/man2/timer_settime.2
> @@ -67,7 +67,11 @@ structure is defined as follows:
>   .EX
>   struct timespec {
>       time_t tv_sec;                /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   
>   struct itimerspec {
> diff --git a/man2/timerfd_create.2 b/man2/timerfd_create.2
> index 832ec4b68..4bf8a3a4b 100644
> --- a/man2/timerfd_create.2
> +++ b/man2/timerfd_create.2
> @@ -159,7 +159,11 @@ each of which is in turn a structure of type
>   .EX
>   struct timespec {
>       time_t tv_sec;                /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;               /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   
>   struct itimerspec {
> diff --git a/man2/utimensat.2 b/man2/utimensat.2
> index 19fa8c677..c806c51a5 100644
> --- a/man2/utimensat.2
> +++ b/man2/utimensat.2
> @@ -94,7 +94,11 @@ This information is conveyed in a structure of the following form:
>   .EX
>   struct timespec {
>       time_t tv_sec;        /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man3/mq_receive.3 b/man3/mq_receive.3
> index 4dac43643..deda2d452 100644
> --- a/man3/mq_receive.3
> +++ b/man3/mq_receive.3
> @@ -98,7 +98,11 @@ specified in the following structure:
>   .EX
>   struct timespec {
>       time_t tv_sec;        /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man3/mq_send.3 b/man3/mq_send.3
> index 6b3fbe98a..c0e67df34 100644
> --- a/man3/mq_send.3
> +++ b/man3/mq_send.3
> @@ -107,7 +107,11 @@ specified in the following structure:
>   .EX
>   struct timespec {
>       time_t tv_sec;        /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;       /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man3/pthread_tryjoin_np.3 b/man3/pthread_tryjoin_np.3
> index 10b498c80..d68c2bbba 100644
> --- a/man3/pthread_tryjoin_np.3
> +++ b/man3/pthread_tryjoin_np.3
> @@ -80,7 +80,11 @@ specifying an absolute time measured since the Epoch (see
>   .EX
>   struct timespec {
>       time_t tv_sec;     /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long   tv_nsec;    /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .in
> diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
> index 1e6a3f74c..80679b180 100644
> --- a/man7/system_data_types.7
> +++ b/man7/system_data_types.7
> @@ -1544,7 +1544,11 @@ or
>   .EX
>   struct timespec {
>       time_t  tv_sec;  /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif
>   };
>   .EE
>   .PP
> 

-- 
Alejandro Colomar
Linux man-pages comaintainer; http://www.kernel.org/doc/man-pages/

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

* Re: [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-11-29 12:31   ` Alejandro Colomar (man-pages)
@ 2021-12-03 23:46     ` наб
  2021-12-06 19:18       ` [PATCH 3/4] Many pages: " Alejandro Colomar (man-pages)
  0 siblings, 1 reply; 31+ messages in thread
From: наб @ 2021-12-03 23:46 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 1694 bytes --]

Hi!

On Mon, Nov 29, 2021 at 01:31:48PM +0100, Alejandro Colomar (man-pages) wrote:
> >     (a) is always sizeof==time_t+8, and
> >     (b) has tv_nsec as __syscall_slong_t
> >         *and* !is_same<__syscall_slong_t, long>
> >         if using ILP64 syscalls on an LP32 system, i.e. on x32.
> I guess you meant LP64, not ILP64?
> AFAIK, glibc doesn't support ILP64.
Yes, good catch! Def. a typo.

> But this would be a simpler commit if we only had one definition.
I was going to suggest it originally, but held up because, well,
before writing this patchset I didn't even know about
system_data_types.7, and it seemed that most other declarations are
in-line (which is sensible, I think, and in line with the common
use-case).

> Do you agree in changing the whole patch set in that (IMO simpler) way?
I mean, IMO in-line is better to use, but a struct this short and
relatively confusing when you actually unroll the types
makes sense to be banished.

So, just so we're clear on the direction of this before I re-write
a lot of these sections, do these (cherry-picking a few):
  clock_getres.2:
    The res and tp arguments are timespec(3) structures, as specified in
    <time.h>.
  mq_receive.3:
    This value is an absolute timeout in seconds and nanoseconds since
	the Epoch, 1970-01-01 00:00:00 +0000 (UTC),
	specified in struct timespec(3).
  pthread_tryjoin_np.3:
    If the timeout expires before thread terminates, the call returns an
	error.  The abstime argument is a struct timespec(3), specifying an
	absolute time measured since the Epoch (see time(2)).
  + adding timespec(3) to the SEE ALSO sexions
Sound about right?

Best,
наб

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH 3/4] Many pages: correct struct timespec::tv_nsec type for x32
  2021-12-03 23:46     ` наб
@ 2021-12-06 19:18       ` Alejandro Colomar (man-pages)
  2021-12-06 20:11         ` [PATCH v2 0/4] timespec(3) migration наб
  0 siblings, 1 reply; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-06 19:18 UTC (permalink / raw)
  To: наб; +Cc: linux-man, Michael Kerrisk (man-pages)

Hi, наб!

On 12/4/21 00:46, наб wrote:
>> But this would be a simpler commit if we only had one definition.
> I was going to suggest it originally, but held up because, well,
> before writing this patchset I didn't even know about
> system_data_types.7, and it seemed that most other declarations are
> in-line (which is sensible, I think, and in line with the common
> use-case).
> 
>> Do you agree in changing the whole patch set in that (IMO simpler) way?
> I mean, IMO in-line is better to use, but a struct this short and
> relatively confusing when you actually unroll the types
> makes sense to be banished.
> 
> So, just so we're clear on the direction of this before I re-write
> a lot of these sections, do these (cherry-picking a few):
>    clock_getres.2:
>      The res and tp arguments are timespec(3) structures, as specified in
>      <time.h>.
>    mq_receive.3:
>      This value is an absolute timeout in seconds and nanoseconds since
> 	the Epoch, 1970-01-01 00:00:00 +0000 (UTC),
> 	specified in struct timespec(3).

I think I slighly prefer "in a timespec(3) structure" (the main two 
reasons are: consistency with existing pages, and also compatibility 
with a possible future change that I have in mind[1] of the link from 
timespec(3) to timespec-struct(3), which would read better as 
timespec-struct(3) structure rather than struct timespec-struct(3)), as 
in the previous example.  However, I only slightly prefer that and don't 
really care that much, and will leave the final decision up to you.

[1] 
<https://lore.kernel.org/linux-man/20211102181454.280919-4-alx.manpages@gmail.com/>

>    pthread_tryjoin_np.3:
>      If the timeout expires before thread terminates, the call returns an
> 	error.  The abstime argument is a struct timespec(3), specifying an
> 	absolute time measured since the Epoch (see time(2)).
>    + adding timespec(3) to the SEE ALSO sexions
> Sound about right?

Yes, they sound great!

Cheers,
Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* [PATCH v2 0/4] timespec(3) migration
  2021-12-06 19:18       ` [PATCH 3/4] Many pages: " Alejandro Colomar (man-pages)
@ 2021-12-06 20:11         ` наб
  2021-12-06 20:12           ` [PATCH v2 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct timespec declarations with "timespec(3) structure" references наб
                             ` (3 more replies)
  0 siblings, 4 replies; 31+ messages in thread
From: наб @ 2021-12-06 20:11 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man, Michael Kerrisk (man-pages)

[-- Attachment #1: Type: text/plain, Size: 2070 bytes --]

On Mon, Dec 06, 2021 at 08:18:26PM +0100, Alejandro Colomar (man-pages) wrote:
> I think I slighly prefer "in a timespec(3) structure".
> However, I only slightly prefer that and don't really care that much, and
> will leave the final decision up to you.
It turned out very easy to rearrange all the pages to use this,
so they're all "timespec(3) structure" or "timespec(3) structures".

I've taken an additional liberty in stripping off
"as specified in <time.h>" from clock_getres.2: _nanosleep doesn't say
it, and they both live in <time.h> anyway.

наб (4):
  clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2,
    poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2,
    timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3,
    mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct
    timespec declarations with "timespec(3) structure" references
  system_data_types.7: standardise on struct timespec fields comments to
    ucase w/tv_nsec range
  system_data_types.7: correct struct timespec::tv_nsec type for x32
  system_data_types.7: note that struct timespec::tv_nsec being long
    long on x32 is an extension

 man2/clock_getres.2          | 15 +++------------
 man2/clock_nanosleep.2       | 14 +++-----------
 man2/io_getevents.2          | 14 ++++----------
 man2/nanosleep.2             | 16 ++++------------
 man2/poll.2                  | 14 ++++----------
 man2/sched_rr_get_interval.2 | 16 ++--------------
 man2/select.2                | 14 ++++----------
 man2/sigwaitinfo.2           | 14 ++++----------
 man2/timer_settime.2         |  8 ++------
 man2/timerfd_create.2        | 11 ++++-------
 man2/utimensat.2             | 14 ++++----------
 man3/mq_receive.3            | 14 ++++----------
 man3/mq_send.3               | 14 ++++----------
 man3/pthread_tryjoin_np.3    | 16 +++++-----------
 man3/sem_wait.3              | 15 ++++-----------
 man7/system_data_types.7     |  9 ++++++++-
 16 files changed, 63 insertions(+), 155 deletions(-)

-- 
2.30.2

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [PATCH v2 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct timespec declarations with "timespec(3) structure" references
  2021-12-06 20:11         ` [PATCH v2 0/4] timespec(3) migration наб
@ 2021-12-06 20:12           ` наб
  2021-12-06 21:14             ` Alejandro Colomar (man-pages)
  2021-12-06 20:12           ` [PATCH v2 2/4] system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 31+ messages in thread
From: наб @ 2021-12-06 20:12 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man, Michael Kerrisk (man-pages)

[-- Attachment #1: Type: text/plain, Size: 14066 bytes --]

Also stripped "as specified in <time.h>" from clock_getres.2,
as it already lives in time.h

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man2/clock_getres.2          | 15 +++------------
 man2/clock_nanosleep.2       | 14 +++-----------
 man2/io_getevents.2          | 14 ++++----------
 man2/nanosleep.2             | 16 ++++------------
 man2/poll.2                  | 14 ++++----------
 man2/sched_rr_get_interval.2 | 16 ++--------------
 man2/select.2                | 14 ++++----------
 man2/sigwaitinfo.2           | 14 ++++----------
 man2/timer_settime.2         |  8 ++------
 man2/timerfd_create.2        | 11 ++++-------
 man2/utimensat.2             | 14 ++++----------
 man3/mq_receive.3            | 14 ++++----------
 man3/mq_send.3               | 14 ++++----------
 man3/pthread_tryjoin_np.3    | 16 +++++-----------
 man3/sem_wait.3              | 15 ++++-----------
 15 files changed, 55 insertions(+), 154 deletions(-)

diff --git a/man2/clock_getres.2 b/man2/clock_getres.2
index c2bb492b9..6de2791ef 100644
--- a/man2/clock_getres.2
+++ b/man2/clock_getres.2
@@ -86,18 +86,8 @@ The
 and
 .I tp
 arguments are
-.I timespec
-structures, as specified in
-.IR <time.h> :
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t   tv_sec;        /* seconds */
-    long     tv_nsec;       /* nanoseconds */
-};
-.EE
-.in
+.BR timespec (3)
+structures.
 .PP
 The
 .I clockid
@@ -539,6 +529,7 @@ main(int argc, char *argv[])
 .BR ftime (3),
 .BR pthread_getcpuclockid (3),
 .BR sysconf (3),
+.BR timespec (3),
 .BR time (7),
 .BR time_namespaces (7),
 .BR vdso (7),
diff --git a/man2/clock_nanosleep.2 b/man2/clock_nanosleep.2
index b8c4afc2c..d70094da2 100644
--- a/man2/clock_nanosleep.2
+++ b/man2/clock_nanosleep.2
@@ -58,17 +58,8 @@ and in allowing the sleep interval to be specified as
 either an absolute or a relative value.
 .PP
 The time values passed to and returned by this call are specified using
-.I timespec
-structures, defined as follows:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds [0 .. 999999999] */
-};
-.EE
-.in
+.BR timespec (3)
+structures.
 .PP
 The
 .I clockid
@@ -272,5 +263,6 @@ shall have no effect on a thread that is blocked on a relative
 .BR restart_syscall (2),
 .BR timer_create (2),
 .BR sleep (3),
+.BR timespec (3),
 .BR usleep (3),
 .BR time (7)
diff --git a/man2/io_getevents.2 b/man2/io_getevents.2
index 7c7e625bf..0debff211 100644
--- a/man2/io_getevents.2
+++ b/man2/io_getevents.2
@@ -41,16 +41,9 @@ up to \fInr\fP events from the completion queue of the AIO context
 specified by \fIctx_id\fP.
 .PP
 The \fItimeout\fP argument specifies the amount of time to wait for events,
-and is specified as a relative timeout in a structure of the following form:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;      /* seconds */
-    long   tv_nsec;     /* nanoseconds [0 .. 999999999] */
-};
-.EE
-.in
+and is specified as a relative timeout in a
+.BR timespec (3)
+structure.
 .PP
 The specified time will be rounded up to the system clock granularity
 and is guaranteed not to expire early.
@@ -134,6 +127,7 @@ may cause a segmentation fault instead of generating the error
 .BR io_destroy (2),
 .BR io_setup (2),
 .BR io_submit (2),
+.BR timespec (3),
 .BR aio (7),
 .BR time (7)
 .\" .SH AUTHOR
diff --git a/man2/nanosleep.2 b/man2/nanosleep.2
index 89d8577db..2484223e0 100644
--- a/man2/nanosleep.2
+++ b/man2/nanosleep.2
@@ -76,19 +76,10 @@ can then be used to call
 .BR nanosleep ()
 again and complete the specified pause (but see NOTES).
 .PP
-The structure
-.I timespec
+The
+.BR timespec (3)
+structure
 is used to specify intervals of time with nanosecond precision.
-It is defined as follows:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
-};
-.EE
-.in
 .PP
 The value of the nanoseconds field must be in the range 0 to 999999999.
 .PP
@@ -237,5 +228,6 @@ This problem is fixed in Linux 2.6.0 and later kernels.
 .BR sched_setscheduler (2),
 .BR timer_create (2),
 .BR sleep (3),
+.BR timespec (3),
 .BR usleep (3),
 .BR time (7)
diff --git a/man2/poll.2 b/man2/poll.2
index 205468f3e..12c181f9c 100644
--- a/man2/poll.2
+++ b/man2/poll.2
@@ -324,16 +324,9 @@ The
 argument specifies an upper limit on the amount of time that
 .BR ppoll ()
 will block.
-This argument is a pointer to a structure of the following form:
-.PP
-.in +4n
-.EX
-struct timespec {
-    long    tv_sec;         /* seconds */
-    long    tv_nsec;        /* nanoseconds */
-};
-.EE
-.in
+This argument is a pointer to a
+.BR timespec (3)
+structure.
 .PP
 If
 .I tmo_p
@@ -659,5 +652,6 @@ main(int argc, char *argv[])
 .BR restart_syscall (2),
 .BR select (2),
 .BR select_tut (2),
+.BR timespec (3),
 .BR epoll (7),
 .BR time (7)
diff --git a/man2/sched_rr_get_interval.2 b/man2/sched_rr_get_interval.2
index 93db938df..965a140bf 100644
--- a/man2/sched_rr_get_interval.2
+++ b/man2/sched_rr_get_interval.2
@@ -38,7 +38,7 @@ sched_rr_get_interval \- get the SCHED_RR interval for the named process
 .SH DESCRIPTION
 .BR sched_rr_get_interval ()
 writes into the
-.I timespec
+.BR timespec (3)
 structure pointed to by
 .I tp
 the round-robin time quantum for the process identified by
@@ -47,19 +47,6 @@ The specified process should be running under the
 .B SCHED_RR
 scheduling policy.
 .PP
-The
-.I timespec
-structure has the following form:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;    /* seconds */
-    long   tv_nsec;   /* nanoseconds */
-};
-.EE
-.in
-.PP
 If
 .I pid
 is zero, the time quantum for the calling process is written into
@@ -132,4 +119,5 @@ Writing 0 to this file resets the quantum to the default value.
 .\" ENOSYS, because SCHED_RR has not yet been fully implemented and tested
 .\" properly.
 .SH SEE ALSO
+.BR timespec (3),
 .BR sched (7)
diff --git a/man2/select.2 b/man2/select.2
index aee25c52c..351597314 100644
--- a/man2/select.2
+++ b/man2/select.2
@@ -353,16 +353,9 @@ struct timeval {
 .PP
 The corresponding argument for
 .BR pselect ()
-has the following type:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t      tv_sec;         /* seconds */
-    long        tv_nsec;        /* nanoseconds */
-};
-.EE
-.in
+is a
+.BR timespec (3)
+structure.
 .PP
 On Linux,
 .BR select ()
@@ -761,6 +754,7 @@ main(void)
 .BR send (2),
 .BR sigprocmask (2),
 .BR write (2),
+.BR timespec (3),
 .BR epoll (7),
 .BR time (7)
 .PP
diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
index 00bc50485..c5a2c36c7 100644
--- a/man2/sigwaitinfo.2
+++ b/man2/sigwaitinfo.2
@@ -88,16 +88,9 @@ the thread is suspended waiting for a signal.
 (This interval will be rounded up to the system clock granularity,
 and kernel scheduling delays mean that the interval
 may overrun by a small amount.)
-This argument is of the following type:
-.PP
-.in +4n
-.EX
-struct timespec {
-    long    tv_sec;         /* seconds */
-    long    tv_nsec;        /* nanoseconds */
-}
-.EE
-.in
+This argument is a
+.BR timespec (3)
+structure.
 .PP
 If both fields of this structure are specified as 0, a poll is performed:
 .BR sigtimedwait ()
@@ -248,5 +241,6 @@ when the kernel provides it.
 .BR sigqueue (3),
 .BR sigsetops (3),
 .BR sigwait (3),
+.BR timespec (3),
 .BR signal (7),
 .BR time (7)
diff --git a/man2/timer_settime.2 b/man2/timer_settime.2
index 10687b211..5a9f3576a 100644
--- a/man2/timer_settime.2
+++ b/man2/timer_settime.2
@@ -65,11 +65,6 @@ structure is defined as follows:
 .PP
 .in +4n
 .EX
-struct timespec {
-    time_t tv_sec;                /* Seconds */
-    long   tv_nsec;               /* Nanoseconds */
-};
-
 struct itimerspec {
     struct timespec it_interval;  /* Timer interval */
     struct timespec it_value;     /* Initial expiration */
@@ -80,7 +75,7 @@ struct itimerspec {
 Each of the substructures of the
 .I itimerspec
 structure is a
-.I timespec
+.BR timespec (3)
 structure that allows a time value to be specified
 in seconds and nanoseconds.
 These time values are measured according to the clock
@@ -214,4 +209,5 @@ See
 .SH SEE ALSO
 .BR timer_create (2),
 .BR timer_getoverrun (2),
+.BR timespec (3),
 .BR time (7)
diff --git a/man2/timerfd_create.2 b/man2/timerfd_create.2
index 65fdfcc45..31b3d524b 100644
--- a/man2/timerfd_create.2
+++ b/man2/timerfd_create.2
@@ -152,16 +152,12 @@ argument specifies the initial expiration and interval for the timer.
 The
 .I itimerspec
 structure used for this argument contains two fields,
-each of which is in turn a structure of type
-.IR timespec :
+each of which is in turn a
+.BR timespec (3)
+structure:
 .PP
 .in +4n
 .EX
-struct timespec {
-    time_t tv_sec;                /* Seconds */
-    long   tv_nsec;               /* Nanoseconds */
-};
-
 struct itimerspec {
     struct timespec it_interval;  /* Interval for periodic timer */
     struct timespec it_value;     /* Initial expiration */
@@ -722,5 +718,6 @@ main(int argc, char *argv[])
 .BR timer_create (2),
 .BR timer_gettime (2),
 .BR timer_settime (2),
+.BR timespec (3),
 .BR epoll (7),
 .BR time (7)
diff --git a/man2/utimensat.2 b/man2/utimensat.2
index cb5f6b693..a1ff452ca 100644
--- a/man2/utimensat.2
+++ b/man2/utimensat.2
@@ -88,16 +88,9 @@ Each of the elements of
 .I times
 specifies a time as the number of seconds and nanoseconds
 since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
-This information is conveyed in a structure of the following form:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
-};
-.EE
-.in
+This information is conveyed in a
+.BR timespec (3)
+structure.
 .PP
 Updated file timestamps are set to the greatest value
 supported by the filesystem that is not greater than the specified time.
@@ -629,6 +622,7 @@ instead checks whether the
 .BR stat (2),
 .BR utimes (2),
 .BR futimes (3),
+.BR timespec (3),
 .BR inode (7),
 .BR path_resolution (7),
 .BR symlink (7)
diff --git a/man3/mq_receive.3 b/man3/mq_receive.3
index df463297d..c68949b9c 100644
--- a/man3/mq_receive.3
+++ b/man3/mq_receive.3
@@ -92,16 +92,9 @@ flag is not enabled for the message queue description, then
 points to a structure which specifies how long the call will block.
 This value is an absolute timeout in seconds and nanoseconds
 since the Epoch, 1970-01-01 00:00:00 +0000 (UTC),
-specified in the following structure:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
-};
-.EE
-.in
+specified in a
+.BR timespec (3)
+structure.
 .PP
 If no message is available,
 and the timeout has already expired by the time of the call,
@@ -183,5 +176,6 @@ is a library function layered on top of that system call.
 .BR mq_open (3),
 .BR mq_send (3),
 .BR mq_unlink (3),
+.BR timespec (3),
 .BR mq_overview (7),
 .BR time (7)
diff --git a/man3/mq_send.3 b/man3/mq_send.3
index 54999f440..df5451555 100644
--- a/man3/mq_send.3
+++ b/man3/mq_send.3
@@ -101,16 +101,9 @@ flag is not enabled for the message queue description, then
 points to a structure which specifies how long the call will block.
 This value is an absolute timeout in seconds and nanoseconds
 since the Epoch, 1970-01-01 00:00:00 +0000 (UTC),
-specified in the following structure:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;        /* seconds */
-    long   tv_nsec;       /* nanoseconds */
-};
-.EE
-.in
+specified in a
+.BR timespec (3)
+structure.
 .PP
 If the message queue is full,
 and the timeout has already expired by the time of the call,
@@ -191,5 +184,6 @@ is a library function layered on top of that system call.
 .BR mq_open (3),
 .BR mq_receive (3),
 .BR mq_unlink (3),
+.BR timespec (3),
 .BR mq_overview (7),
 .BR time (7)
diff --git a/man3/pthread_tryjoin_np.3 b/man3/pthread_tryjoin_np.3
index e912f8e3b..98a81a1da 100644
--- a/man3/pthread_tryjoin_np.3
+++ b/man3/pthread_tryjoin_np.3
@@ -72,18 +72,11 @@ terminates,
 the call returns an error.
 The
 .I abstime
-argument is a structure of the following form,
+argument is a
+.BR timespec (3)
+structure,
 specifying an absolute time measured since the Epoch (see
-.BR time (2)):
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;     /* seconds */
-    long   tv_nsec;    /* nanoseconds */
-};
-.EE
-.in
+.BR time (2)).
 .SH RETURN VALUE
 On success,
 these functions return 0;
@@ -178,4 +171,5 @@ if (s != 0) {
 .BR clock_gettime (2),
 .BR pthread_exit (3),
 .BR pthread_join (3),
+.BR timespec (3),
 .BR pthreads (7)
diff --git a/man3/sem_wait.3 b/man3/sem_wait.3
index bc7988a1a..bc8f0c725 100644
--- a/man3/sem_wait.3
+++ b/man3/sem_wait.3
@@ -76,18 +76,10 @@ specifies a limit on the amount of time that the call
 should block if the decrement cannot be immediately performed.
 The
 .I abs_timeout
-argument points to a structure that specifies an absolute timeout
+argument points to a
+.BR timespec (3)
+structure that specifies an absolute timeout
 in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
-This structure is defined as follows:
-.PP
-.in +4n
-.EX
-struct timespec {
-    time_t tv_sec;      /* Seconds */
-    long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */
-};
-.EE
-.in
 .PP
 If the timeout has already expired by the time of the call,
 and the semaphore could not be locked immediately,
@@ -270,5 +262,6 @@ main(int argc, char *argv[])
 .BR clock_gettime (2),
 .BR sem_getvalue (3),
 .BR sem_post (3),
+.BR timespec (3),
 .BR sem_overview (7),
 .BR time (7)
-- 
2.30.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [PATCH v2 2/4] system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range
  2021-12-06 20:11         ` [PATCH v2 0/4] timespec(3) migration наб
  2021-12-06 20:12           ` [PATCH v2 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct timespec declarations with "timespec(3) structure" references наб
@ 2021-12-06 20:12           ` наб
  2021-12-06 21:18             ` Alejandro Colomar (man-pages)
  2021-12-06 20:12           ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
  2021-12-06 20:12           ` [PATCH v2 4/4] system_data_types.7: note that struct timespec::tv_nsec being long long on x32 is an extension наб
  3 siblings, 1 reply; 31+ messages in thread
From: наб @ 2021-12-06 20:12 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man, Michael Kerrisk (man-pages)

[-- Attachment #1: Type: text/plain, Size: 547 bytes --]

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man7/system_data_types.7 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index d117b1d2b..1e6a3f74c 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1544,7 +1544,7 @@ or
 .EX
 struct timespec {
     time_t  tv_sec;  /* Seconds */
-    long    tv_nsec; /* Nanoseconds */
+    long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
 };
 .EE
 .PP
-- 
2.30.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-12-06 20:11         ` [PATCH v2 0/4] timespec(3) migration наб
  2021-12-06 20:12           ` [PATCH v2 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct timespec declarations with "timespec(3) structure" references наб
  2021-12-06 20:12           ` [PATCH v2 2/4] system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
@ 2021-12-06 20:12           ` наб
  2021-12-06 21:30             ` Alejandro Colomar (man-pages)
  2021-12-06 20:12           ` [PATCH v2 4/4] system_data_types.7: note that struct timespec::tv_nsec being long long on x32 is an extension наб
  3 siblings, 1 reply; 31+ messages in thread
From: наб @ 2021-12-06 20:12 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man, Michael Kerrisk (man-pages)

[-- Attachment #1: Type: text/plain, Size: 1960 bytes --]

There are three files that govern userspace struct timespec on glibc:
1. bits/wordsize.h, defining:
   (a) __WORDSIZE to 32 on ILP32 and 64 on LP64
   (b) on x32: __SYSCALL_WORDSIZE to 64
2. bits/timesize.h, defining
   (a) __TIMESIZE to __WORDSIZE, except on x32 where it's 64
3. bits/types/struct_timespec.h, declaring struct timespec as:
     struct timespec
     {
      __time_t tv_sec;      /* Seconds.  */
     #if __WORDSIZE == 64 \
      || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
      || __TIMESIZE == 32
      __syscall_slong_t tv_nsec;    /* Nanoseconds.  */
     #else
     # if __BYTE_ORDER == __BIG_ENDIAN
      int: 32;           /* Padding.  */
      long int tv_nsec;  /* Nanoseconds.  */
     # else
      long int tv_nsec;  /* Nanoseconds.  */
      int: 32;           /* Padding.  */
     # endif
     #endif
     };
   this has two side-effects: struct timespec
   (a) is always sizeof==time_t+8, and
   (b) has tv_nsec as __syscall_slong_t
       *and* !is_same<__syscall_slong_t, long>
       if using LP64 syscalls on an ILP32 system, i.e. on x32.

This means, that the simplified
  struct timespec {
      time_t  tv_sec;  /* Seconds */
      long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
  };
declaration is *invalid* for x32,
where struct timespec::tv_nsec is an int64_t (long long).

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man7/system_data_types.7 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index 1e6a3f74c..80679b180 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1544,7 +1544,11 @@ or
 .EX
 struct timespec {
     time_t  tv_sec;  /* Seconds */
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
     long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
+#else
+    long long tv_nsec;
+#endif
 };
 .EE
 .PP
-- 
2.30.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [PATCH v2 4/4] system_data_types.7: note that struct timespec::tv_nsec being long long on x32 is an extension
  2021-12-06 20:11         ` [PATCH v2 0/4] timespec(3) migration наб
                             ` (2 preceding siblings ...)
  2021-12-06 20:12           ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
@ 2021-12-06 20:12           ` наб
  3 siblings, 0 replies; 31+ messages in thread
From: наб @ 2021-12-06 20:12 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man, Michael Kerrisk (man-pages)

[-- Attachment #1: Type: text/plain, Size: 567 bytes --]

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man7/system_data_types.7 | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index 80679b180..a64a9c55f 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1556,6 +1556,9 @@ Describes times in seconds and nanoseconds.
 .PP
 .IR "Conforming to" :
 C11 and later; POSIX.1-2001 and later.
+The 64-bit
+.I tv_nsec
+on x32 is an extension.
 .PP
 .IR "See also" :
 .BR clock_gettime (2),
-- 
2.30.2

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct timespec declarations with "timespec(3) structure" references
  2021-12-06 20:12           ` [PATCH v2 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct timespec declarations with "timespec(3) structure" references наб
@ 2021-12-06 21:14             ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-06 21:14 UTC (permalink / raw)
  To: наб; +Cc: linux-man, Michael Kerrisk (man-pages)

Hi наб,

On 12/6/21 21:12, наб wrote:
> Also stripped "as specified in <time.h>" from clock_getres.2,
> as it already lives in time.h
> 
> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>

Nice.  I shortened the title, if you don't mind.  Instead of the many 
pages, I used "Many pages", so that it remains a one liner.  Since there 
are too many pages involved, we only care about the fact that we 
replaced that pattern in all pages that had it, and not that much about 
which pages had it, I think.  Yes?

Patch applied to my tree.

Thanks,

Alex

> ---
>   man2/clock_getres.2          | 15 +++------------
>   man2/clock_nanosleep.2       | 14 +++-----------
>   man2/io_getevents.2          | 14 ++++----------
>   man2/nanosleep.2             | 16 ++++------------
>   man2/poll.2                  | 14 ++++----------
>   man2/sched_rr_get_interval.2 | 16 ++--------------
>   man2/select.2                | 14 ++++----------
>   man2/sigwaitinfo.2           | 14 ++++----------
>   man2/timer_settime.2         |  8 ++------
>   man2/timerfd_create.2        | 11 ++++-------
>   man2/utimensat.2             | 14 ++++----------
>   man3/mq_receive.3            | 14 ++++----------
>   man3/mq_send.3               | 14 ++++----------
>   man3/pthread_tryjoin_np.3    | 16 +++++-----------
>   man3/sem_wait.3              | 15 ++++-----------
>   15 files changed, 55 insertions(+), 154 deletions(-)
> 
> diff --git a/man2/clock_getres.2 b/man2/clock_getres.2
> index c2bb492b9..6de2791ef 100644
> --- a/man2/clock_getres.2
> +++ b/man2/clock_getres.2
> @@ -86,18 +86,8 @@ The
>   and
>   .I tp
>   arguments are
> -.I timespec
> -structures, as specified in
> -.IR <time.h> :
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t   tv_sec;        /* seconds */
> -    long     tv_nsec;       /* nanoseconds */
> -};
> -.EE
> -.in
> +.BR timespec (3)
> +structures.
>   .PP
>   The
>   .I clockid
> @@ -539,6 +529,7 @@ main(int argc, char *argv[])
>   .BR ftime (3),
>   .BR pthread_getcpuclockid (3),
>   .BR sysconf (3),
> +.BR timespec (3),
>   .BR time (7),
>   .BR time_namespaces (7),
>   .BR vdso (7),
> diff --git a/man2/clock_nanosleep.2 b/man2/clock_nanosleep.2
> index b8c4afc2c..d70094da2 100644
> --- a/man2/clock_nanosleep.2
> +++ b/man2/clock_nanosleep.2
> @@ -58,17 +58,8 @@ and in allowing the sleep interval to be specified as
>   either an absolute or a relative value.
>   .PP
>   The time values passed to and returned by this call are specified using
> -.I timespec
> -structures, defined as follows:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds [0 .. 999999999] */
> -};
> -.EE
> -.in
> +.BR timespec (3)
> +structures.
>   .PP
>   The
>   .I clockid
> @@ -272,5 +263,6 @@ shall have no effect on a thread that is blocked on a relative
>   .BR restart_syscall (2),
>   .BR timer_create (2),
>   .BR sleep (3),
> +.BR timespec (3),
>   .BR usleep (3),
>   .BR time (7)
> diff --git a/man2/io_getevents.2 b/man2/io_getevents.2
> index 7c7e625bf..0debff211 100644
> --- a/man2/io_getevents.2
> +++ b/man2/io_getevents.2
> @@ -41,16 +41,9 @@ up to \fInr\fP events from the completion queue of the AIO context
>   specified by \fIctx_id\fP.
>   .PP
>   The \fItimeout\fP argument specifies the amount of time to wait for events,
> -and is specified as a relative timeout in a structure of the following form:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;      /* seconds */
> -    long   tv_nsec;     /* nanoseconds [0 .. 999999999] */
> -};
> -.EE
> -.in
> +and is specified as a relative timeout in a
> +.BR timespec (3)
> +structure.
>   .PP
>   The specified time will be rounded up to the system clock granularity
>   and is guaranteed not to expire early.
> @@ -134,6 +127,7 @@ may cause a segmentation fault instead of generating the error
>   .BR io_destroy (2),
>   .BR io_setup (2),
>   .BR io_submit (2),
> +.BR timespec (3),
>   .BR aio (7),
>   .BR time (7)
>   .\" .SH AUTHOR
> diff --git a/man2/nanosleep.2 b/man2/nanosleep.2
> index 89d8577db..2484223e0 100644
> --- a/man2/nanosleep.2
> +++ b/man2/nanosleep.2
> @@ -76,19 +76,10 @@ can then be used to call
>   .BR nanosleep ()
>   again and complete the specified pause (but see NOTES).
>   .PP
> -The structure
> -.I timespec
> +The
> +.BR timespec (3)
> +structure
>   is used to specify intervals of time with nanosecond precision.
> -It is defined as follows:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> -};
> -.EE
> -.in
>   .PP
>   The value of the nanoseconds field must be in the range 0 to 999999999.
>   .PP
> @@ -237,5 +228,6 @@ This problem is fixed in Linux 2.6.0 and later kernels.
>   .BR sched_setscheduler (2),
>   .BR timer_create (2),
>   .BR sleep (3),
> +.BR timespec (3),
>   .BR usleep (3),
>   .BR time (7)
> diff --git a/man2/poll.2 b/man2/poll.2
> index 205468f3e..12c181f9c 100644
> --- a/man2/poll.2
> +++ b/man2/poll.2
> @@ -324,16 +324,9 @@ The
>   argument specifies an upper limit on the amount of time that
>   .BR ppoll ()
>   will block.
> -This argument is a pointer to a structure of the following form:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    long    tv_sec;         /* seconds */
> -    long    tv_nsec;        /* nanoseconds */
> -};
> -.EE
> -.in
> +This argument is a pointer to a
> +.BR timespec (3)
> +structure.
>   .PP
>   If
>   .I tmo_p
> @@ -659,5 +652,6 @@ main(int argc, char *argv[])
>   .BR restart_syscall (2),
>   .BR select (2),
>   .BR select_tut (2),
> +.BR timespec (3),
>   .BR epoll (7),
>   .BR time (7)
> diff --git a/man2/sched_rr_get_interval.2 b/man2/sched_rr_get_interval.2
> index 93db938df..965a140bf 100644
> --- a/man2/sched_rr_get_interval.2
> +++ b/man2/sched_rr_get_interval.2
> @@ -38,7 +38,7 @@ sched_rr_get_interval \- get the SCHED_RR interval for the named process
>   .SH DESCRIPTION
>   .BR sched_rr_get_interval ()
>   writes into the
> -.I timespec
> +.BR timespec (3)
>   structure pointed to by
>   .I tp
>   the round-robin time quantum for the process identified by
> @@ -47,19 +47,6 @@ The specified process should be running under the
>   .B SCHED_RR
>   scheduling policy.
>   .PP
> -The
> -.I timespec
> -structure has the following form:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;    /* seconds */
> -    long   tv_nsec;   /* nanoseconds */
> -};
> -.EE
> -.in
> -.PP
>   If
>   .I pid
>   is zero, the time quantum for the calling process is written into
> @@ -132,4 +119,5 @@ Writing 0 to this file resets the quantum to the default value.
>   .\" ENOSYS, because SCHED_RR has not yet been fully implemented and tested
>   .\" properly.
>   .SH SEE ALSO
> +.BR timespec (3),
>   .BR sched (7)
> diff --git a/man2/select.2 b/man2/select.2
> index aee25c52c..351597314 100644
> --- a/man2/select.2
> +++ b/man2/select.2
> @@ -353,16 +353,9 @@ struct timeval {
>   .PP
>   The corresponding argument for
>   .BR pselect ()
> -has the following type:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t      tv_sec;         /* seconds */
> -    long        tv_nsec;        /* nanoseconds */
> -};
> -.EE
> -.in
> +is a
> +.BR timespec (3)
> +structure.
>   .PP
>   On Linux,
>   .BR select ()
> @@ -761,6 +754,7 @@ main(void)
>   .BR send (2),
>   .BR sigprocmask (2),
>   .BR write (2),
> +.BR timespec (3),
>   .BR epoll (7),
>   .BR time (7)
>   .PP
> diff --git a/man2/sigwaitinfo.2 b/man2/sigwaitinfo.2
> index 00bc50485..c5a2c36c7 100644
> --- a/man2/sigwaitinfo.2
> +++ b/man2/sigwaitinfo.2
> @@ -88,16 +88,9 @@ the thread is suspended waiting for a signal.
>   (This interval will be rounded up to the system clock granularity,
>   and kernel scheduling delays mean that the interval
>   may overrun by a small amount.)
> -This argument is of the following type:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    long    tv_sec;         /* seconds */
> -    long    tv_nsec;        /* nanoseconds */
> -}
> -.EE
> -.in
> +This argument is a
> +.BR timespec (3)
> +structure.
>   .PP
>   If both fields of this structure are specified as 0, a poll is performed:
>   .BR sigtimedwait ()
> @@ -248,5 +241,6 @@ when the kernel provides it.
>   .BR sigqueue (3),
>   .BR sigsetops (3),
>   .BR sigwait (3),
> +.BR timespec (3),
>   .BR signal (7),
>   .BR time (7)
> diff --git a/man2/timer_settime.2 b/man2/timer_settime.2
> index 10687b211..5a9f3576a 100644
> --- a/man2/timer_settime.2
> +++ b/man2/timer_settime.2
> @@ -65,11 +65,6 @@ structure is defined as follows:
>   .PP
>   .in +4n
>   .EX
> -struct timespec {
> -    time_t tv_sec;                /* Seconds */
> -    long   tv_nsec;               /* Nanoseconds */
> -};
> -
>   struct itimerspec {
>       struct timespec it_interval;  /* Timer interval */
>       struct timespec it_value;     /* Initial expiration */
> @@ -80,7 +75,7 @@ struct itimerspec {
>   Each of the substructures of the
>   .I itimerspec
>   structure is a
> -.I timespec
> +.BR timespec (3)
>   structure that allows a time value to be specified
>   in seconds and nanoseconds.
>   These time values are measured according to the clock
> @@ -214,4 +209,5 @@ See
>   .SH SEE ALSO
>   .BR timer_create (2),
>   .BR timer_getoverrun (2),
> +.BR timespec (3),
>   .BR time (7)
> diff --git a/man2/timerfd_create.2 b/man2/timerfd_create.2
> index 65fdfcc45..31b3d524b 100644
> --- a/man2/timerfd_create.2
> +++ b/man2/timerfd_create.2
> @@ -152,16 +152,12 @@ argument specifies the initial expiration and interval for the timer.
>   The
>   .I itimerspec
>   structure used for this argument contains two fields,
> -each of which is in turn a structure of type
> -.IR timespec :
> +each of which is in turn a
> +.BR timespec (3)
> +structure:
>   .PP
>   .in +4n
>   .EX
> -struct timespec {
> -    time_t tv_sec;                /* Seconds */
> -    long   tv_nsec;               /* Nanoseconds */
> -};
> -
>   struct itimerspec {
>       struct timespec it_interval;  /* Interval for periodic timer */
>       struct timespec it_value;     /* Initial expiration */
> @@ -722,5 +718,6 @@ main(int argc, char *argv[])
>   .BR timer_create (2),
>   .BR timer_gettime (2),
>   .BR timer_settime (2),
> +.BR timespec (3),
>   .BR epoll (7),
>   .BR time (7)
> diff --git a/man2/utimensat.2 b/man2/utimensat.2
> index cb5f6b693..a1ff452ca 100644
> --- a/man2/utimensat.2
> +++ b/man2/utimensat.2
> @@ -88,16 +88,9 @@ Each of the elements of
>   .I times
>   specifies a time as the number of seconds and nanoseconds
>   since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
> -This information is conveyed in a structure of the following form:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> -};
> -.EE
> -.in
> +This information is conveyed in a
> +.BR timespec (3)
> +structure.
>   .PP
>   Updated file timestamps are set to the greatest value
>   supported by the filesystem that is not greater than the specified time.
> @@ -629,6 +622,7 @@ instead checks whether the
>   .BR stat (2),
>   .BR utimes (2),
>   .BR futimes (3),
> +.BR timespec (3),
>   .BR inode (7),
>   .BR path_resolution (7),
>   .BR symlink (7)
> diff --git a/man3/mq_receive.3 b/man3/mq_receive.3
> index df463297d..c68949b9c 100644
> --- a/man3/mq_receive.3
> +++ b/man3/mq_receive.3
> @@ -92,16 +92,9 @@ flag is not enabled for the message queue description, then
>   points to a structure which specifies how long the call will block.
>   This value is an absolute timeout in seconds and nanoseconds
>   since the Epoch, 1970-01-01 00:00:00 +0000 (UTC),
> -specified in the following structure:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> -};
> -.EE
> -.in
> +specified in a
> +.BR timespec (3)
> +structure.
>   .PP
>   If no message is available,
>   and the timeout has already expired by the time of the call,
> @@ -183,5 +176,6 @@ is a library function layered on top of that system call.
>   .BR mq_open (3),
>   .BR mq_send (3),
>   .BR mq_unlink (3),
> +.BR timespec (3),
>   .BR mq_overview (7),
>   .BR time (7)
> diff --git a/man3/mq_send.3 b/man3/mq_send.3
> index 54999f440..df5451555 100644
> --- a/man3/mq_send.3
> +++ b/man3/mq_send.3
> @@ -101,16 +101,9 @@ flag is not enabled for the message queue description, then
>   points to a structure which specifies how long the call will block.
>   This value is an absolute timeout in seconds and nanoseconds
>   since the Epoch, 1970-01-01 00:00:00 +0000 (UTC),
> -specified in the following structure:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;        /* seconds */
> -    long   tv_nsec;       /* nanoseconds */
> -};
> -.EE
> -.in
> +specified in a
> +.BR timespec (3)
> +structure.
>   .PP
>   If the message queue is full,
>   and the timeout has already expired by the time of the call,
> @@ -191,5 +184,6 @@ is a library function layered on top of that system call.
>   .BR mq_open (3),
>   .BR mq_receive (3),
>   .BR mq_unlink (3),
> +.BR timespec (3),
>   .BR mq_overview (7),
>   .BR time (7)
> diff --git a/man3/pthread_tryjoin_np.3 b/man3/pthread_tryjoin_np.3
> index e912f8e3b..98a81a1da 100644
> --- a/man3/pthread_tryjoin_np.3
> +++ b/man3/pthread_tryjoin_np.3
> @@ -72,18 +72,11 @@ terminates,
>   the call returns an error.
>   The
>   .I abstime
> -argument is a structure of the following form,
> +argument is a
> +.BR timespec (3)
> +structure,
>   specifying an absolute time measured since the Epoch (see
> -.BR time (2)):
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;     /* seconds */
> -    long   tv_nsec;    /* nanoseconds */
> -};
> -.EE
> -.in
> +.BR time (2)).
>   .SH RETURN VALUE
>   On success,
>   these functions return 0;
> @@ -178,4 +171,5 @@ if (s != 0) {
>   .BR clock_gettime (2),
>   .BR pthread_exit (3),
>   .BR pthread_join (3),
> +.BR timespec (3),
>   .BR pthreads (7)
> diff --git a/man3/sem_wait.3 b/man3/sem_wait.3
> index bc7988a1a..bc8f0c725 100644
> --- a/man3/sem_wait.3
> +++ b/man3/sem_wait.3
> @@ -76,18 +76,10 @@ specifies a limit on the amount of time that the call
>   should block if the decrement cannot be immediately performed.
>   The
>   .I abs_timeout
> -argument points to a structure that specifies an absolute timeout
> +argument points to a
> +.BR timespec (3)
> +structure that specifies an absolute timeout
>   in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
> -This structure is defined as follows:
> -.PP
> -.in +4n
> -.EX
> -struct timespec {
> -    time_t tv_sec;      /* Seconds */
> -    long   tv_nsec;     /* Nanoseconds [0 .. 999999999] */
> -};
> -.EE
> -.in
>   .PP
>   If the timeout has already expired by the time of the call,
>   and the semaphore could not be locked immediately,
> @@ -270,5 +262,6 @@ main(int argc, char *argv[])
>   .BR clock_gettime (2),
>   .BR sem_getvalue (3),
>   .BR sem_post (3),
> +.BR timespec (3),
>   .BR sem_overview (7),
>   .BR time (7)
> 


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* Re: [PATCH v2 2/4] system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range
  2021-12-06 20:12           ` [PATCH v2 2/4] system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
@ 2021-12-06 21:18             ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-06 21:18 UTC (permalink / raw)
  To: наб; +Cc: linux-man, Michael Kerrisk (man-pages)

Hi наб,

On 12/6/21 21:12, наб wrote:
> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>

I rewrote the title:

     system_data_types.7: timespec: Add tv_nsec range to comment


Patch applied.

Thanks,
Alex


> ---
>   man7/system_data_types.7 | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
> index d117b1d2b..1e6a3f74c 100644
> --- a/man7/system_data_types.7
> +++ b/man7/system_data_types.7
> @@ -1544,7 +1544,7 @@ or
>   .EX
>   struct timespec {
>       time_t  tv_sec;  /* Seconds */
> -    long    tv_nsec; /* Nanoseconds */
> +    long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
>   };
>   .EE
>   .PP
> 


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* Re: [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-12-06 20:12           ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
@ 2021-12-06 21:30             ` Alejandro Colomar (man-pages)
  2021-12-06 22:03               ` [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability наб
  2021-12-07 11:02               ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 Stefan Puiu
  0 siblings, 2 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-06 21:30 UTC (permalink / raw)
  To: наб; +Cc: linux-man, Michael Kerrisk (man-pages)

Hi наб,

On 12/6/21 21:12, наб wrote:
> diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
> index 1e6a3f74c..80679b180 100644
> --- a/man7/system_data_types.7
> +++ b/man7/system_data_types.7
> @@ -1544,7 +1544,11 @@ or
>   .EX
>   struct timespec {
>       time_t  tv_sec;  /* Seconds */
> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>       long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
> +#else
> +    long long tv_nsec;
> +#endif

I prefer showing there the (simple) POSIX definition, and then in Notes 
add a message that glibc uses a different type on most systems. 
Otherwise, we're loosing the information that non-glibc systems use long.

How about something like the following?:

Notes: glibc uses long long instead of long for tv_nsec in some 
architectures:

	#if !(__x86_64__ && __ILP32__ /* == x32 */)
		long      tv_nsec;
	#else
		long long tv_nsec;
	#endif


BTW, I don't understand why long long, if long can perfectly represent 0 
.. 999999999.  If you know the rationale for such extension, it would be 
a great addition to Notes too.

Thanks!

Alex

>   };
>   .EE
>   .PP
> 


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-06 21:30             ` Alejandro Colomar (man-pages)
@ 2021-12-06 22:03               ` наб
  2021-12-06 22:56                 ` Alejandro Colomar (man-pages)
  2021-12-07 11:02               ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 Stefan Puiu
  1 sibling, 1 reply; 31+ messages in thread
From: наб @ 2021-12-06 22:03 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man, Michael Kerrisk (man-pages)

[-- Attachment #1: Type: text/plain, Size: 2965 bytes --]

There are three files that govern userspace struct timespec on glibc:
1. bits/wordsize.h, defining:
   (a) __WORDSIZE to 32 on ILP32 and 64 on LP64
   (b) on x32: __SYSCALL_WORDSIZE to 64
2. bits/timesize.h, defining
   (a) __TIMESIZE to __WORDSIZE, except on x32 where it's 64
3. bits/types/struct_timespec.h, declaring struct timespec as:
     struct timespec
     {
      __time_t tv_sec;      /* Seconds.  */
     #if __WORDSIZE == 64 \
      || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
      || __TIMESIZE == 32
      __syscall_slong_t tv_nsec;    /* Nanoseconds.  */
     #else
     # if __BYTE_ORDER == __BIG_ENDIAN
      int: 32;           /* Padding.  */
      long int tv_nsec;  /* Nanoseconds.  */
     # else
      long int tv_nsec;  /* Nanoseconds.  */
      int: 32;           /* Padding.  */
     # endif
     #endif
     };
   this has two side-effects: struct timespec
   (a) is always sizeof==time_t+8, and
   (b) has tv_nsec as __syscall_slong_t
       *and* !is_same<__syscall_slong_t, long>
       if using LP64 syscalls on an ILP32 system, i.e. on x32.

This means, that the simplified
  struct timespec {
      time_t  tv_sec;  /* Seconds */
      long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
  };
declaration is *invalid* for x32,
where struct timespec::tv_nsec is an int64_t (long long).

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
The reasoning is explained in the commit message,
but I elucidated it in a more approachable way in the Notes,
which also include the link from Jakub Wilk upthread.

Nevertheless, log2(10^(3*3) - 1) <= 31 is a good point!
I also added this as a slight portability guide toward the end.

This replaces 3/4 and 4/4.

 man7/system_data_types.7 | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index 1e6a3f74c..cce17fc3e 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1553,6 +1553,36 @@ Describes times in seconds and nanoseconds.
 .IR "Conforming to" :
 C11 and later; POSIX.1-2001 and later.
 .PP
+.IR Notes :
+.I tv_nsec
+is the
+.I syscall
+long, though this affects only fringe architectures like X32,
+which is ILP32, but uses the LP64 AMD64 syscall ABI.
+.br
+In reality, the field ends up being defined as:
+.EX
+.in +4
+#if !(__x86_64__ && __ILP32__ /* == x32 */)
+    long      tv_nsec;
+#else
+    long long tv_nsec;
+#endif
+.in
+.EE
+.PP
+This is a long-standing and long-enshrined
+.UR https://sourceware.org/bugzilla/show_bug.cgi?id=16437
+glibc bug
+.I #16437
+.UE ,
+an incompatible extension to the standards;
+however, as even a 32-bit
+.I long
+can hold the entire
+.I tv_nsec
+range, it's safe to forcibly down-cast it to the standard type.
+.PP
 .IR "See also" :
 .BR clock_gettime (2),
 .BR clock_nanosleep (2),
-- 
2.30.2

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-06 22:03               ` [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability наб
@ 2021-12-06 22:56                 ` Alejandro Colomar (man-pages)
  2021-12-06 23:31                   ` наб
  0 siblings, 1 reply; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-06 22:56 UTC (permalink / raw)
  To: наб, Jakub Wilk, Libc-alpha
  Cc: linux-man, Michael Kerrisk (man-pages)

[CC += Jakub, glibc]

Hi наб (and other readers),

On 12/6/21 23:03, наб wrote:
> There are three files that govern userspace struct timespec on glibc:
> 1. bits/wordsize.h, defining:
>     (a) __WORDSIZE to 32 on ILP32 and 64 on LP64
>     (b) on x32: __SYSCALL_WORDSIZE to 64
> 2. bits/timesize.h, defining
>     (a) __TIMESIZE to __WORDSIZE, except on x32 where it's 64
> 3. bits/types/struct_timespec.h, declaring struct timespec as:
>       struct timespec
>       {
>        __time_t tv_sec;      /* Seconds.  */
>       #if __WORDSIZE == 64 \
>        || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
>        || __TIMESIZE == 32
>        __syscall_slong_t tv_nsec;    /* Nanoseconds.  */
>       #else
>       # if __BYTE_ORDER == __BIG_ENDIAN
>        int: 32;           /* Padding.  */
>        long int tv_nsec;  /* Nanoseconds.  */
>       # else
>        long int tv_nsec;  /* Nanoseconds.  */
>        int: 32;           /* Padding.  */
>       # endif
>       #endif
>       };
>     this has two side-effects: struct timespec
>     (a) is always sizeof==time_t+8, and
>     (b) has tv_nsec as __syscall_slong_t
>         *and* !is_same<__syscall_slong_t, long>
>         if using LP64 syscalls on an ILP32 system, i.e. on x32.
> 
> This means, that the simplified
>    struct timespec {
>        time_t  tv_sec;  /* Seconds */
>        long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
>    };
> declaration is *invalid* for x32,
> where struct timespec::tv_nsec is an int64_t (long long).
> 
> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
> ---
> The reasoning is explained in the commit message,
> but I elucidated it in a more approachable way in the Notes,
> which also include the link from Jakub Wilk upthread.
> 

I (more or less) understand the deduction of why that happens on certain 
systems,  what I was wondering is if there's an intention behind that, 
or if it's just an accident.  Why not just use plain 'long' always as 
POSIX says it should be.  I don't see the feature part of this bug.

> Nevertheless, log2(10^(3*3) - 1) <= 31 is a good point!

Yes, that's what I really don't understand.  'long' is at least 32 bits, 
which is enough for 1G.  Was there ever a good reason for glibc to use 
64 bits?  It seems like a wrong decision that is maintained for 
consistency.  If that's it I'm in favor of mentioning it in a Bugs 
section (as Jakub proposed), instead of a Notes section.  Maybe someone 
from glibc may give a rationale for this deviation from POSIX.

> I also added this as a slight portability guide toward the end.

Nice.

> 
> This replaces 3/4 and 4/4.
> 
Okay.


>   man7/system_data_types.7 | 30 ++++++++++++++++++++++++++++++
>   1 file changed, 30 insertions(+)
> 
> diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
> index 1e6a3f74c..cce17fc3e 100644
> --- a/man7/system_data_types.7
> +++ b/man7/system_data_types.7
> @@ -1553,6 +1553,36 @@ Describes times in seconds and nanoseconds.
>   .IR "Conforming to" :
>   C11 and later; POSIX.1-2001 and later.
>   .PP
> +.IR Notes :
> +.I tv_nsec
> +is the
> +.I syscall
> +long, though this affects only fringe architectures like X32,
> +which is ILP32, but uses the LP64 AMD64 syscall ABI.

I'd add an explicit mention that this is for glibc, since it deviates 
from the "Conforming to".  Maybe preceding the paragraph with "In/On (I 
never knew if there goes in or on) glibc," would do.

> +.br

We don't use '.br'.  In this case I think just continuing in the same 
paragraph would be fine (i.e., no break at all).

> +In reality, the field ends up being defined as:

Here I'd add a blank line with '.PP'.

> +.EX
> +.in +4

Please, revert the order of .in and .EX.
It's meaningless, but I prefer consistency.  See man-pages(7), which 
shows this order, and also the following:

$ grep -rn '^\.EX$' -A1 man? | grep '\.in' | wc -l
2
$ grep -rn '^\.EX$' -B1 man? | grep '\.in' | wc -l
1048


One of those 2 cases was this patch.

> +#if !(__x86_64__ && __ILP32__ /* == x32 */)

Now I notice:

Shouldn't this use defined()?

#if !(defined(__x86_64__) && defined(__ILP32__) /* == x32 */)

Also, I prefer to avoid complexity in mentally parsing the ifs, so I'd 
reorder it to remove the negation:

#if defined(__x86_64__) && defined(__ILP32__)  /* == x32 */
	long long tv_nsec;
#else
	long      tv_nsec;
#endif

And also note a cosmetic minor thing: at least two spaces before a comment.


Cheers,
Alex

> +    long      tv_nsec;
> +#else
> +    long long tv_nsec;
> +#endif
> +.in
> +.EE
> +.PP
> +This is a long-standing and long-enshrined
> +.UR https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> +glibc bug
> +.I #16437
> +.UE ,
> +an incompatible extension to the standards;
> +however, as even a 32-bit
> +.I long
> +can hold the entire
> +.I tv_nsec
> +range, it's safe to forcibly down-cast it to the standard type.
> +.PP
>   .IR "See also" :
>   .BR clock_gettime (2),
>   .BR clock_nanosleep (2),
> 


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-06 22:56                 ` Alejandro Colomar (man-pages)
@ 2021-12-06 23:31                   ` наб
  2021-12-07  0:38                     ` Alejandro Colomar (man-pages)
       [not found]                     ` <a55c07d0-960f-4dfe-90bf-4fee33976198@www.fastmail.com>
  0 siblings, 2 replies; 31+ messages in thread
From: наб @ 2021-12-06 23:31 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: Jakub Wilk, Libc-alpha, linux-man, Michael Kerrisk (man-pages)

[-- Attachment #1: Type: text/plain, Size: 6210 bytes --]

On Mon, Dec 06, 2021 at 11:56:19PM +0100, Alejandro Colomar (man-pages) wrote:
> I (more or less) understand the deduction of why that happens on certain
> systems,  what I was wondering is if there's an intention behind that, or if
> it's just an accident.  Why not just use plain 'long' always as POSIX says
> it should be.  I don't see the feature part of this bug.
>
> 'long' is at least 32 bits, which
> is enough for 1G.  Was there ever a good reason for glibc to use 64 bits?  It
> seems like a wrong decision that is maintained for consistency.   If that's it
> I'm in favor of mentioning it in a Bugs section (as Jakub proposed), instead
> of a Notes section.  Maybe someone from glibc may give a rationale for this
> deviation from POSIX.
AFAICT, as you say, this isn't much more than a side-effect
of using the amd64 ABI and not being too careful with how it interacts
with the POSIX requirement (it's entirely feasible to re-wrap
a user-space timespec, or even use the bitfield trick glibc
already does to not have to do it), but then I'm far from an expert;
indeed, maybe someone with more glibc involvement will know.

Updating to Bugs for now, maybe we can downgrade later.

> I'd add an explicit mention that this is for glibc, since it deviates from
> the "Conforming to".
Fair enough, though I don't actually know if this is glibc-exclusive.
I assume it is, since I didn't find a timespec in the musl git
repository and the linux uapi header has the straight-forward
definition, but I can't be sure because I don't actually run
(well, even know of) any x32 musl systems I could verify this on.

> Maybe preceding the paragraph with "In/On (I never
> knew if there goes in or on) glibc," would do.
Out of those two: on (in would point to glibc internals),
but I'd actually go for "Under", here, since glibc is an over-arching
(literally) universe-defining context, rather than an add-on,
or something build your program on top of.

For my own curiosity: which preposition would you use in Spanish here?

> On 12/6/21 23:03, наб wrote:
> > +.br
> We don't use '.br'.  In this case I think just continuing in the same
> paragraph would be fine (i.e., no break at all).
> > +In reality, the field ends up being defined as:
> Here I'd add a blank line with '.PP'.
> > +.EX
> > +.in +4
> Please, revert the order of .in and .EX.
> It's meaningless, but I prefer consistency.  See man-pages(7), which shows
> this order, and also the following:
> 
> $ grep -rn '^\.EX$' -A1 man? | grep '\.in' | wc -l
> 2
> $ grep -rn '^\.EX$' -B1 man? | grep '\.in' | wc -l
> 1048
> 
> 
> One of those 2 cases was this patch.
Sure, sure, and sure

> > +#if !(__x86_64__ && __ILP32__ /* == x32 */)
> 
> Now I notice:
> 
> Shouldn't this use defined()?
> 
> #if !(defined(__x86_64__) && defined(__ILP32__) /* == x32 */)
Eeeeh, not really? That's functionally identical but, like,
very verbose for no good reason.

> Also, I prefer to avoid complexity in mentally parsing the ifs, so I'd
> reorder it to remove the negation:
> 
> #if defined(__x86_64__) && defined(__ILP32__)  /* == x32 */
> 	long long tv_nsec;
> #else
> 	long      tv_nsec;
> #endif
long first made more sense when this was in-line,
but I agree, non-negated is better.

> And also note a cosmetic minor thing: at least two spaces before a comment.
Sure


Updated scissor-patch below. I've also fixed some grammar errors toward
the tail-end of the (now) Bugs section.

Best,
наб

-- >8 --
There are three files that govern userspace struct timespec on glibc:
1. bits/wordsize.h, defining:
   (a) __WORDSIZE to 32 on ILP32 and 64 on LP64
   (b) on x32: __SYSCALL_WORDSIZE to 64
2. bits/timesize.h, defining
   (a) __TIMESIZE to __WORDSIZE, except on x32 where it's 64
3. bits/types/struct_timespec.h, declaring struct timespec as:
     struct timespec
     {
      __time_t tv_sec;      /* Seconds.  */
     #if __WORDSIZE == 64 \
      || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
      || __TIMESIZE == 32
      __syscall_slong_t tv_nsec;    /* Nanoseconds.  */
     #else
     # if __BYTE_ORDER == __BIG_ENDIAN
      int: 32;           /* Padding.  */
      long int tv_nsec;  /* Nanoseconds.  */
     # else
      long int tv_nsec;  /* Nanoseconds.  */
      int: 32;           /* Padding.  */
     # endif
     #endif
     };
   this has two side-effects: struct timespec
   (a) is always sizeof==time_t+8, and
   (b) has tv_nsec as __syscall_slong_t
       *and* !is_same<__syscall_slong_t, long>
       if using LP64 syscalls on an ILP32 system, i.e. on x32.

This means, that the simplified
  struct timespec {
      time_t  tv_sec;  /* Seconds */
      long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
  };
declaration is *invalid* for x32,
where struct timespec::tv_nsec is an int64_t (long long).

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man7/system_data_types.7 | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index 1e6a3f74c..66c9a5d3d 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1553,6 +1553,37 @@ Describes times in seconds and nanoseconds.
 .IR "Conforming to" :
 C11 and later; POSIX.1-2001 and later.
 .PP
+.IR Bugs :
+Under glibc,
+.I tv_nsec
+is the
+.I syscall
+long, though this affects only fringe architectures like X32,
+which is ILP32, but uses the LP64 AMD64 syscall ABI.
+In reality, the field ends up being defined as:
+.PP
+.in +4
+.EX
+#if __x86_64__ && __ILP32__  /* == x32 */
+    long long tv_nsec;
+#else
+    long      tv_nsec;
+#endif
+.EE
+.in
+.PP
+This is a long-standing and long-enshrined
+.UR https://sourceware.org/bugzilla/show_bug.cgi?id=16437
+glibc bug
+.I #16437
+.UE ,
+and an incompatible extension to the standards;
+however, as even a 32-bit
+.I long
+can hold the entire
+.I tv_nsec
+range, it's always safe to forcibly down-cast it to the standard type.
+.PP
 .IR "See also" :
 .BR clock_gettime (2),
 .BR clock_nanosleep (2),
-- 
2.30.2

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-06 23:31                   ` наб
@ 2021-12-07  0:38                     ` Alejandro Colomar (man-pages)
  2021-12-07  1:08                       ` наб
       [not found]                     ` <a55c07d0-960f-4dfe-90bf-4fee33976198@www.fastmail.com>
  1 sibling, 1 reply; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-07  0:38 UTC (permalink / raw)
  To: наб
  Cc: Jakub Wilk, Libc-alpha, linux-man, Michael Kerrisk (man-pages),
	Zack Weinberg

On 12/7/21 00:31, наб wrote:
> On Mon, Dec 06, 2021 at 11:56:19PM +0100, Alejandro Colomar (man-pages) wrote:
>> I (more or less) understand the deduction of why that happens on certain
>> systems,  what I was wondering is if there's an intention behind that, or if
>> it's just an accident.  Why not just use plain 'long' always as POSIX says
>> it should be.  I don't see the feature part of this bug.
>>
>> 'long' is at least 32 bits, which
>> is enough for 1G.  Was there ever a good reason for glibc to use 64 bits?  It
>> seems like a wrong decision that is maintained for consistency.   If that's it
>> I'm in favor of mentioning it in a Bugs section (as Jakub proposed), instead
>> of a Notes section.  Maybe someone from glibc may give a rationale for this
>> deviation from POSIX.
> AFAICT, as you say, this isn't much more than a side-effect
> of using the amd64 ABI and not being too careful with how it interacts
> with the POSIX requirement (it's entirely feasible to re-wrap
> a user-space timespec, or even use the bitfield trick glibc
> already does to not have to do it), but then I'm far from an expert;
> indeed, maybe someone with more glibc involvement will know.
> 
> Updating to Bugs for now, maybe we can downgrade later.

Sure,  I'll delay applying this patch to allow for comments.

> 
>> Maybe preceding the paragraph with "In/On (I never
>> knew if there goes in or on) glibc," would do.
> Out of those two: on (in would point to glibc internals),
> but I'd actually go for "Under", here, since glibc is an over-arching
> (literally) universe-defining context, rather than an add-on,
> or something build your program on top of.

Interesting :)

> 
> For my own curiosity: which preposition would you use in Spanish here?
> 
I would say "en" (which normally translates to "in" in English).

Under some circumstances I might use "con" ("with" in English), but it 
would be rarer.

>> On 12/6/21 23:03, наб wrote:
>>> +.br
>> We don't use '.br'.  In this case I think just continuing in the same
>> paragraph would be fine (i.e., no break at all).
>>> +In reality, the field ends up being defined as:
>> Here I'd add a blank line with '.PP'.
>>> +.EX
>>> +.in +4
>> Please, revert the order of .in and .EX.
>> It's meaningless, but I prefer consistency.  See man-pages(7), which shows
>> this order, and also the following:
>>
>> $ grep -rn '^\.EX$' -A1 man? | grep '\.in' | wc -l
>> 2
>> $ grep -rn '^\.EX$' -B1 man? | grep '\.in' | wc -l
>> 1048
>>
>>
>> One of those 2 cases was this patch.
> Sure, sure, and sure
> 
>>> +#if !(__x86_64__ && __ILP32__ /* == x32 */)
>>
>> Now I notice:
>>
>> Shouldn't this use defined()?
>>
>> #if !(defined(__x86_64__) && defined(__ILP32__) /* == x32 */)
> Eeeeh, not really? That's functionally identical but, like,
> very verbose for no good reason.

Are those defined to actual values?  Or are they defined just empty?
I thought they were empty (but have never used those macros, so don't 
know at all), in which case it would matter:


user@sqli:~/src/test$ cat defined.c
#define C
#define D

#if A && B
#warning AB
#else
#warning notAB
#endif

#if C && D
#warning CD
#else
#warning notCD
#endif
user@sqli:~/src/test$ cc -Wall -Wextra defined.c
defined.c:7:2: warning: #warning notAB [-Wcpp]
     7 | #warning notAB
       |  ^~~~~~~
defined.c:10:7: error: operator '&&' has no left operand
    10 | #if C && D
       |       ^~
defined.c:13:2: warning: #warning notCD [-Wcpp]
    13 | #warning notCD
       |  ^~~~~~~



Cheers,
Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-07  0:38                     ` Alejandro Colomar (man-pages)
@ 2021-12-07  1:08                       ` наб
  2021-12-07  1:34                         ` Alejandro Colomar (man-pages)
  0 siblings, 1 reply; 31+ messages in thread
From: наб @ 2021-12-07  1:08 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: Jakub Wilk, Libc-alpha, linux-man, Michael Kerrisk (man-pages),
	Zack Weinberg

[-- Attachment #1: Type: text/plain, Size: 1685 bytes --]

On Tue, Dec 07, 2021 at 01:38:34AM +0100, Alejandro Colomar (man-pages) wrote:
> On 12/7/21 00:31, наб wrote:
> > For my own curiosity: which preposition would you use in Spanish here?
> I would say "en" (which normally translates to "in" in English).
> 
> Under some circumstances I might use "con" ("with" in English), but it would
> be rarer.
Huh! That's neat, I wouldn't've expected it!

> > Eeeeh, not really? That's functionally identical but, like,
> > very verbose for no good reason.
> Are those defined to actual values?  Or are they defined just empty?
> I thought they were empty (but have never used those macros, so don't know
> at all), in which case it would matter:
They're either undefined (=> 0) or defined to a truthy value
(1, realistically, but you see versions in some other APIs).
It'd also be logically valid to define them to 0,
but this is rare because people do define-checks.

A "default" -D macro, like all features are, is 1,
so your test program is more accurately represented as:
-- >8 --
nabijaczleweli@tarta:~/uwu$ cat defined.c
#if A && B
#warning AB
#else
#warning notAB
#endif

#if C && D
#warning CD
#else
#warning notCD
#endif
nabijaczleweli@tarta:~/uwu$ cc -E defined.c > /dev/null
defined.c:4:2: warning: notAB [-W#warnings]
#warning notAB
 ^
defined.c:10:2: warning: notCD [-W#warnings]
#warning notCD
 ^
2 warnings generated.
nabijaczleweli@tarta:~/uwu$ cc -DA -DB -E defined.c > /dev/null
defined.c:2:2: warning: AB [-W#warnings]
#warning AB
 ^
defined.c:10:2: warning: notCD [-W#warnings]
#warning notCD
 ^
2 warnings generated.
-- >8 --

Which behaves as expected.

Best,
наб

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-07  1:08                       ` наб
@ 2021-12-07  1:34                         ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-07  1:34 UTC (permalink / raw)
  To: наб
  Cc: Jakub Wilk, Libc-alpha, linux-man, Michael Kerrisk (man-pages),
	Zack Weinberg

On 12/7/21 02:08, наб wrote:
> On Tue, Dec 07, 2021 at 01:38:34AM +0100, Alejandro Colomar (man-pages) wrote:
>> On 12/7/21 00:31, наб wrote:
>>> For my own curiosity: which preposition would you use in Spanish here?
>> I would say "en" (which normally translates to "in" in English).
>>
>> Under some circumstances I might use "con" ("with" in English), but it would
>> be rarer.
> Huh! That's neat, I wouldn't've expected it!
> 
>>> Eeeeh, not really? That's functionally identical but, like,
>>> very verbose for no good reason.
>> Are those defined to actual values?  Or are they defined just empty?
>> I thought they were empty (but have never used those macros, so don't know
>> at all), in which case it would matter:
> They're either undefined (=> 0) or defined to a truthy value
> (1, realistically, but you see versions in some other APIs).
> It'd also be logically valid to define them to 0,
> but this is rare because people do define-checks.
> 
> A "default" -D macro, like all features are, is 1,

Huh, I didn't expect that.  Good to know it.
You can see that I don't use them a lot :)

So, nothing else to add to the patch; LGTM.  I'll leave up to you to 
decide if Notes or Bugs, and will wait also until tomorrow to merge it 
to see if someone has anything to add.

Thanks a lot!

Kind regards,
Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
       [not found]                       ` <7c29781b-1030-44f9-b078-f5b09a14e321@gmail.com>
@ 2021-12-07  1:41                         ` наб
  2021-12-07 18:43                           ` Joseph Myers
  2022-01-03 15:44                           ` наб
  0 siblings, 2 replies; 31+ messages in thread
From: наб @ 2021-12-07  1:41 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: Zack Weinberg, libc-alpha, linux-man

[-- Attachment #1: Type: text/plain, Size: 5382 bytes --]

On Tue, Dec 07, 2021 at 01:52:52AM +0100, Alejandro Colomar (man-pages) wrote:
> On 12/7/21 01:18, Zack Weinberg wrote:
> > Depending on the kernel, the architecture, the ABI, and the state of _TIME_BITS, the format of `struct timespec` as expected by system calls may be any of
> > 
> > struct timespec { int32_t tv_sec; int32_t tv_nsec; };
> > struct timespec { int64_t tv_sec; int64_t tv_nsec; };
> > struct timespec { int64_t tv_sec; int32_t __padding; int32_t tv_nsec; }
> > struct timespec { int64_t tv_sec; int32_t tv_nsec; int32_t __padding; }
> > 
> > These may be incompatible with using bare `long` for tv_nsec in the user space headers.  The problem cases are when the kernel expects option 2 but user space's `long` is only 32 bits wide, or if the kernel expects option 3 or 4 when `long` is 64 bits wide and the endianness of `long` doesn't agree with the position of the padding.  I don't remember which ABIs actually manifest an incompatibility, but I remember this being discussed repeatedly during the project to make 64-bit time_t available to ILP32 ABIs.
> > 
> > The C library CANNOT paper over the incompatibility by converting formats in the syscall wrappers, because `struct timespec` objects get embedded in an unbounded set of `ioctl` parameter blocks, `sendmsg` ancillary data structures, etc. etc. etc.  We can't even make a list.
This I forgot to take into account, mea culpa!

> > Personally I consider the situation a defect in POSIX and C11; the definition of `struct timespec` should always have been
> > 
> > struct timespec { time_t tv_sec; nsec_t tv_nsec; };
> > 
> > where nsec_t is an integer type that can represent the range [0, 10**9).  Last time this came up, Joseph didn't think there was any chance of persuading either the Austin Group or WG14 to make this change, unfortunately.
Sadly, agree on both fronts.

Looking through "timespec" on Aardvark for prior art reveals nothing,
except for a likely resolution to any proposal of this sort:
> Although we agree that it would have been better if these functions had
> been designed this way to begin with, we believe that making the change
> now will break existing, conforming code with no real benefit. 

Considering this is, as outlined above, a real ABI-meets-standard moment
that affects all users of the Linux syscall ABI, I rolled back to Notes,
replaced glibc references with a "this is unfortunate but unfixable"
stanza, and a link to this post in the libc-alpha archive in the comment.

Regrettably, I think this is the best we can do,
save for committing a plan9. Scissor-patch below.

Cheers,
наб

-- >8 --
There are three files that govern userspace struct timespec on glibc:
1. bits/wordsize.h, defining:
   (a) __WORDSIZE to 32 on ILP32 and 64 on LP64
   (b) on x32: __SYSCALL_WORDSIZE to 64
2. bits/timesize.h, defining
   (a) __TIMESIZE to __WORDSIZE, except on x32 where it's 64
3. bits/types/struct_timespec.h, declaring struct timespec as:
     struct timespec
     {
      __time_t tv_sec;      /* Seconds.  */
     #if __WORDSIZE == 64 \
      || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
      || __TIMESIZE == 32
      __syscall_slong_t tv_nsec;    /* Nanoseconds.  */
     #else
     # if __BYTE_ORDER == __BIG_ENDIAN
      int: 32;           /* Padding.  */
      long int tv_nsec;  /* Nanoseconds.  */
     # else
      long int tv_nsec;  /* Nanoseconds.  */
      int: 32;           /* Padding.  */
     # endif
     #endif
     };
   this has two side-effects: struct timespec
   (a) is always sizeof==time_t+8, and
   (b) has tv_nsec as __syscall_slong_t
       *and* !is_same<__syscall_slong_t, long>
       if using LP64 syscalls on an ILP32 system, i.e. on x32.

This means, that the simplified
  struct timespec {
      time_t  tv_sec;  /* Seconds */
      long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
  };
declaration is *invalid* for x32,
where struct timespec::tv_nsec is an int64_t (long long).

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man7/system_data_types.7 | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
index 1e6a3f74c..46fcf013d 100644
--- a/man7/system_data_types.7
+++ b/man7/system_data_types.7
@@ -1553,6 +1553,36 @@ Describes times in seconds and nanoseconds.
 .IR "Conforming to" :
 C11 and later; POSIX.1-2001 and later.
 .PP
+.IR Notes :
+.I tv_nsec
+is the
+.I syscall
+long, though this affects only fringe architectures like X32,
+which is ILP32, but uses the LP64 AMD64 syscall ABI.
+In reality, the field ends up being defined as:
+.PP
+.in +4
+.EX
+#if __x86_64__ && __ILP32__  /* == x32 */
+    long long tv_nsec;
+#else
+    long      tv_nsec;
+#endif
+.EE
+.in
+.PP
+This is one of the many unfortunate side-effects of the intersection of
+.I tv_nsec
+being defined as
+.IR long ,
+and cannot be addressed while preserving backward compatibility.
+.\" https://sourceware.org/pipermail/libc-alpha/2021-December/133702.html
+However, as even a 32-bit
+.I long
+can hold the entire
+.I tv_nsec
+range, it's always safe to forcibly down-cast it to the standard type.
+.PP
 .IR "See also" :
 .BR clock_gettime (2),
 .BR clock_nanosleep (2),
-- 
2.30.2


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-12-06 21:30             ` Alejandro Colomar (man-pages)
  2021-12-06 22:03               ` [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability наб
@ 2021-12-07 11:02               ` Stefan Puiu
  2021-12-07 11:05                 ` Alejandro Colomar (man-pages)
  1 sibling, 1 reply; 31+ messages in thread
From: Stefan Puiu @ 2021-12-07 11:02 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: наб, lnx-man, Michael Kerrisk (man-pages)

Hi,

Just a little nitpick below...

On Tue, Dec 7, 2021 at 7:56 AM Alejandro Colomar (man-pages)
<alx.manpages@gmail.com> wrote:
>
> Hi наб,
>
> On 12/6/21 21:12, наб wrote:
> > diff --git a/man7/system_data_types.7 b/man7/system_data_types.7
> > index 1e6a3f74c..80679b180 100644
> > --- a/man7/system_data_types.7
> > +++ b/man7/system_data_types.7
> > @@ -1544,7 +1544,11 @@ or
> >   .EX
> >   struct timespec {
> >       time_t  tv_sec;  /* Seconds */
> > +#if !(__x86_64__ && __ILP32__ /* == x32 */)
> >       long    tv_nsec; /* Nanoseconds [0 .. 999999999] */
> > +#else
> > +    long long tv_nsec;
> > +#endif
>
> I prefer showing there the (simple) POSIX definition, and then in Notes
> add a message that glibc uses a different type on most systems.
> Otherwise, we're loosing the information that non-glibc systems use long.
>
> How about something like the following?:
>
> Notes: glibc uses long long instead of long for tv_nsec in some
> architectures:
>
>         #if !(__x86_64__ && __ILP32__ /* == x32 */)
>                 long      tv_nsec;
>         #else
>                 long long tv_nsec;
>         #endif

The #if condition is actually "we're not on x32", so maybe the comment
could say /* != x32 */? Otherwise it looks like the comment
contradicts the code; I know the comment is inside the paranthesis,
and the negation ('!') is outside, but the negation might be easy to
overlook.

Or maybe leave the x32 field size for a note? (E.g. something like
"This is true on almost all arches, but see NOTES", and then under
NOTES specify that "actually, on x32 tv_nsec is long long"). The #if
in the definition doesn't *exactly* match the code anyway.

Thanks,
Stefan.

>
>
> BTW, I don't understand why long long, if long can perfectly represent 0
> .. 999999999.  If you know the rationale for such extension, it would be
> a great addition to Notes too.
>
> Thanks!
>
> Alex
>
> >   };
> >   .EE
> >   .PP
> >
>
>
> --
> Alejandro Colomar
> Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
> http://www.alejandro-colomar.es/

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

* Re: [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32
  2021-12-07 11:02               ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 Stefan Puiu
@ 2021-12-07 11:05                 ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-12-07 11:05 UTC (permalink / raw)
  To: Stefan Puiu; +Cc: наб, lnx-man, Michael Kerrisk (man-pages)

Hi, Stefan!

On 12/7/21 12:02, Stefan Puiu wrote:
>> Notes: glibc uses long long instead of long for tv_nsec in some
>> architectures:
>>
>>          #if !(__x86_64__ && __ILP32__ /* == x32 */)
>>                  long      tv_nsec;
>>          #else
>>                  long long tv_nsec;
>>          #endif
> 
> The #if condition is actually "we're not on x32", so maybe the comment
> could say /* != x32 */? Otherwise it looks like the comment
> contradicts the code; I know the comment is inside the paranthesis,
> and the negation ('!') is outside, but the negation might be easy to
> overlook.
> 
> Or maybe leave the x32 field size for a note? (E.g. something like
> "This is true on almost all arches, but see NOTES", and then under
> NOTES specify that "actually, on x32 tv_nsec is long long"). The #if
> in the definition doesn't *exactly* match the code anyway.

In the latest version of the patch (unfortunately it's not tagged as 
v4), we removed the negation to avoid that problem.

Thanks for reporting it :)


Cheers,
Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-07  1:41                         ` наб
@ 2021-12-07 18:43                           ` Joseph Myers
  2021-12-07 18:52                             ` Florian Weimer
  2022-01-03 15:44                           ` наб
  1 sibling, 1 reply; 31+ messages in thread
From: Joseph Myers @ 2021-12-07 18:43 UTC (permalink / raw)
  To: наб
  Cc: Alejandro Colomar (man-pages), linux-man, Zack Weinberg, libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1153 bytes --]

On Tue, 7 Dec 2021, наб via Libc-alpha wrote:

> Looking through "timespec" on Aardvark for prior art reveals nothing,
> except for a likely resolution to any proposal of this sort:
> > Although we agree that it would have been better if these functions had
> > been designed this way to begin with, we believe that making the change
> > now will break existing, conforming code with no real benefit. 

Geoff Clare said (austin-group-l, Thu, 29 May 2014 16:20:22 +0100):

  C11 requires tv_nsec to be type long, which means that if we change
  it to be a new snseconds_t type in Issue 8, we would have to require
  that snseconds_t is defined as long in order not to conflict with C11.

and Rich Felker (Thu, 29 May 2014 13:08:59 -0400):

  This is just a linux kernel bug which needs to be fixed. They have a
  number of other such bugs in x32 too. It's possible to work around it
  in userspace on the library side (we do this in musl libc) but it's a
  bit costly/painful and glibc does not do so yet. There's an open bug
  for it which I filed:

and I don't see any other responses in that discussion.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-07 18:43                           ` Joseph Myers
@ 2021-12-07 18:52                             ` Florian Weimer
  0 siblings, 0 replies; 31+ messages in thread
From: Florian Weimer @ 2021-12-07 18:52 UTC (permalink / raw)
  To: Joseph Myers
  Cc: наб, Alejandro Colomar (man-pages),
	linux-man, Zack Weinberg, libc-alpha

* Joseph Myers:

> On Tue, 7 Dec 2021, наб via Libc-alpha wrote:
>
>> Looking through "timespec" on Aardvark for prior art reveals nothing,
>> except for a likely resolution to any proposal of this sort:
>> > Although we agree that it would have been better if these functions had
>> > been designed this way to begin with, we believe that making the change
>> > now will break existing, conforming code with no real benefit. 
>
> Geoff Clare said (austin-group-l, Thu, 29 May 2014 16:20:22 +0100):
>
>   C11 requires tv_nsec to be type long, which means that if we change
>   it to be a new snseconds_t type in Issue 8, we would have to require
>   that snseconds_t is defined as long in order not to conflict with C11.
>
> and Rich Felker (Thu, 29 May 2014 13:08:59 -0400):
>
>   This is just a linux kernel bug which needs to be fixed. They have a
>   number of other such bugs in x32 too. It's possible to work around it
>   in userspace on the library side (we do this in musl libc) but it's a
>   bit costly/painful and glibc does not do so yet. There's an open bug
>   for it which I filed:
>
> and I don't see any other responses in that discussion.

This came up again during the time64 work.  The kernel was eventually
changed to ignore the padding, so userspace can use a long int type.
x32 wasn't changed for backwards compatibility reasons.

Thanks,
Florian


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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2021-12-07  1:41                         ` наб
  2021-12-07 18:43                           ` Joseph Myers
@ 2022-01-03 15:44                           ` наб
  2022-01-03 16:54                             ` Alejandro Colomar (man-pages)
  1 sibling, 1 reply; 31+ messages in thread
From: наб @ 2022-01-03 15:44 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages); +Cc: linux-man

[-- Attachment #1: Type: text/plain, Size: 346 bytes --]

On Tue, Dec 07, 2021 at 02:41:15AM +0100, наб wrote:
> Regrettably, I think this is the best we can do,
> save for committing a plan9. Scissor-patch below.

Bumping this ‒ I think it's sensible to have this in as
glibc/WG14/Austin Group proceedings transpire, but this is ultimately
your decision ‒ how do you rule on it?

наб

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability
  2022-01-03 15:44                           ` наб
@ 2022-01-03 16:54                             ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 31+ messages in thread
From: Alejandro Colomar (man-pages) @ 2022-01-03 16:54 UTC (permalink / raw)
  To: наб; +Cc: linux-man

On 1/3/22 16:44, наб wrote:
> On Tue, Dec 07, 2021 at 02:41:15AM +0100, наб wrote:
>> Regrettably, I think this is the best we can do,
>> save for committing a plan9. Scissor-patch below.
> 
> Bumping this ‒ I think it's sensible to have this in as
> glibc/WG14/Austin Group proceedings transpire, but this is ultimately
> your decision ‒ how do you rule on it?

Thanks for the ping, I already forgot about it!
I like your patch, so I applied it :)

Thanks,

Alex

-- 
Alejandro Colomar
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

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

end of thread, other threads:[~2022-01-03 16:54 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-28 18:17 [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
2021-11-28 18:17 ` [PATCH 2/4] poll.2, sigwaitinfo.2: fix struct timespec::tv_sec to be time_t, not long наб
2021-11-29 12:27   ` Alejandro Colomar (man-pages)
2021-11-28 18:17 ` [PATCH 3/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
2021-11-29  9:45   ` Jakub Wilk
2021-11-29 12:31   ` Alejandro Colomar (man-pages)
2021-12-03 23:46     ` наб
2021-12-06 19:18       ` [PATCH 3/4] Many pages: " Alejandro Colomar (man-pages)
2021-12-06 20:11         ` [PATCH v2 0/4] timespec(3) migration наб
2021-12-06 20:12           ` [PATCH v2 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timerfd_create.2, timer_settime.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3: replace in-line struct timespec declarations with "timespec(3) structure" references наб
2021-12-06 21:14             ` Alejandro Colomar (man-pages)
2021-12-06 20:12           ` [PATCH v2 2/4] system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range наб
2021-12-06 21:18             ` Alejandro Colomar (man-pages)
2021-12-06 20:12           ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 наб
2021-12-06 21:30             ` Alejandro Colomar (man-pages)
2021-12-06 22:03               ` [PATCH v3 3/3] system_data_types.7: note struct timespec::tv_nsec type for x32 and portability наб
2021-12-06 22:56                 ` Alejandro Colomar (man-pages)
2021-12-06 23:31                   ` наб
2021-12-07  0:38                     ` Alejandro Colomar (man-pages)
2021-12-07  1:08                       ` наб
2021-12-07  1:34                         ` Alejandro Colomar (man-pages)
     [not found]                     ` <a55c07d0-960f-4dfe-90bf-4fee33976198@www.fastmail.com>
     [not found]                       ` <7c29781b-1030-44f9-b078-f5b09a14e321@gmail.com>
2021-12-07  1:41                         ` наб
2021-12-07 18:43                           ` Joseph Myers
2021-12-07 18:52                             ` Florian Weimer
2022-01-03 15:44                           ` наб
2022-01-03 16:54                             ` Alejandro Colomar (man-pages)
2021-12-07 11:02               ` [PATCH v2 3/4] system_data_types.7: correct struct timespec::tv_nsec type for x32 Stefan Puiu
2021-12-07 11:05                 ` Alejandro Colomar (man-pages)
2021-12-06 20:12           ` [PATCH v2 4/4] system_data_types.7: note that struct timespec::tv_nsec being long long on x32 is an extension наб
2021-11-28 18:17 ` [PATCH " наб
2021-11-29 12:26 ` [PATCH 1/4] clock_getres.2, clock_nanosleep.2, io_getevents.2, nanosleep.2, poll.2, sched_rr_get_interval.2, select.2, sigwaitinfo.2, timer_settime.2, timerfd_create.2, utimensat.2, mq_receive.3, mq_send.3, pthread_tryjoin_np.3, sem_wait.3, system_data_types.7: standardise on struct timespec fields comments to ucase w/tv_nsec range Alejandro Colomar (man-pages)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.