[libc-commits] [libc] 995105d - [libc] Add the POSIX waitpid function and the BSD wait4 function.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Wed Oct 5 00:39:51 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-10-05T07:38:55Z
New Revision: 995105de1b134e2b8bd393ea4caf9c93be41ea4d

URL: https://github.com/llvm/llvm-project/commit/995105de1b134e2b8bd393ea4caf9c93be41ea4d
DIFF: https://github.com/llvm/llvm-project/commit/995105de1b134e2b8bd393ea4caf9c93be41ea4d.diff

LOG: [libc] Add the POSIX waitpid function and the BSD wait4 function.

Reviewed By: lntue, michaelrj

Differential Revision: https://reviews.llvm.org/D135225

Added: 
    libc/include/llvm-libc-types/struct_rusage.h
    libc/include/llvm-libc-types/struct_timeval.h
    libc/include/llvm-libc-types/suseconds_t.h
    libc/src/sys/wait/linux/wait4.cpp
    libc/src/sys/wait/linux/waitpid.cpp
    libc/src/sys/wait/wait4.h
    libc/src/sys/wait/waitpid.h
    libc/test/src/sys/wait/CMakeLists.txt
    libc/test/src/sys/wait/wait4_test.cpp
    libc/test/src/sys/wait/waitpid_test.cpp

Modified: 
    libc/config/linux/api.td
    libc/config/linux/x86_64/entrypoints.txt
    libc/include/CMakeLists.txt
    libc/include/llvm-libc-macros/linux/sys-wait-macros.h
    libc/include/llvm-libc-types/CMakeLists.txt
    libc/spec/bsd_ext.td
    libc/spec/posix.td
    libc/spec/spec.td
    libc/src/sys/wait/CMakeLists.txt
    libc/src/sys/wait/linux/CMakeLists.txt
    libc/test/integration/src/unistd/CMakeLists.txt
    libc/test/integration/src/unistd/fork_test.cpp
    libc/test/src/sys/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 8496b29455d65..01a7814e2d281 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -272,7 +272,7 @@ def SysStatAPI : PublicAPI<"sys/stat.h"> {
 }
 
 def SysWaitAPI : PublicAPI<"sys/wait.h"> {
-  let Types = ["pid_t"];
+  let Types = ["pid_t", "struct rusage"];
 }
 
 def SysSendfileAPI : PublicAPI<"sys/sendfile.h"> {

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0bd5f897edbbc..a1e8ea8530850 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -133,6 +133,8 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # sys/wait.h entrypoints
     libc.src.sys.wait.wait
+    libc.src.sys.wait.wait4
+    libc.src.sys.wait.waitpid
 
     # unistd.h entrypoints
     libc.src.unistd.access

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 3e5d0bb853e3c..63f9dfe0b547e 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -284,6 +284,7 @@ add_gen_header(
     .llvm_libc_common_h
     .llvm-libc-macros.sys_wait_macros
     .llvm-libc-types.pid_t
+    .llvm-libc-types.struct_rusage
 )
 
 if(NOT LLVM_LIBC_FULL_BUILD)

diff  --git a/libc/include/llvm-libc-macros/linux/sys-wait-macros.h b/libc/include/llvm-libc-macros/linux/sys-wait-macros.h
index 5b5ad22ecae14..aaafe42abc5fc 100644
--- a/libc/include/llvm-libc-macros/linux/sys-wait-macros.h
+++ b/libc/include/llvm-libc-macros/linux/sys-wait-macros.h
@@ -9,6 +9,11 @@
 #ifndef __LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
 #define __LLVM_LIBC_MACROS_LINUX_SYS_WAIT_MACROS_H
 
+// Wait flags
+#define WNOHANG 1    // Do not block
+#define WUNTRACED 2  // Report is a child has stopped even if untraced
+#define WCONTINUED 8 // Report if a stopped child has been resumed by SIGCONT
+
 // Wait status info macros
 #define WTERMSIG(status) (((status)&0x7F))
 #define WIFEXITED(status) (WTERMSIG(status) == 0)

diff  --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 3b367ab5da988..b9e87eb888996 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -43,14 +43,17 @@ add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type)
 add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h)
 add_header(pthread_once_t HDR pthread_once_t.h DEPENDS .__futex_word)
 add_header(rlim_t HDR rlim_t.h)
