public inbox for libc-stable@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2.33 COMMITTED 1/6] tst: Provide test for select
@ 2021-04-13 21:04 Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 2/6] misc: Fix tst-select timeout handling (BZ#27648) Adhemerval Zanella
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2021-04-13 21:04 UTC (permalink / raw)
  To: libc-stable; +Cc: Lukasz Majewski

From: Lukasz Majewski <lukma@denx.de>

This change adds new test to assess select()'s timeout related
functionality (the rdfs set provides valid fd - stderr - but during
normal program operation there is no data to be read, so one just
waits for timeout).

To be more specific - two use cases are checked:
- if select() times out immediately when passed struct timeval has
  zero values of tv_usec and tv_sec.
- if select() times out after timeout specified in passed argument

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

(cherry picked from commit bff3019afc77eb51634471827daaa1c17a6dc5bd)
---
 misc/Makefile     |  2 +-
 misc/tst-select.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 misc/tst-select.c

diff --git a/misc/Makefile b/misc/Makefile
index b08d7c68ab..05ad034baf 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -88,7 +88,7 @@ tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
 	 tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
 	 tst-preadvwritev2 tst-preadvwritev64v2 tst-warn-wide \
 	 tst-ldbl-warn tst-ldbl-error tst-dbl-efgcvt tst-ldbl-efgcvt \
-	 tst-mntent-autofs tst-syscalls tst-mntent-escape
+	 tst-mntent-autofs tst-syscalls tst-mntent-escape tst-select
 
 # Tests which need libdl.
 ifeq (yes,$(build-shared))
diff --git a/misc/tst-select.c b/misc/tst-select.c
new file mode 100644
index 0000000000..7c310256c5
--- /dev/null
+++ b/misc/tst-select.c
@@ -0,0 +1,71 @@
+/* Test for select timeout.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <time.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/select.h>
+#include <support/check.h>
+#include <support/xtime.h>
+#include <support/timespec.h>
+
+#define TST_SELECT_TIMEOUT 1
+#define TST_SELECT_FD_ERR 2
+
+static int
+test_select_timeout (bool zero_tmo)
+{
+  const int fds = TST_SELECT_FD_ERR;
+  int timeout = TST_SELECT_TIMEOUT;
+  struct timeval to = { 0, 0 };
+  struct timespec ts;
+  fd_set rfds;
+
+  FD_ZERO (&rfds);
+  FD_SET (fds, &rfds);
+
+  if (zero_tmo)
+    timeout = 0;
+
+  to.tv_sec = timeout;
+  ts = xclock_now (CLOCK_REALTIME);
+  ts = timespec_add (ts, (struct timespec) { timeout, 0 });
+
+  /* Wait for timeout.  */
+  int ret = select (fds + 1, &rfds, NULL, NULL, &to);
+  if (ret == -1)
+    FAIL_EXIT1 ("select failed: %m\n");
+
+  TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
+
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  /* Check if select exits immediately.  */
+  test_select_timeout (true);
+
+  /* Check if select exits after specified timeout.  */
+  test_select_timeout (false);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.27.0


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

* [PATCH 2.33 COMMITTED 2/6] misc: Fix tst-select timeout handling (BZ#27648)
  2021-04-13 21:04 [PATCH 2.33 COMMITTED 1/6] tst: Provide test for select Adhemerval Zanella
@ 2021-04-13 21:04 ` Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 3/6] libsupport: Add support_select_modifies_timeout Adhemerval Zanella
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2021-04-13 21:04 UTC (permalink / raw)
  To: libc-stable

Instead of polling the stderr, create two pipes and fork to check
if child timeout as expected similar to tst-pselect.c.  Also lower
the timeout value.

Checked on x86_64-linux-gnu.

(cherry picked from commit 1b53b5d970c232b48843c778ac4566ff5b566c3b)
---
 NEWS              |  1 +
 misc/tst-select.c | 85 ++++++++++++++++++++++++++++++-----------------
 2 files changed, 56 insertions(+), 30 deletions(-)

diff --git a/NEWS b/NEWS
index 6f32249818..4bc898e858 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,7 @@ The following bugs are resolved with this release:
   [27304] pthread_cond_destroy does not pass private flag to futex system calls
   [27537] test-container: Always copy test-specific support files
   [27577] elf/ld.so --help doesn't work
+  [27648] FAIL: misc/tst-select
 \f
 Version 2.33
 
diff --git a/misc/tst-select.c b/misc/tst-select.c
index 7c310256c5..5ad057cd51 100644
--- a/misc/tst-select.c
+++ b/misc/tst-select.c
@@ -16,54 +16,79 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
 #include <errno.h>
-#include <stdbool.h>
-#include <sys/select.h>
+#include <support/capture_subprocess.h>
 #include <support/check.h>
-#include <support/xtime.h>
 #include <support/timespec.h>
+#include <support/xunistd.h>
+#include <support/xtime.h>
 
-#define TST_SELECT_TIMEOUT 1
-#define TST_SELECT_FD_ERR 2
+struct child_args
+{
+  int fds[2][2];
+  struct timeval tmo;
+};
 
-static int
-test_select_timeout (bool zero_tmo)
+static void
+do_test_child (void *clousure)
 {
-  const int fds = TST_SELECT_FD_ERR;
-  int timeout = TST_SELECT_TIMEOUT;
-  struct timeval to = { 0, 0 };
-  struct timespec ts;
-  fd_set rfds;
+  struct child_args *args = (struct child_args *) clousure;
 
-  FD_ZERO (&rfds);
-  FD_SET (fds, &rfds);
+  close (args->fds[0][1]);
+  close (args->fds[1][0]);
 
-  if (zero_tmo)
-    timeout = 0;
+  fd_set rfds;
+  FD_ZERO (&rfds);
+  FD_SET (args->fds[0][0], &rfds);
 
-  to.tv_sec = timeout;
-  ts = xclock_now (CLOCK_REALTIME);
-  ts = timespec_add (ts, (struct timespec) { timeout, 0 });
+  struct timespec ts = xclock_now (CLOCK_REALTIME);
+  ts = timespec_add (ts, (struct timespec) { args->tmo.tv_sec, 0 });
 
-  /* Wait for timeout.  */
-  int ret = select (fds + 1, &rfds, NULL, NULL, &to);
-  if (ret == -1)
-    FAIL_EXIT1 ("select failed: %m\n");
+  int r = select (args->fds[0][0] + 1, &rfds, NULL, NULL, &args->tmo);
+  TEST_COMPARE (r, 0);
 
   TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
 
-  return 0;
+  xwrite (args->fds[1][1], "foo", 3);
 }
 
 static int
 do_test (void)
 {
-  /* Check if select exits immediately.  */
-  test_select_timeout (true);
-
-  /* Check if select exits after specified timeout.  */
-  test_select_timeout (false);
+  struct child_args args;
+
+  xpipe (args.fds[0]);
+  xpipe (args.fds[1]);
+
+  /* The child select should timeout and write on its pipe end.  */
+  args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 250000 };
+  {
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (do_test_child, &args);
+    support_capture_subprocess_check (&result, "tst-select-child", 0,
+				      sc_allow_none);
+  }
+
+  /* Same as before, but simulating polling.  */
+  args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
+  {
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (do_test_child, &args);
+    support_capture_subprocess_check (&result, "tst-select-child", 0,
+				      sc_allow_none);
+  }
+
+  xclose (args.fds[0][0]);
+  xclose (args.fds[1][1]);
+
+  {
+    fd_set rfds;
+    FD_ZERO (&rfds);
+    FD_SET (args.fds[1][0], &rfds);
+
+    int r = select (args.fds[1][0] + 1, &rfds, NULL, NULL, &args.tmo);
+    TEST_COMPARE (r, 1);
+  }
 
   return 0;
 }
-- 
2.27.0


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

* [PATCH 2.33 COMMITTED 3/6] libsupport: Add support_select_modifies_timeout
  2021-04-13 21:04 [PATCH 2.33 COMMITTED 1/6] tst: Provide test for select Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 2/6] misc: Fix tst-select timeout handling (BZ#27648) Adhemerval Zanella
@ 2021-04-13 21:04 ` Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 4/6] libsupport: Add support_select_normalizes_timeout Adhemerval Zanella
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2021-04-13 21:04 UTC (permalink / raw)
  To: libc-stable

It will be used on a select() test.

(cherry picked from commit 5628f103f5937611730845390928cb43ef716012)
---
 support/Makefile                          |  1 +
 support/support.h                         |  5 ++++
 support/support_select_modifies_timeout.c | 29 +++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 support/support_select_modifies_timeout.c

diff --git a/support/Makefile b/support/Makefile
index bb9889efb4..4fd76b0e5e 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -67,6 +67,7 @@ libsupport-routines = \
   support_quote_string \
   support_record_failure \
   support_run_diff \
+  support_select_modifies_timeout \
   support_set_small_thread_stack_size \
   support_shared_allocate \
   support_small_stack_thread_attribute \
diff --git a/support/support.h b/support/support.h
index 9cbc455720..9c9612644a 100644
--- a/support/support.h
+++ b/support/support.h
@@ -23,6 +23,7 @@
 #ifndef SUPPORT_H
 #define SUPPORT_H
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <sys/cdefs.h>
 /* For mode_t.  */
@@ -129,6 +130,10 @@ extern void support_copy_file (const char *from, const char *to);
 extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
 					size_t, unsigned int);
 
