[libc-commits] [libc] [libc][POSIX][poll.h] implement poll (PR #125118)

Nick Desaulniers via libc-commits libc-commits at lists.llvm.org
Thu Jan 30 15:52:15 PST 2025


https://github.com/nickdesaulniers updated https://github.com/llvm/llvm-project/pull/125118

>From 035836d3a78bd596ef093a76591bae322ca4f112 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 13:21:44 -0800
Subject: [PATCH 1/9] [libc][POSIX][poll.h] implement poll

Simple syscall.

Fixes: #124647
---
 libc/config/linux/x86_64/entrypoints.txt      |  3 +
 libc/hdr/types/CMakeLists.txt                 | 16 +++++
 libc/hdr/types/nfds_t.h                       | 23 +++++++
 libc/hdr/types/struct_pollfd.h                | 23 +++++++
 libc/include/CMakeLists.txt                   | 10 +++
 libc/include/llvm-libc-macros/CMakeLists.txt  |  6 ++
 .../llvm-libc-macros/linux/CMakeLists.txt     |  6 ++
 .../llvm-libc-macros/linux/poll-macros.h      | 65 +++++++++++++++++++
 libc/include/llvm-libc-macros/poll-macros.h   | 16 +++++
 libc/include/llvm-libc-types/CMakeLists.txt   | 10 +--
 libc/include/llvm-libc-types/nfds_t.h         | 14 ++++
 libc/include/llvm-libc-types/struct_pollfd.h  | 18 +++++
 libc/include/poll.yaml                        | 16 +++++
 libc/src/CMakeLists.txt                       |  1 +
 libc/src/poll/linux/CMakeLists.txt            | 14 ++++
 libc/src/poll/linux/poll.cpp                  | 31 +++++++++
 libc/src/poll/poll.h                          | 22 +++++++
 libc/test/src/CMakeLists.txt                  |  1 +
 libc/test/src/poll/poll_test.cpp              | 18 +++++
 19 files changed, 309 insertions(+), 4 deletions(-)
 create mode 100644 libc/hdr/types/nfds_t.h
 create mode 100644 libc/hdr/types/struct_pollfd.h
 create mode 100644 libc/include/llvm-libc-macros/linux/poll-macros.h
 create mode 100644 libc/include/llvm-libc-macros/poll-macros.h
 create mode 100644 libc/include/llvm-libc-types/nfds_t.h
 create mode 100644 libc/include/llvm-libc-types/struct_pollfd.h
 create mode 100644 libc/include/poll.yaml
 create mode 100644 libc/src/poll/linux/CMakeLists.txt
 create mode 100644 libc/src/poll/linux/poll.cpp
 create mode 100644 libc/src/poll/poll.h
 create mode 100644 libc/test/src/poll/poll_test.cpp

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 366e4d34294d15..b8600059430f85 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -32,6 +32,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.fcntl.open
     libc.src.fcntl.openat
 
+    # poll.h entrypoints
+    libc.src.poll.poll
+
     # sched.h entrypoints
     libc.src.sched.sched_get_priority_max
     libc.src.sched.sched_get_priority_min
diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 3dfa38a020fad0..dfc90009ef54a8 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -342,3 +342,19 @@ add_proxy_header_library(
     libc.include.llvm-libc-types.struct_iovec
     libc.include.sys_uio
 )
+
+add_proxy_header_library(
+  nfds_t
+  HDRS
+    nfds_t.h
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-types.nfds_t
+)
+
+add_proxy_header_library(
+  struct_pollfd
+  HDRS
+    struct_pollfd.h
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-types.struct_pollfd
+)
diff --git a/libc/hdr/types/nfds_t.h b/libc/hdr/types/nfds_t.h
new file mode 100644
index 00000000000000..9143564c2333e7
--- /dev/null
+++ b/libc/hdr/types/nfds_t.h
@@ -0,0 +1,23 @@
+//===-- Definition of nfds_t ----------------------------------------------===//
+//
+// 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_HDR_TYPES_NFDS_T_H
+#define LLVM_LIBC_HDR_TYPES_NFDS_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/nfds_t.h"
+
+#else // overlay mode
+
+#include <poll.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_NFDS_T_H
diff --git a/libc/hdr/types/struct_pollfd.h b/libc/hdr/types/struct_pollfd.h
new file mode 100644
index 00000000000000..efec6fc80ac109
--- /dev/null
+++ b/libc/hdr/types/struct_pollfd.h
@@ -0,0 +1,23 @@
+//===-- Definition of struct pollfd ---------------------------------------===//
+//
+// 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_HDR_TYPES_STRUCT_POLLFD_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_POLLFD_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_pollfd.h"
+
+#else // overlay mode
+
+#include <poll.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_POLLFD_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index e5ceea360d3965..624f83a4ec2834 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -704,6 +704,16 @@ add_header_macro(
     .llvm-libc-types.struct_lconv
 )
 