+add_header(time_t HDR time_t.h)
+add_header(suseconds_t HDR suseconds_t.h)
+add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t)
 add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
+add_header(struct_rusage HDR struct_rusage.h DEPENDS .struct_timeval)
 add_header(ssize_t HDR ssize_t.h)
 add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
 add_header(union_sigval HDR union_sigval.h)
 add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t)
 add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros)
 add_header(struct_sigaction HDR struct_sigaction.h DEPENDS .sigset_t .siginfo_t)
-add_header(time_t HDR time_t.h)
 add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t)
 add_header(
   struct_stat

diff  --git a/libc/include/llvm-libc-types/struct_rusage.h b/libc/include/llvm-libc-types/struct_rusage.h
new file mode 100644
index 0000000000000..43f345792205d
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_rusage.h
@@ -0,0 +1,37 @@
+//===-- Definition of type struct rusage ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_TYPES_STRUCT_RUSAGE_H__
+#define __LLVM_LIBC_TYPES_STRUCT_RUSAGE_H__
+
+#include <llvm-libc-types/struct_timeval.h>
+
+struct rusage {
+  struct timeval ru_utime;
+  struct timeval ru_stime;
+#ifdef __linux__
+  // Following fields are linux extensions as expected by the
+  // linux syscalls.
+  long ru_maxrss;   // Maximum resident set size
+  long ru_ixrss;    // Integral shared memory size
+  long ru_idrss;    // Integral unshared data size
+  long ru_isrss;    // Integral unshared stack size
+  long ru_minflt;   // Page reclaims
+  long ru_majflt;   // Page faults
+  long ru_nswap;    // Swaps
+  long ru_inblock;  // Block input operations
+  long ru_oublock;  // Block output operations
+  long ru_msgsnd;   // Messages sent
+  long ru_msgrcv;   // Messages received
+  long ru_nsignals; // Signals received
+  long ru_nvcsw;    // Voluntary context switches
+  long ru_nivcsw;   // Involuntary context switches
+#endif
+};
+
+#endif // __LLVM_LIBC_TYPES_STRUCT_RUSAGE_H__

diff  --git a/libc/include/llvm-libc-types/struct_timeval.h b/libc/include/llvm-libc-types/struct_timeval.h
new file mode 100644
index 0000000000000..756fecabb6ace
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_timeval.h
@@ -0,0 +1,20 @@
+//===-- Definition of struct timeval -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_TYPES_TIMEVAL_H__
+#define __LLVM_LIBC_TYPES_TIMEVAL_H__
+
+#include <llvm-libc-types/suseconds_t.h>
+#include <llvm-libc-types/time_t.h>
+
+struct timeval {
+  time_t tv_sec;       // Seconds
+  suseconds_t tv_usec; // Micro seconds
+};
+
+#endif // __LLVM_LIBC_TYPES_TIMEVAL_H__

diff  --git a/libc/include/llvm-libc-types/suseconds_t.h b/libc/include/llvm-libc-types/suseconds_t.h
new file mode 100644
index 0000000000000..d7298ed74a4cd
--- /dev/null
+++ b/libc/include/llvm-libc-types/suseconds_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of suseconds_t type ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_TYPES_SUSECONDS_T_H__
+#define __LLVM_LIBC_TYPES_SUSECONDS_T_H__
+
+typedef __INT32_TYPE__ suseconds_t;
+
+#endif // __LLVM_LIBC_TYPES_SUSECONDS_T_H__

diff  --git a/libc/spec/bsd_ext.td b/libc/spec/bsd_ext.td
index 577d978ca7264..5779ab79c4f1d 100644
--- a/libc/spec/bsd_ext.td
+++ b/libc/spec/bsd_ext.td
@@ -18,7 +18,22 @@ def BsdExtensions : StandardSpec<"BSDExtensions"> {
       ]
   >;
 
+  HeaderSpec SysWait = HeaderSpec<
+      "sys/wait.h",
+      [], // Macros
+      [StructRUsage], // Types
+      [], // Enumerations
+      [
+        FunctionSpec<
+            "wait4",
+            RetValSpec<PidT>,
+            [ArgSpec<PidT>, ArgSpec<IntPtr>, ArgSpec<IntType>, ArgSpec<StructRUsagePtr>]
+        >
+      ]
+  >;
+
   let Headers = [
     String,
+    SysWait,
   ];
 }

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
index 47e71e9cc567d..369455bb37c21 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -971,13 +971,18 @@ def POSIX : StandardSpec<"POSIX"> {
   HeaderSpec SysWait = HeaderSpec<
     "sys/wait.h",
     [], // Macros
-    [PidT],
+    [PidT, StructRUsage],
     [], // Enumerations
     [
       FunctionSpec<
         "wait",
         RetValSpec<PidT>,
         [ArgSpec<IntPtr>]
+      >,
+      FunctionSpec<
+        "waitpid",
+        RetValSpec<PidT>,
+        [ArgSpec<PidT>, ArgSpec<IntPtr>, ArgSpec<IntType>]
       >
     ]
   >;

diff  --git a/libc/spec/spec.td b/libc/spec/spec.td
index 87974ece2f8d2..85a8f46eb59db 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -115,6 +115,8 @@ def FILERestrictedPtr : RestrictedPtrType<FILE>;
 def PThreadTType : NamedType<"pthread_t">;
 
 def PidT : NamedType<"pid_t">;
+def StructRUsage : NamedType<"struct rusage">;
+def StructRUsagePtr : PtrType<StructRUsage>;
 
 //added because __assert_fail needs it.
 def UnsignedType : NamedType<"unsigned">;

diff  --git a/libc/src/sys/wait/CMakeLists.txt b/libc/src/sys/wait/CMakeLists.txt
index 9731d7daa361a..eb572b0618e33 100644
--- a/libc/src/sys/wait/CMakeLists.txt
+++ b/libc/src/sys/wait/CMakeLists.txt
@@ -8,3 +8,17 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.wait
 )