+/* Return true if select modify the timeout to reflect the amount of time
+   no slept.  */
+extern bool support_select_modifies_timeout (void);
+
 __END_DECLS
 
 #endif /* SUPPORT_H */
diff --git a/support/support_select_modifies_timeout.c b/support/support_select_modifies_timeout.c
new file mode 100644
index 0000000000..653ea2cc98
--- /dev/null
+++ b/support/support_select_modifies_timeout.c
@@ -0,0 +1,29 @@
+/* Return whether select modifies the timeout.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/support.h>
+
+bool
+support_select_modifies_timeout (void)
+{
+#ifdef __linux__
+  return true;
+#else
+  return false;
+#endif
+}
-- 
2.27.0


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

* [PATCH 2.33 COMMITTED 4/6] libsupport: Add support_select_normalizes_timeout
  2021-04-13 21:04 [PATCH 2.33 COMMITTED 1/6] tst: Provide test for select Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 2/6] misc: Fix tst-select timeout handling (BZ#27648) Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 3/6] libsupport: Add support_select_modifies_timeout Adhemerval Zanella
@ 2021-04-13 21:04 ` Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 5/6] linux: Normalize and return timeout on select (BZ #27651) Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 6/6] linux: always update select timeout (BZ #27706) Adhemerval Zanella
  4 siblings, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2021-04-13 21:04 UTC (permalink / raw)
  To: libc-stable

It will be used on a select() test.

(cherry-pick from commit 49a40ba18e2cb948259771317fe6ff6f5eb68683)
---
 support/Makefile                            |  1 +
 support/support.h                           |  4 +++
 support/support_select_normalizes_timeout.c | 29 +++++++++++++++++++++
 3 files changed, 34 insertions(+)
 create mode 100644 support/support_select_normalizes_timeout.c

diff --git a/support/Makefile b/support/Makefile
index 4fd76b0e5e..fc5d9d4c79 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -68,6 +68,7 @@ libsupport-routines = \
   support_record_failure \
   support_run_diff \
   support_select_modifies_timeout \
+  support_select_normalizes_timeout \
   support_set_small_thread_stack_size \
   support_shared_allocate \
   support_small_stack_thread_attribute \
diff --git a/support/support.h b/support/support.h
index 9c9612644a..8c7890e0a6 100644
--- a/support/support.h
+++ b/support/support.h
@@ -134,6 +134,10 @@ extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
    no slept.  */
 extern bool support_select_modifies_timeout (void);
 