+add_header_macro(
+  poll
+  ../libc/include/poll.yaml
+  poll.h
+  DEPENDS
+    .llvm-libc-types.struct_pollfd
+    .llvm-libc-types.nfds_t
+    .llvm-libc-macros.poll-macros
+  )
+
 if(NOT LLVM_LIBC_FULL_BUILD)
   # We don't install headers in non-fullbuild mode.
   return()
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index 9d5d9f65442889..441b550543f67d 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -321,3 +321,9 @@ add_macro_header(
   HDR
     pthread-macros.h
 )
+
+add_macro_header(
+  poll-macros
+  HDR
+    poll-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index 461b190c02eacf..61da55eabd40ba 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -10,6 +10,12 @@ add_header(
     fcntl-macros.h
 )
 
+add_header(
+  poll-macros
+  HDR
+    poll-macros.h
+)
+
 add_header(
   sched_macros
   HDR
diff --git a/libc/include/llvm-libc-macros/linux/poll-macros.h b/libc/include/llvm-libc-macros/linux/poll-macros.h
new file mode 100644
index 00000000000000..6c6d026728d3fa
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/poll-macros.h
@@ -0,0 +1,65 @@
+//===-- Macros defined in poll.h header file ------------------------------===//
+//
+// 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_MACROS_LINUX_POLL_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_POLL_MACROS_H
+
+// From asm-generic/poll.h, redefined here to avoid redeclaring struct pollfd.
+#ifndef POLLIN
+#define POLLIN          0x0001
+#endif
+
+#ifndef POLLPRI
+#define POLLPRI         0x0002
+#endif
+
+#ifndef POLLOUT
+#define POLLOUT         0x0004
+#endif
+
+#ifndef POLLERR
+#define POLLERR         0x0008
+#endif
+
+#ifndef POLLHUP
+#define POLLHUP         0x0010
+#endif
+
+#ifndef POLLNVAL
+#define POLLNVAL        0x0020
+#endif
+
+#ifndef POLLRDNORM
+#define POLLRDNORM      0x0040
+#endif
+
+#ifndef POLLRDBAND
+#define POLLRDBAND      0x0080
+#endif
+
+#ifndef POLLWRNORM
+#define POLLWRNORM      0x0100
+#endif
+
+#ifndef POLLWRBAND
+#define POLLWRBAND      0x0200
+#endif
+
+#ifndef POLLMSG
+#define POLLMSG         0x0400
+#endif
+
+#ifndef POLLREMOVE
+#define POLLREMOVE      0x1000
+#endif
+
+#ifndef POLLRDHUP
+#define POLLRDHUP       0x2000
+#endif
+
+#endif // LLVM_LIBC_MACROS_LINUX_POLL_MACROS_H
diff --git a/libc/include/llvm-libc-macros/poll-macros.h b/libc/include/llvm-libc-macros/poll-macros.h
new file mode 100644
index 00000000000000..52b59a978a21f7
--- /dev/null
+++ b/libc/include/llvm-libc-macros/poll-macros.h
@@ -0,0 +1,16 @@
+//===-- Macros defined in poll.h header file ------------------------------===//
+//
+// 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_MACROS_POLL_MACROS_H
+#define LLVM_LIBC_MACROS_POLL_MACROS_H
+
+#ifdef __linux__
+#include "linux/poll-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_POLL_MACROS_H
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 6cbaa1ac0b30c3..9e8d2f818d4ed4 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -44,6 +44,7 @@ add_header(jmp_buf HDR jmp_buf.h)
 add_header(mbstate_t HDR mbstate_t.h)
 add_header(mode_t HDR mode_t.h)
 add_header(mtx_t HDR mtx_t.h DEPENDS .__futex_word .__mutex_type)
+add_header(nfds_t HDR nfds_t.h)
 add_header(nlink_t HDR nlink_t.h)
 add_header(off_t HDR off_t.h)
 add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
@@ -67,14 +68,15 @@ else()
 endif()
 add_header(stack_t HDR stack_t.h DEPENDS .size_t)
 add_header(suseconds_t HDR suseconds_t.h)
+add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
+add_header(struct_f_owner_ex HDR struct_f_owner_ex.h DEPENDS .pid_t)
 add_header(struct_flock HDR struct_flock.h DEPENDS .off_t .pid_t)
 add_header(struct_flock64 HDR struct_flock64.h DEPENDS .off64_t .pid_t)
-add_header(struct_f_owner_ex HDR struct_f_owner_ex.h DEPENDS .pid_t)
-add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t)
+add_header(struct_pollfd HDR struct_pollfd.h)
 add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
-add_header(struct_rusage HDR struct_rusage.h DEPENDS .struct_timeval)
-add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
 add_header(struct_sched_param HDR struct_sched_param.h)
+add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t)
+add_header(struct_rusage HDR struct_rusage.h DEPENDS .struct_timeval)
 add_header(union_sigval HDR union_sigval.h)
 add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
 add_header(sig_atomic_t HDR sig_atomic_t.h)