+
+add_entrypoint_object(
+  wait4
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.wait4
+)
+
+add_entrypoint_object(
+  waitpid
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.waitpid
+)

diff  --git a/libc/src/sys/wait/linux/CMakeLists.txt b/libc/src/sys/wait/linux/CMakeLists.txt
index 88e6f34fba692..89f10ec68579a 100644
--- a/libc/src/sys/wait/linux/CMakeLists.txt
+++ b/libc/src/sys/wait/linux/CMakeLists.txt
@@ -11,3 +11,31 @@ add_entrypoint_object(
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
 )
+
+add_entrypoint_object(
+  wait4
+  SRCS
+    wait4.cpp
+  HDRS
+    ../wait4.h
+  DEPENDS
+    libc.include.errno
+    libc.include.sys_wait
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  waitpid
+  SRCS
+    waitpid.cpp
+  HDRS
+    ../waitpid.h
+  DEPENDS
+    libc.include.errno
+    libc.include.sys_wait
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)

diff  --git a/libc/src/sys/wait/linux/wait4.cpp b/libc/src/sys/wait/linux/wait4.cpp
new file mode 100644
index 0000000000000..f52346cc47ade
--- /dev/null
+++ b/libc/src/sys/wait/linux/wait4.cpp
@@ -0,0 +1,31 @@
+//===-- Linux implementation of wait4 -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/wait/wait4.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+#include <sys/wait.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(pid_t, wait4,
+                   (pid_t pid, int *wait_status, int options,
+                    struct rusage *usage)) {
+  pid = __llvm_libc::syscall_impl(SYS_wait4, pid, wait_status, options, usage);
+  if (pid < 0) {
+    errno = -pid;
+    return -1;
+  }
+  return pid;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/sys/wait/linux/waitpid.cpp b/libc/src/sys/wait/linux/waitpid.cpp
new file mode 100644
index 0000000000000..f5e5d2b1bc1fd
--- /dev/null
+++ b/libc/src/sys/wait/linux/waitpid.cpp
@@ -0,0 +1,29 @@
+//===-- Linux implementation of waitpid -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/wait/waitpid.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+#include <sys/wait.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(pid_t, waitpid, (pid_t pid, int *wait_status, int options)) {
+  pid = __llvm_libc::syscall_impl(SYS_wait4, pid, wait_status, options, 0);
+  if (pid < 0) {
+    errno = -pid;
+    return -1;
+  }
+  return pid;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/sys/wait/wait4.h b/libc/src/sys/wait/wait4.h
new file mode 100644
index 0000000000000..91c01747ecbb5
--- /dev/null
+++ b/libc/src/sys/wait/wait4.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for wait4 -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_WAIT_WAIT4_H
+#define LLVM_LIBC_SRC_SYS_WAIT_WAIT4_H
+
+#include <sys/wait.h>
+
+namespace __llvm_libc {
+
+pid_t wait4(pid_t pid, int *waitstatus, int options, struct rusage *usage);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SYS_WAIT_WAIT4_H

diff  --git a/libc/src/sys/wait/waitpid.h b/libc/src/sys/wait/waitpid.h
new file mode 100644
index 0000000000000..1407c7f9b0ed5
--- /dev/null
+++ b/libc/src/sys/wait/waitpid.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for waitpid -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_WAIT_WAITPID_H
+#define LLVM_LIBC_SRC_SYS_WAIT_WAITPID_H
+
+#include <sys/wait.h>
+
+namespace __llvm_libc {
+
+pid_t waitpid(pid_t pid, int *waitstatus, int options);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SYS_WAIT_WAITPID_H

diff  --git a/libc/test/integration/src/unistd/CMakeLists.txt b/libc/test/integration/src/unistd/CMakeLists.txt
index 624f911cc9357..338e1ee04a2fa 100644
--- a/libc/test/integration/src/unistd/CMakeLists.txt
+++ b/libc/test/integration/src/unistd/CMakeLists.txt
@@ -16,5 +16,7 @@ add_integration_test(
     libc.include.unistd
     libc.src.signal.raise
     libc.src.sys.wait.wait
+    libc.src.sys.wait.wait4
+    libc.src.sys.wait.waitpid
     libc.src.unistd.fork
 )

diff  --git a/libc/test/integration/src/unistd/fork_test.cpp b/libc/test/integration/src/unistd/fork_test.cpp
index 0cf89f00b8729..e42dbcb96d36a 100644
--- a/libc/test/integration/src/unistd/fork_test.cpp
+++ b/libc/test/integration/src/unistd/fork_test.cpp
@@ -8,6 +8,8 @@
 
 #include "src/signal/raise.h"
 #include "src/sys/wait/wait.h"
+#include "src/sys/wait/wait4.h"
+#include "src/sys/wait/waitpid.h"
 #include "src/unistd/fork.h"
 
 #include "utils/IntegrationTest/test.h"
@@ -17,6 +19,11 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+// The tests wait4 and waitpid are present as tests for those functions
+// really and not for the fork function. They are here along with the tests
+// for fork because it is convenient to invoke and test them after forking
+// a child.
+
 void fork_and_wait_normal_exit() {
   pid_t pid = __llvm_libc::fork();
   if (pid == 0)
@@ -29,6 +36,33 @@ void fork_and_wait_normal_exit() {
   ASSERT_TRUE(WIFEXITED(status));
 }
 
+void fork_and_wait4_normal_exit() {
+  pid_t pid = __llvm_libc::fork();
+  if (pid == 0)
+    return; // Just end without any thing special.
+  ASSERT_TRUE(pid > 0);
+  int status;
+  struct rusage usage;
+  usage.ru_utime = {0, 0};
+  usage.ru_stime = {0, 0};
+  pid_t cpid = __llvm_libc::wait4(pid, &status, 0, &usage);
+  ASSERT_TRUE(cpid > 0);
+  ASSERT_EQ(cpid, pid);
+  ASSERT_TRUE(WIFEXITED(status));
+}
+
+void fork_and_waitpid_normal_exit() {
+  pid_t pid = __llvm_libc::fork();
+  if (pid == 0)
+    return; // Just end without any thing special.
+  ASSERT_TRUE(pid > 0);
+  int status;
+  pid_t cpid = __llvm_libc::waitpid(pid, &status, 0);
+  ASSERT_TRUE(cpid > 0);
+  ASSERT_EQ(cpid, pid);
+  ASSERT_TRUE(WIFEXITED(status));
+}
+
 void fork_and_wait_signal_exit() {
   pid_t pid = __llvm_libc::fork();
   if (pid == 0)
@@ -42,8 +76,41 @@ void fork_and_wait_signal_exit() {
   ASSERT_TRUE(WTERMSIG(status) == SIGUSR1);
 }
 
+void fork_and_wait4_signal_exit() {
+  pid_t pid = __llvm_libc::fork();
+  if (pid == 0)
+    __llvm_libc::raise(SIGUSR1);
+  ASSERT_TRUE(pid > 0);
+  int status;
+  struct rusage usage;
+  usage.ru_utime = {0, 0};
+  usage.ru_stime = {0, 0};
+  pid_t cpid = __llvm_libc::wait4(pid, &status, 0, &usage);
+  ASSERT_TRUE(cpid > 0);
+  ASSERT_EQ(cpid, pid);
+  ASSERT_FALSE(WIFEXITED(status));
+  ASSERT_TRUE(WTERMSIG(status) == SIGUSR1);
+}
+
+void fork_and_waitpid_signal_exit() {
+  pid_t pid = __llvm_libc::fork();
+  if (pid == 0)
+    __llvm_libc::raise(SIGUSR1);
+  ASSERT_TRUE(pid > 0);
+  int status;
+  pid_t cpid = __llvm_libc::waitpid(pid, &status, 0);
+  ASSERT_TRUE(cpid > 0);
+  ASSERT_EQ(cpid, pid);
+  ASSERT_FALSE(WIFEXITED(status));
+  ASSERT_TRUE(WTERMSIG(status) == SIGUSR1);
+}
+
 TEST_MAIN(int argc, char **argv, char **envp) {
   fork_and_wait_normal_exit();
+  fork_and_wait4_normal_exit();
+  fork_and_waitpid_normal_exit();
   fork_and_wait_signal_exit();
+  fork_and_wait4_signal_exit();
+  fork_and_waitpid_signal_exit();
   return 0;
 }

diff  --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index 7e6ab887b3107..f8e25cc8d4e54 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -3,3 +3,4 @@ add_subdirectory(resource)
 add_subdirectory(sendfile)
 add_subdirectory(stat)
 add_subdirectory(utsname)
+add_subdirectory(wait)

diff  --git a/libc/test/src/sys/wait/CMakeLists.txt b/libc/test/src/sys/wait/CMakeLists.txt
new file mode 100644
index 0000000000000..59176b8d6d7be
--- /dev/null
+++ b/libc/test/src/sys/wait/CMakeLists.txt
@@ -0,0 +1,25 @@
+add_libc_testsuite(libc_sys_wait_unittests)
+
+add_libc_unittest(
+  waitpid_test
+  SUITE
+    libc_sys_stat_unittests
+  SRCS
+    waitpid_test.cpp
+  DEPENDS
+    libc.include.errno
+    libc.include.sys_wait
+    libc.src.sys.wait.waitpid
+)
+
+add_libc_unittest(
+  wait4_test
+  SUITE
+    libc_sys_stat_unittests
+  SRCS
+    wait4_test.cpp
+  DEPENDS
+    libc.include.errno
+    libc.include.sys_wait
+    libc.src.sys.wait.wait4
+)

diff  --git a/libc/test/src/sys/wait/wait4_test.cpp b/libc/test/src/sys/wait/wait4_test.cpp
new file mode 100644
index 0000000000000..096db0019cb9e
--- /dev/null
+++ b/libc/test/src/sys/wait/wait4_test.cpp
@@ -0,0 +1,23 @@
+//===-- Unittests for wait4 -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/wait/wait4.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+#include <errno.h>
+#include <sys/wait.h>
+
+// The test here is a simpl test for WNOHANG functionality. For a more
+// involved test, look at fork_test.
+
+TEST(LlvmLibcwait4Test, NoHangTest) {
+  using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+  int status;
+  ASSERT_THAT(__llvm_libc::wait4(-1, &status, WNOHANG, nullptr), Fails(ECHILD));
+}

diff  --git a/libc/test/src/sys/wait/waitpid_test.cpp b/libc/test/src/sys/wait/waitpid_test.cpp
new file mode 100644
index 0000000000000..302be07baab26
--- /dev/null
+++ b/libc/test/src/sys/wait/waitpid_test.cpp
@@ -0,0 +1,23 @@
+//===-- Unittests for waitpid ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/wait/waitpid.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+#include <errno.h>
+#include <sys/wait.h>
+
+// The test here is a simpl test for WNOHANG functionality. For a more
+// involved test, look at fork_test.
+
+TEST(LlvmLibcWaitPidTest, NoHangTest) {
+  using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+  int status;
+  ASSERT_THAT(__llvm_libc::waitpid(-1, &status, WNOHANG), Fails(ECHILD));
+}


        


More information about the libc-commits mailing list