+/* Return true if select normalize the timeout input by taking in account
+   tv_usec larger than 1000000.  */
+extern bool support_select_normalizes_timeout (void);
+
 __END_DECLS
 
 #endif /* SUPPORT_H */
diff --git a/support/support_select_normalizes_timeout.c b/support/support_select_normalizes_timeout.c
new file mode 100644
index 0000000000..987f9b035e
--- /dev/null
+++ b/support/support_select_normalizes_timeout.c
@@ -0,0 +1,29 @@
+/* Return whether select normalizes the timeout.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/support.h>
+
+bool
+support_select_normalizes_timeout (void)
+{
+#ifdef __linux__
+  return true;
+#else
+  return false;
+#endif
+}
-- 
2.27.0


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

* [PATCH 2.33 COMMITTED 5/6] linux: Normalize and return timeout on select (BZ #27651)
  2021-04-13 21:04 [PATCH 2.33 COMMITTED 1/6] tst: Provide test for select Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 4/6] libsupport: Add support_select_normalizes_timeout Adhemerval Zanella
@ 2021-04-13 21:04 ` Adhemerval Zanella
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 6/6] linux: always update select timeout (BZ #27706) Adhemerval Zanella
  4 siblings, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2021-04-13 21:04 UTC (permalink / raw)
  To: libc-stable

The commit 2433d39b697, which added time64 support to select, changed
the function to use __NR_pselect6 (or __NR_pelect6_time64) on all
architectures.  However, on architectures where the symbol was
implemented with __NR_select the kernel normalizes the passed timeout
instead of return EINVAL.  For instance, the input timeval
{ 0, 5000000 } is interpreted as { 5, 0 }.

And as indicated by BZ #27651, this semantic seems to be expected
and changing it results in some performance issues (most likely
the program does not check the return code and keeps issuing
select with unormalized tv_usec argument).

To avoid a different semantic depending whether which syscall the
architecture used to issue, select now always normalize the timeout
input.  This is a slight change for some ABIs (for instance aarch64).

Checked on x86_64-linux-gnu and i686-linux-gnu.

(cherry picked from commit 9d7c5cc38e58fb0923e88901f87174a511b61552)
---
 NEWS                             |  1 +
 include/time.h                   |  5 ++++
 misc/tst-select.c                | 17 +++++++++++++
 sunrpc/svcauth_des.c             |  1 -
 sysdeps/unix/sysv/linux/select.c | 41 +++++++++++++++++++++++++-------
 5 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/NEWS b/NEWS
index 4bc898e858..52d676f6c5 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ The following bugs are resolved with this release:
   [27537] test-container: Always copy test-specific support files
   [27577] elf/ld.so --help doesn't work
   [27648] FAIL: misc/tst-select
+  [27651] Performance regression after updating to 2.33
 \f
 Version 2.33
 
diff --git a/include/time.h b/include/time.h
index caf2af5e74..e0636132a6 100644
--- a/include/time.h
+++ b/include/time.h
@@ -502,6 +502,11 @@ time_now (void)
   __clock_gettime (TIME_CLOCK_GETTIME_CLOCKID, &ts);
   return ts.tv_sec;
 }
+
+#define NSEC_PER_SEC    1000000000L  /* Nanoseconds per second.  */
+#define USEC_PER_SEC    1000000L     /* Microseconds per second.  */
+#define NSEC_PER_USEC   1000L        /* Nanoseconds per microsecond.  */
+
 #endif
 
 #endif