diff --git a/libc/include/llvm-libc-types/nfds_t.h b/libc/include/llvm-libc-types/nfds_t.h
new file mode 100644
index 00000000000000..c0abccee8a7da9
--- /dev/null
+++ b/libc/include/llvm-libc-types/nfds_t.h
@@ -0,0 +1,14 @@
+//===-- Definition of type nfds_t -----------------------------------------===//
+//
+// 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_NFDS_T_H
+#define LLVM_LIBC_TYPES_NFDS_T_H
+
+typedef unsigned int nfds_t;
+
+#endif // LLVM_LIBC_TYPES_NFDS_T_H
diff --git a/libc/include/llvm-libc-types/struct_pollfd.h b/libc/include/llvm-libc-types/struct_pollfd.h
new file mode 100644
index 00000000000000..80abc8e76efc64
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_pollfd.h
@@ -0,0 +1,18 @@
+//===-- Definition of type struct pollfd ----------------------------------===//
+//
+// 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_POLLFD_H
+#define LLVM_LIBC_TYPES_STRUCT_POLLFD_H
+
+struct pollfd {
+  int fd;
+  short events;
+  short revents;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_POLLFD_H
diff --git a/libc/include/poll.yaml b/libc/include/poll.yaml
new file mode 100644
index 00000000000000..399cc91854cdf6
--- /dev/null
+++ b/libc/include/poll.yaml
@@ -0,0 +1,16 @@
+header: poll.h
+header_template: poll.h.def
+macros: []
+types:
+  - type_name: struct_pollfd
+  - type_name: nfds_t
+enums: []
+functions:
+  - name: poll
+    standards:
+      - posix
+    return_type: int
+    arguments:
+      - type: struct pollfd *
+      - type: nfds_t
+      - type: int
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 41183429f67a75..19a354ceee4b65 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -20,6 +20,7 @@ add_subdirectory(unistd)
 if(${LIBC_TARGET_OS} STREQUAL "linux")
   add_subdirectory(dirent)
   add_subdirectory(fcntl)
+  add_subdirectory(poll)
   add_subdirectory(pthread)
   add_subdirectory(sched)
   add_subdirectory(sys)
diff --git a/libc/src/poll/linux/CMakeLists.txt b/libc/src/poll/linux/CMakeLists.txt
new file mode 100644
index 00000000000000..f12589381f1638
--- /dev/null
+++ b/libc/src/poll/linux/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_entrypoint_object(
+  poll
+  SRCS
+    poll.cpp
+  HDRS
+    ../poll.h
+  DEPENDS
+    libc.hdr.types.nfds_t
+    libc.hdr.types.struct_pollfd
+    libc.include.poll
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
diff --git a/libc/src/poll/linux/poll.cpp b/libc/src/poll/linux/poll.cpp
new file mode 100644
index 00000000000000..4e3ec6de6d6b49
--- /dev/null
+++ b/libc/src/poll/linux/poll.cpp
@@ -0,0 +1,31 @@
+//===-- Implementation of poll --------------------------------------------===//
+//
+// 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/poll/poll.h"
+
+#include "hdr/types/nfds_t.h"
+#include "hdr/types/struct_pollfd.h"
+#include "src/__support/OSUtil/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/errno/libc_errno.h"
+
+#include <sys/syscall.h> // SYS_poll
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, poll, (struct pollfd *fds, nfds_t nfds, int timeout)) {
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_poll, fds, nfds, timeout);
+  if (ret < 0) {
+    libc_errno = -ret;
+    return -1;
+  }
+  return ret;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/poll/poll.h b/libc/src/poll/poll.h
new file mode 100644
index 00000000000000..5fe4c2beec1d32
--- /dev/null
+++ b/libc/src/poll/poll.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for poll ----------------------------*-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_POLL_POLL_H
+#define LLVM_LIBC_SRC_POLL_POLL_H
+
+#include "hdr/types/nfds_t.h"
+#include "hdr/types/struct_pollfd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int poll(struct pollfd *fds, nfds_t nfds, int timeout);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif //  LLVM_LIBC_SRC_POLL_POLL_H
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index a8f779ff651315..b7c145788c0cdc 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -77,6 +77,7 @@ add_subdirectory(inttypes)
 
 if(${LIBC_TARGET_OS} STREQUAL "linux")
   add_subdirectory(fcntl)
+  add_subdirectory(poll)
   add_subdirectory(sched)
   add_subdirectory(sys)
   add_subdirectory(termios)
diff --git a/libc/test/src/poll/poll_test.cpp b/libc/test/src/poll/poll_test.cpp
new file mode 100644
index 00000000000000..5519dd5607bb5e
--- /dev/null
+++ b/libc/test/src/poll/poll_test.cpp
@@ -0,0 +1,18 @@
+//===-- Unittests for poll ------------------------------------------------===//
+//
+// 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/errno/libc_errno.h"
+#include "src/poll/poll.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcPollTest, SmokeTest) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  int ret = LIBC_NAMESPACE::poll(nullptr, 0, 0);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_EQ(0, ret);
+}

