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

via libc-commits libc-commits at lists.llvm.org
Wed Feb 5 13:24:43 PST 2025


Author: Nick Desaulniers
Date: 2025-02-05T13:24:39-08:00
New Revision: 8e35b3d29b35d854055503b213604138a4a17cb0

URL: https://github.com/llvm/llvm-project/commit/8e35b3d29b35d854055503b213604138a4a17cb0
DIFF: https://github.com/llvm/llvm-project/commit/8e35b3d29b35d854055503b213604138a4a17cb0.diff

LOG: [libc][POSIX][poll.h] implement poll (#125118)

Simple syscall.

Fixes: #124647

Added: 
    libc/hdr/types/nfds_t.h
    libc/hdr/types/struct_pollfd.h
    libc/include/llvm-libc-macros/linux/poll-macros.h
    libc/include/llvm-libc-macros/poll-macros.h
    libc/include/llvm-libc-types/nfds_t.h
    libc/include/llvm-libc-types/struct_pollfd.h
    libc/include/poll.h.def
    libc/include/poll.yaml
    libc/src/poll/CMakeLists.txt
    libc/src/poll/linux/CMakeLists.txt
    libc/src/poll/linux/poll.cpp
    libc/src/poll/poll.h
    libc/test/src/poll/CMakeLists.txt
    libc/test/src/poll/poll_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/aarch64/headers.txt
    libc/config/linux/arm/entrypoints.txt
    libc/config/linux/riscv/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/config/linux/x86_64/headers.txt
    libc/hdr/types/CMakeLists.txt
    libc/include/CMakeLists.txt
    libc/include/llvm-libc-macros/CMakeLists.txt
    libc/include/llvm-libc-macros/linux/CMakeLists.txt
    libc/include/llvm-libc-types/CMakeLists.txt
    libc/src/CMakeLists.txt
    libc/test/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 49e3c04b0ca16a..3119c59b93af88 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/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/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 4d1d87170208d0..c405172c8a13b7 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/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c8e0adaeee2827..b5b8389da97f6a 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/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/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..d6724c5ee32119
--- /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.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

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/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
+)

diff  --git a/libc/src/poll/linux/CMakeLists.txt b/libc/src/poll/linux/CMakeLists.txt
new file mode 100644
index 00000000000000..a9ef596c36c893
--- /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.hdr.types.struct_timespec
+    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..886e57ccd5942b
--- /dev/null
+++ b/libc/src/poll/linux/poll.cpp
@@ -0,0 +1,49 @@
+//===-- 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 "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, SYS_ppoll
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, poll, (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)
+  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;
+  }
+  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..ac3cc1d36a71d3
--- /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(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/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
+)

diff  --git a/libc/test/src/poll/poll_test.cpp b/libc/test/src/poll/poll_test.cpp
new file mode 100644
index 00000000000000..30f5e41c61ecf7
--- /dev/null
+++ b/libc/test/src/poll/poll_test.cpp
@@ -0,0 +1,25 @@
+//===-- 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 "hdr/limits_macros.h" // UINT_MAX
+#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);
+}
+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);
+}


        


More information about the libc-commits mailing list