This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC v1 04/16] sysdeps/wait: Use __NR_waitid if avaliable
- From: Alistair Francis <alistair dot francis at wdc dot com>
- To: libc-alpha at sourceware dot org
- Cc: alistair dot francis at wdc dot com, alistair23 at gmail dot com
- Date: Fri, 21 Jun 2019 21:37:23 -0700
- Subject: [RFC v1 04/16] sysdeps/wait: Use __NR_waitid if avaliable
- Ironport-sdr: 4Tf6ExFt/aB6OX4wd+ElOeRkY6CXEno2IYN0mUi1GRLyYIe8CD+3FdcRxUX/IsmXctaQDVfeoS mXbgTxEQT7tREM7bFhyabj16LMeAVaJBTNSSCXnIUE4SaobJzZGzs7tr9xe7ZNRAi8dsYIOA5l NtleXcg4ey6ZNbIDeFJ6QJRv7kL4FueE9yJoihPfy+oh1mqz9aNshrak0jeGtYlilQ5WyEXc1P QCePwZyAUFiRv2IvVExT3eWum+zznf+O3EA7lwH0fHF9Wrn3m0yXnFvMZDc8h2e8sHuuM6r3sI 233mkdjlhdj1mjxum9OLMS/g
- Ironport-sdr: IVO9ADi1GwBCKPVRM/Gq0XA7NdGl8+Z0D4KvurxZ3U09kyrxfdqX88HBbTp3xaLvA3s7NpqsYK Bi5q68er4ZkgpVWjRLRc3t9wufEm15cYxOV5u9TvNtXDpugNy4FRfw1A6o46aUsaycfEjQ66Mo Ul3OzJI+YVcUdmv105PBXL/HJtW58pcTHqhpGA4olSxpRb+LACttW61IW2uqyQxUX6OTDRU0qH YpQWlUAW0/poROyKLq9s91sC76kR5iM6B4Gj/m08ymK9/0vSFD36cGpo2fdRqcmaxvH3f7nGFQ OSk=
- References: <cover.1561177967.git.alistair.francis@wdc.com>
If the __NR_waitid syscall is avaliable let's use that as __NR_waitpid
and __NR_wait4 aren't always avaliable (they aren't avaliable on RV32).
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
ChangeLog | 3 ++
sysdeps/unix/sysv/linux/wait.c | 19 ++++++++++++-
sysdeps/unix/sysv/linux/waitpid.c | 33 ++++++++++++++++++++++
sysdeps/unix/sysv/linux/waitpid_nocancel.c | 32 +++++++++++++++++++++
4 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index f1c7acb6ab..9ed9bea8b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@
* sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise.
* sysdeps/unix/sysv/linux/lowlevellock-futex.h: Use __NR_futex_time64 if we don't have __NR_futex.
* sysdeps/unix/sysv/linux/gettimeofday.c: Use clock_gettime64 syscall for gettimeofday.
+ * sysdeps/unix/sysv/linux/wait.c: Use __NR_waitid if avaliable.
+ * sysdeps/unix/sysv/linux/waitpid.c: Likewise.
+ * sysdeps/unix/sysv/linux/waitpid_nocancel.c: Likewise.
2019-06-20 Dmitry V. Levin <ldv@altlinux.org>
Florian Weimer <fweimer@redhat.com>
diff --git a/sysdeps/unix/sysv/linux/wait.c b/sysdeps/unix/sysv/linux/wait.c
index 498bd1c095..9e81ea61ba 100644
--- a/sysdeps/unix/sysv/linux/wait.c
+++ b/sysdeps/unix/sysv/linux/wait.c
@@ -26,8 +26,25 @@
pid_t
__libc_wait (int *stat_loc)
{
- pid_t result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0,
+ pid_t result;
+
+#if defined(__NR_waitid)
+ siginfo_t infop;
+
+ result = SYSCALL_CANCEL (waitid, P_ALL, 0, &infop, 0);
+
+ if (stat_loc) {
+ *stat_loc = infop.si_status;
+ }
+
+ if (result == 0) {
+ result = infop.si_pid;
+ }
+#else
+ result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0,
(struct rusage *) NULL);
+#endif
+
return result;
}
diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c
index f0897574c0..8bc15ba92f 100644
--- a/sysdeps/unix/sysv/linux/waitpid.c
+++ b/sysdeps/unix/sysv/linux/waitpid.c
@@ -20,12 +20,45 @@
#include <sysdep-cancel.h>
#include <stdlib.h>
#include <sys/wait.h>
+#include <unistd.h>
__pid_t
__waitpid (__pid_t pid, int *stat_loc, int options)
{
#ifdef __NR_waitpid
return SYSCALL_CANCEL (waitpid, pid, stat_loc, options);
+#elif defined(__NR_waitid)
+ int ret;
+ idtype_t idtype = P_PID;
+ siginfo_t infop;
+
+ /* Set this to zero so we can test if WNOHANG was specified in options
+ * and there were no children in a waitable state. This is required to match
+ * waitid() behaviour.
+ */
+ infop.si_pid = 0;
+
+ if (pid < -1) {
+ idtype = P_PGID;
+ pid *= -1;
+ } else if (pid == -1) {
+ idtype = P_ALL;
+ } else if (pid == 0) {
+ idtype = P_PGID;
+ pid = getpgrp();
+ }
+
+ ret = SYSCALL_CANCEL (waitid, idtype, pid, &infop, options);
+
+ if (stat_loc) {
+ *stat_loc = infop.si_status;
+ }
+
+ if (ret == 0) {
+ return infop.si_pid;
+ }
+
+ return ret;
#else
return SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL);
#endif
diff --git a/sysdeps/unix/sysv/linux/waitpid_nocancel.c b/sysdeps/unix/sysv/linux/waitpid_nocancel.c
index 89e36a5c0b..d50d15c488 100644
--- a/sysdeps/unix/sysv/linux/waitpid_nocancel.c
+++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c
@@ -27,6 +27,38 @@ __waitpid_nocancel (__pid_t pid, int *stat_loc, int options)
{
#ifdef __NR_waitpid
return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options);
+#elif defined(__NR_waitid)
+ int ret;
+ idtype_t idtype = P_PID;
+ siginfo_t infop;
+
+ /* Set this to zero so we can test if WNOHANG was specified in options
+ * and there were no children in a waitable state. This is required to match
+ * waitid() behaviour.
+ */
+ infop.si_pid = 0;
+
+ if (pid < -1) {
+ idtype = P_PGID;
+ pid *= -1;
+ } else if (pid == -1) {
+ idtype = P_ALL;
+ } else if (pid == 0) {
+ idtype = P_PGID;
+ pid = getpgrp();
+ }
+
+ ret = INLINE_SYSCALL_CALL (waitid, idtype, pid, &infop, options);
+
+ if (stat_loc) {
+ *stat_loc = infop.si_status;
+ }
+
+ if (ret == 0) {
+ return infop.si_pid;
+ }
+
+ return ret;
#else
return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL);
#endif
--
2.22.0