>From f5527d90b4c8be78a98a13e7ebf0691612a5602d Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 13:28:37 -0800
Subject: [PATCH 2/9] reformat

---
 .../llvm-libc-macros/linux/poll-macros.h      | 26 +++++++++----------
 libc/src/poll/linux/poll.cpp                  |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/libc/include/llvm-libc-macros/linux/poll-macros.h b/libc/include/llvm-libc-macros/linux/poll-macros.h
index 6c6d026728d3fa..d6724c5ee32119 100644
--- a/libc/include/llvm-libc-macros/linux/poll-macros.h
+++ b/libc/include/llvm-libc-macros/linux/poll-macros.h
@@ -11,55 +11,55 @@
 
 // From asm-generic/poll.h, redefined here to avoid redeclaring struct pollfd.
 #ifndef POLLIN
-#define POLLIN          0x0001
+#define POLLIN 0x0001
 #endif
 
 #ifndef POLLPRI
-#define POLLPRI         0x0002
+#define POLLPRI 0x0002
 #endif
 
 #ifndef POLLOUT
-#define POLLOUT         0x0004
+#define POLLOUT 0x0004
 #endif
 
 #ifndef POLLERR
-#define POLLERR         0x0008
+#define POLLERR 0x0008
 #endif
 
 #ifndef POLLHUP
-#define POLLHUP         0x0010
+#define POLLHUP 0x0010
 #endif
 
 #ifndef POLLNVAL
-#define POLLNVAL        0x0020
+#define POLLNVAL 0x0020
 #endif
 
 #ifndef POLLRDNORM
-#define POLLRDNORM      0x0040
+#define POLLRDNORM 0x0040
 #endif
 
 #ifndef POLLRDBAND
-#define POLLRDBAND      0x0080
+#define POLLRDBAND 0x0080
 #endif
 
 #ifndef POLLWRNORM
-#define POLLWRNORM      0x0100
+#define POLLWRNORM 0x0100
 #endif
 
 #ifndef POLLWRBAND