diff --git a/misc/tst-select.c b/misc/tst-select.c
index 5ad057cd51..534105b500 100644
--- a/misc/tst-select.c
+++ b/misc/tst-select.c
@@ -19,6 +19,7 @@
 #include <errno.h>
 #include <support/capture_subprocess.h>
 #include <support/check.h>
+#include <support/support.h>
 #include <support/timespec.h>
 #include <support/xunistd.h>
 #include <support/xtime.h>
@@ -47,6 +48,12 @@ do_test_child (void *clousure)
   int r = select (args->fds[0][0] + 1, &rfds, NULL, NULL, &args->tmo);
   TEST_COMPARE (r, 0);
 
+  if (support_select_modifies_timeout ())
+    {
+      TEST_COMPARE (args->tmo.tv_sec, 0);
+      TEST_COMPARE (args->tmo.tv_usec, 0);
+    }
+
   TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
 
   xwrite (args->fds[1][1], "foo", 3);
@@ -69,6 +76,16 @@ do_test (void)
 				      sc_allow_none);
   }
 
+  if (support_select_normalizes_timeout ())
+    {
+      /* This is handled as 1 second instead of failing with EINVAL.  */
+      args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 1000000 };
+      struct support_capture_subprocess result;
+      result = support_capture_subprocess (do_test_child, &args);
+      support_capture_subprocess_check (&result, "tst-select-child", 0,
+					sc_allow_none);
+    }
+
   /* Same as before, but simulating polling.  */
   args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
   {
diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c
index 7607abc818..25a85c9097 100644
--- a/sunrpc/svcauth_des.c
+++ b/sunrpc/svcauth_des.c
@@ -58,7 +58,6 @@
 
 #define debug(msg)		/*printf("svcauth_des: %s\n", msg) */
 
-#define USEC_PER_SEC ((uint32_t) 1000000L)
 #define BEFORE(t1, t2) timercmp(t1, t2, <)
 
 /*
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index 415aa87d3c..3b67ff4476 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -33,12 +33,34 @@ int
 __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 	    struct __timeval64 *timeout)
 {
-  struct __timespec64 ts64, *pts64 = NULL;
-  if (timeout != NULL)
+  __time64_t s = timeout != NULL ? timeout->tv_sec : 0;
+  int32_t us = timeout != NULL ? timeout->tv_usec : 0;
+  int32_t ns;
+
+  if (s < 0 || us < 0)
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  /* Normalize the timeout, as legacy Linux __NR_select and __NR__newselect.
+     Different than syscall, it also handle possible overflow.  */
+  if (us / USEC_PER_SEC > INT64_MAX - s)
     {
-      ts64 = timeval64_to_timespec64 (*timeout);
-      pts64 = &ts64;
+      s = INT64_MAX;
+      ns = NSEC_PER_SEC - 1;
     }
+  else
+    {
+      s += us / USEC_PER_SEC;
+      us = us % USEC_PER_SEC;
+      ns = us * NSEC_PER_USEC;
+    }
+
+  struct __timespec64 ts64, *pts64 = NULL;
+   if (timeout != NULL)
+     {
+       ts64.tv_sec = s;
+       ts64.tv_nsec = ns;
+       pts64 = &ts64;
+     }
 
 #ifndef __NR_pselect6_time64
 # define __NR_pselect6_time64 __NR_pselect6
@@ -52,10 +74,10 @@ __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
          (though the pselect() glibc call suppresses this behavior).
          Since select() on Linux has the same behavior as the pselect6
          syscall, we update the timeout here.  */
-      if (r == 0 || errno != ENOSYS)
+      if (r >= 0 || errno != ENOSYS)
 	{
 	  if (timeout != NULL)
-	    TIMEVAL_TO_TIMESPEC (timeout, &ts64);
+	    TIMESPEC_TO_TIMEVAL (timeout, &ts64);
 	  return r;
 	}
 
@@ -64,14 +86,15 @@ __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 
 #ifndef __ASSUME_TIME64_SYSCALLS
   struct timespec ts32, *pts32 = NULL;
-  if (timeout != NULL)
+  if (pts64 != NULL)
     {
-      if (! in_time_t_range (timeout->tv_sec))
+      if (! in_time_t_range (pts64->tv_sec))
 	{
 	  __set_errno (EINVAL);
 	  return -1;
 	}
-      ts32 = valid_timespec64_to_timespec (ts64);
+      ts32.tv_sec = s;
+      ts32.tv_nsec = ns;
       pts32 = &ts32;
     }
 # ifndef __ASSUME_PSELECT
-- 
2.27.0


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

* [PATCH 2.33 COMMITTED 6/6] linux: always update select timeout (BZ #27706)
  2021-04-13 21:04 [PATCH 2.33 COMMITTED 1/6] tst: Provide test for select Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 5/6] linux: Normalize and return timeout on select (BZ #27651) Adhemerval Zanella
@ 2021-04-13 21:04 ` Adhemerval Zanella
  4 siblings, 0 replies; 6+ messages in thread
From: Adhemerval Zanella @ 2021-04-13 21:04 UTC (permalink / raw)
  To: libc-stable

The timeout should be updated even on failure for time64 support.

Checked on i686-linux-gnu.

(cherry-pick from commit cedbf6d5f3f70ca911176de87d6e453eeab4b7a1)
---
 NEWS                             |  1 +
 misc/tst-select.c                | 30 ++++++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/select.c |  4 ++--
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 52d676f6c5..769aeb24b7 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,7 @@ The following bugs are resolved with this release:
   [27577] elf/ld.so --help doesn't work
   [27648] FAIL: misc/tst-select
   [27651] Performance regression after updating to 2.33
+  [27706] select fails to update timeout on error
 \f
 Version 2.33
 
diff --git a/misc/tst-select.c b/misc/tst-select.c
index 534105b500..52aa26651f 100644
--- a/misc/tst-select.c
+++ b/misc/tst-select.c
@@ -23,6 +23,7 @@
 #include <support/timespec.h>
 #include <support/xunistd.h>
 #include <support/xtime.h>
+#include <support/xsignal.h>
 
 struct child_args
 {
@@ -30,6 +31,12 @@ struct child_args
   struct timeval tmo;
 };
 
+static void
+alarm_handler (int signum)
+{
+  /* Do nothing.  */
+}
+
 static void
 do_test_child (void *clousure)
 {
@@ -59,6 +66,22 @@ do_test_child (void *clousure)
   xwrite (args->fds[1][1], "foo", 3);
 }
 
+static void
+do_test_child_alarm (void *clousure)
+{
+  struct sigaction act = { .sa_handler = alarm_handler };
+  xsigaction (SIGALRM, &act, NULL);
+  alarm (1);
+
+  struct timeval tv = { .tv_sec = 10, .tv_usec = 0 };
+  int r = select (0, NULL, NULL, NULL, &tv);
+  TEST_COMPARE (r, -1);
+  TEST_COMPARE (errno, EINTR);
+
+  if (support_select_modifies_timeout ())
+    TEST_VERIFY (tv.tv_sec < 10);
+}
+
 static int
 do_test (void)
 {
@@ -98,6 +121,13 @@ do_test (void)
   xclose (args.fds[0][0]);
   xclose (args.fds[1][1]);
 
+  {
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (do_test_child_alarm, NULL);
+    support_capture_subprocess_check (&result, "tst-select-child", 0,
+				      sc_allow_none);
+  }
+
   {
     fd_set rfds;
     FD_ZERO (&rfds);
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index 3b67ff4476..dc16a816ed 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -107,7 +107,7 @@ __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
   r = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, pts32,
 		      NULL);
 # endif
-  if (r >= 0 && timeout != NULL)
+  if (timeout != NULL)
     *timeout = valid_timespec_to_timeval64 (ts32);
 #endif
 
@@ -128,7 +128,7 @@ __select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
       ptv64 = &tv64;
     }
   int r = __select64 (nfds, readfds, writefds, exceptfds, ptv64);
-  if (r >= 0 && timeout != NULL)
+  if (timeout != NULL)
     /* The remanining timeout will be always less the input TIMEOUT.  */
     *timeout = valid_timeval64_to_timeval (tv64);
   return r;
-- 
2.27.0


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

end of thread, other threads:[~2021-04-13 21:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-13 21:04 [PATCH 2.33 COMMITTED 1/6] tst: Provide test for select Adhemerval Zanella
2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 2/6] misc: Fix tst-select timeout handling (BZ#27648) Adhemerval Zanella
2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 3/6] libsupport: Add support_select_modifies_timeout Adhemerval Zanella
2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 4/6] libsupport: Add support_select_normalizes_timeout Adhemerval Zanella
2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 5/6] linux: Normalize and return timeout on select (BZ #27651) Adhemerval Zanella
2021-04-13 21:04 ` [PATCH 2.33 COMMITTED 6/6] linux: always update select timeout (BZ #27706) Adhemerval Zanella

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