-#define POLLWRBAND      0x0200
+#define POLLWRBAND 0x0200
 #endif
 
 #ifndef POLLMSG
-#define POLLMSG         0x0400
+#define POLLMSG 0x0400
 #endif
 
 #ifndef POLLREMOVE
-#define POLLREMOVE      0x1000
+#define POLLREMOVE 0x1000
 #endif
 
 #ifndef POLLRDHUP
-#define POLLRDHUP       0x2000
+#define POLLRDHUP 0x2000
 #endif
 
 #endif // LLVM_LIBC_MACROS_LINUX_POLL_MACROS_H
diff --git a/libc/src/poll/linux/poll.cpp b/libc/src/poll/linux/poll.cpp
index 4e3ec6de6d6b49..2a3a13b3876783 100644
--- a/libc/src/poll/linux/poll.cpp
+++ b/libc/src/poll/linux/poll.cpp
@@ -19,7 +19,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(int, poll, (struct pollfd *fds, nfds_t nfds, int timeout)) {
+LLVM_LIBC_FUNCTION(int, poll, (struct pollfd * fds, nfds_t nfds, int timeout)) {
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_poll, fds, nfds, timeout);
   if (ret < 0) {
     libc_errno = -ret;

>From a860748c9d563f84bc5fdaad6528e10e08404767 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 13:46:45 -0800
Subject: [PATCH 3/9] SYS_ppoll fallback

---
 libc/config/linux/aarch64/entrypoints.txt |  3 +++
 libc/config/linux/arm/entrypoints.txt     |  3 +++
 libc/config/linux/riscv/entrypoints.txt   |  3 +++
 libc/src/poll/linux/CMakeLists.txt        |  1 +
 libc/src/poll/linux/poll.cpp              | 20 +++++++++++++++++++-
 5 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 09eb51a3f8fc62..9bac057f4d6b73 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -32,6 +32,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.fcntl.open
     libc.src.fcntl.openat
 
+    # poll.h entrypoints
+    libc.src.poll.poll
+
     # sched.h entrypoints
     libc.src.sched.sched_get_priority_max
     libc.src.sched.sched_get_priority_min
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 42ea803baac047..170525c5529a04 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -20,6 +20,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     # errno.h entrypoints
     libc.src.errno.errno
 
+    # poll.h entrypoints
+    libc.src.poll.poll
+
     # string.h entrypoints
     libc.src.string.memccpy
     libc.src.string.memchr
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 14a05a2f3fbf2a..b84c9b9e28e98b 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -32,6 +32,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.fcntl.open
     libc.src.fcntl.openat
 
+    # poll.h entrypoints
+    libc.src.poll.poll
+
     # sched.h entrypoints
     libc.src.sched.sched_get_priority_max
     libc.src.sched.sched_get_priority_min
diff --git a/libc/src/poll/linux/CMakeLists.txt b/libc/src/poll/linux/CMakeLists.txt
index f12589381f1638..672aafa920412e 100644
--- a/libc/src/poll/linux/CMakeLists.txt
+++ b/libc/src/poll/linux/CMakeLists.txt
@@ -7,6 +7,7 @@ add_entrypoint_object(
   DEPENDS
     libc.hdr.types.nfds_t
     libc.hdr.types.struct_pollfd
+    libc.hdr.types.struct_timespec
     libc.include.poll
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
diff --git a/libc/src/poll/linux/poll.cpp b/libc/src/poll/linux/poll.cpp
index 2a3a13b3876783..e730c429ad0aaa 100644
--- a/libc/src/poll/linux/poll.cpp
+++ b/libc/src/poll/linux/poll.cpp
@@ -10,17 +10,35 @@
 
 #include "hdr/types/nfds_t.h"
 #include "hdr/types/struct_pollfd.h"
+#include "hdr/types/struct_timespec.h"
 #include "src/__support/OSUtil/syscall.h" // syscall_impl
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/errno/libc_errno.h"
 
-#include <sys/syscall.h> // SYS_poll
+#include <sys/syscall.h> // SYS_poll, SYS_ppoll
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, poll, (struct pollfd * fds, nfds_t nfds, int timeout)) {
+
+#ifdef SYS_poll
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_poll, fds, nfds, timeout);
+#elif defined(SYS_ppoll)
+  struct timespec ts, *tsp;
+  if (timeout >= 0) {
+    ts.tv_sec = timeout / 1000;
+    ts.tv_nsec = (timeout % 1000) * 1000000;
+    tsp = &ts;
+  } else {
+    tsp = nullptr;
+  }
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ppoll, fds, nfds, tsp,
+                                              nullptr, 0);
+#else
+#error "SYS_ppoll_time64?"
+#endif
+
   if (ret < 0) {
     libc_errno = -ret;
     return -1;

>From 1d8cb3aae2f760eed9ce5d13524b91a48bffc947 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 15:16:00 -0800
Subject: [PATCH 4/9] git add cmake

---
 libc/src/poll/CMakeLists.txt | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 libc/src/poll/CMakeLists.txt

diff --git a/libc/src/poll/CMakeLists.txt b/libc/src/poll/CMakeLists.txt
new file mode 100644
index 00000000000000..65fbe46bb46128
--- /dev/null
+++ b/libc/src/poll/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+  poll
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.poll
+)

>From 19e043956d2926a405d1f261989176741e76ab6b Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 15:16:09 -0800
Subject: [PATCH 5/9] add failure test

---
 libc/test/src/poll/poll_test.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/libc/test/src/poll/poll_test.cpp b/libc/test/src/poll/poll_test.cpp
index 5519dd5607bb5e..30f5e41c61ecf7 100644
--- a/libc/test/src/poll/poll_test.cpp
+++ b/libc/test/src/poll/poll_test.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "hdr/limits_macros.h" // UINT_MAX
 #include "src/errno/libc_errno.h"
 #include "src/poll/poll.h"
 #include "test/UnitTest/Test.h"
@@ -16,3 +17,9 @@ TEST(LlvmLibcPollTest, SmokeTest) {
   ASSERT_ERRNO_SUCCESS();
   ASSERT_EQ(0, ret);
 }
+TEST(LlvmLibcPollTest, SmokeFailureTest) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  int ret = LIBC_NAMESPACE::poll(nullptr, UINT_MAX, 0);
+  ASSERT_ERRNO_EQ(EINVAL);
+  ASSERT_EQ(-1, ret);
+}

>From 86c978082ebe3a0f6caad53d7dd6c8c2b884df18 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 15:19:58 -0800
Subject: [PATCH 6/9] reformat

---
 libc/src/poll/linux/poll.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/src/poll/linux/poll.cpp b/libc/src/poll/linux/poll.cpp
index e730c429ad0aaa..bb20feb5d6eb5f 100644
--- a/libc/src/poll/linux/poll.cpp
+++ b/libc/src/poll/linux/poll.cpp
@@ -33,8 +33,8 @@ LLVM_LIBC_FUNCTION(int, poll, (struct pollfd * fds, nfds_t nfds, int timeout)) {
   } else {
     tsp = nullptr;
   }
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ppoll, fds, nfds, tsp,
-                                              nullptr, 0);
+  int ret =
+      LIBC_NAMESPACE::syscall_impl<int>(SYS_ppoll, fds, nfds, tsp, nullptr, 0);
 #else
 #error "SYS_ppoll_time64?"
 #endif

>From 6fc7519871b6fda58bb020f19cf93a134318bea5 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 15:39:06 -0800
Subject: [PATCH 7/9] fixup header emission

---
 libc/config/linux/aarch64/headers.txt |  9 +++++----
 libc/config/linux/x86_64/headers.txt  | 27 +++++++++++++--------------
 libc/src/poll/linux/CMakeLists.txt    |  1 -
 3 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 05f15a0e4e5cbb..4b64a514c30c35 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -8,30 +8,31 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.features
     libc.include.fenv
     libc.include.float
-    libc.include.stdint
     libc.include.inttypes
     libc.include.limits
     libc.include.link
     libc.include.malloc
     libc.include.math
+    libc.include.poll
     libc.include.pthread
+    libc.include.search
     libc.include.signal
-    libc.include.stdckdint
     libc.include.stdbit
+    libc.include.stdckdint
+    libc.include.stdint
     libc.include.stdio
     libc.include.stdlib
     libc.include.string
     libc.include.strings
-    libc.include.search
     libc.include.sys_mman
     libc.include.sys_socket
     libc.include.sys_syscall
     libc.include.sys_time
     libc.include.threads
     libc.include.time
+    libc.include.uchar
     libc.include.unistd
     libc.include.wchar
-    libc.include.uchar
 
     libc.include.sys_ioctl
     # Disabled due to epoll_wait syscalls not being available on this platform.
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index 8750100302ea7e..8d422698821bc1 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -1,4 +1,5 @@
 set(TARGET_PUBLIC_HEADERS
+    libc.include.arpa_inet
     libc.include.assert
     libc.include.complex
     libc.include.ctype
@@ -10,35 +11,27 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.features
     libc.include.fenv
     libc.include.float
-    libc.include.stdint
     libc.include.inttypes
     libc.include.limits
     libc.include.link
+    libc.include.locale
     libc.include.malloc
     libc.include.math
+    libc.include.poll
     libc.include.pthread
     libc.include.sched
+    libc.include.search
+    libc.include.setjmp
     libc.include.signal
     libc.include.spawn
-    libc.include.setjmp
-    libc.include.stdckdint
     libc.include.stdbit
+    libc.include.stdckdint
     libc.include.stdfix
+    libc.include.stdint
     libc.include.stdio
     libc.include.stdlib
     libc.include.string
     libc.include.strings
-    libc.include.search
-    libc.include.termios
-    libc.include.threads
-    libc.include.time
-    libc.include.unistd
-    libc.include.wchar
-    libc.include.uchar
-    libc.include.locale
-
-    libc.include.arpa_inet
-
     libc.include.sys_auxv
     libc.include.sys_epoll
     libc.include.sys_ioctl
@@ -56,4 +49,10 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_types
     libc.include.sys_utsname
     libc.include.sys_wait
+    libc.include.termios
+    libc.include.threads
+    libc.include.time
+    libc.include.uchar
+    libc.include.unistd
+    libc.include.wchar
 )
diff --git a/libc/src/poll/linux/CMakeLists.txt b/libc/src/poll/linux/CMakeLists.txt
index 672aafa920412e..a9ef596c36c893 100644
--- a/libc/src/poll/linux/CMakeLists.txt
+++ b/libc/src/poll/linux/CMakeLists.txt
@@ -8,7 +8,6 @@ add_entrypoint_object(
     libc.hdr.types.nfds_t
     libc.hdr.types.struct_pollfd
     libc.hdr.types.struct_timespec
-    libc.include.poll
     libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno

>From 7e24ed0f077227e3da23adfdfdf273e66339307e Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 15:40:23 -0800
Subject: [PATCH 8/9] git add another file I forgot

---
 libc/test/src/poll/CMakeLists.txt | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 libc/test/src/poll/CMakeLists.txt

diff --git a/libc/test/src/poll/CMakeLists.txt b/libc/test/src/poll/CMakeLists.txt
new file mode 100644
index 00000000000000..c4af14168b906d
--- /dev/null
+++ b/libc/test/src/poll/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_custom_target(libc_poll_unittests)
+
+add_libc_unittest(
+  poll_test
+  SUITE
+    libc_poll_unittests
+  SRCS
+    poll_test.cpp
+  DEPENDS
+    libc.hdr.limits_macros
+    libc.src.errno.errno
+    libc.src.poll.poll
+    libc.test.UnitTest.ErrnoSetterMatcher
+)

>From 576e644350dec331859823943c93cc7d57d92783 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 30 Jan 2025 15:51:17 -0800
Subject: [PATCH 9/9] one of these days, I'll remember to git add everything...

---
 libc/include/poll.h.def | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 libc/include/poll.h.def

diff --git a/libc/include/poll.h.def b/libc/include/poll.h.def
new file mode 100644
index 00000000000000..2f0e0376fa7bba
--- /dev/null
+++ b/libc/include/poll.h.def
@@ -0,0 +1,17 @@
+//===-- C standard library header poll.h ----------------------------------===//
+//
+// 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_POLL_H
+#define LLVM_LIBC_POLL_H
+
+#include "__llvm-libc-common.h"
+#include "llvm-libc-macros/poll-macros.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_POLL_H



More information about the libc-commits mailing list