[libc-commits] [libc] [libc] implement ioctl (PR #85890)

Nhat Nguyen via libc-commits libc-commits at lists.llvm.org
Wed Mar 27 17:32:13 PDT 2024


https://github.com/changkhothuychung updated https://github.com/llvm/llvm-project/pull/85890

>From b12e5c2daf39aed6523e0ce3e12494c25b6ed136 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Tue, 19 Mar 2024 22:37:54 -0400
Subject: [PATCH 1/6] initial commit

---
 libc/config/linux/aarch64/entrypoints.txt    |  3 ++
 libc/config/linux/riscv/entrypoints.txt      |  3 ++
 libc/config/linux/x86_64/entrypoints.txt     |  3 ++
 libc/spec/linux.td                           | 18 +++++++++
 libc/src/sys/ioctl/CMakeLists.txt            | 12 ++++++
 libc/src/sys/ioctl/ioctl.h                   | 20 ++++++++++
 libc/src/sys/ioctl/linux/CMakeLists.txt      | 13 +++++++
 libc/src/sys/ioctl/linux/ioctl.cpp           | 39 ++++++++++++++++++++
 libc/test/src/sys/ioctl/CMakeLists.txt       |  3 ++
 libc/test/src/sys/ioctl/linux/CMakeLists.txt | 14 +++++++
 libc/test/src/sys/ioctl/linux/ioctl_test.cpp | 29 +++++++++++++++
 11 files changed, 157 insertions(+)
 create mode 100644 libc/src/sys/ioctl/CMakeLists.txt
 create mode 100644 libc/src/sys/ioctl/ioctl.h
 create mode 100644 libc/src/sys/ioctl/linux/CMakeLists.txt
 create mode 100644 libc/src/sys/ioctl/linux/ioctl.cpp
 create mode 100644 libc/test/src/sys/ioctl/CMakeLists.txt
 create mode 100644 libc/test/src/sys/ioctl/linux/CMakeLists.txt
 create mode 100644 libc/test/src/sys/ioctl/linux/ioctl_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 52e9e8036a3fae..4c8ba6b169d2de 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -130,6 +130,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     #libc.src.stdio.scanf
     #libc.src.stdio.fscanf
 
+    # sys/ioctl.h entrypoints
+    libc.src.sys.ioctl.ioctl
+
     # sys/mman.h entrypoints
     libc.src.sys.mman.madvise
     libc.src.sys.mman.mmap
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 52ca12121812d1..64a2732dde5b7a 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -136,6 +136,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.scanf
     libc.src.stdio.fscanf
 
+    # sys/ioctl.h entrypoints
+    libc.src.sys.ioctl.ioctl
+
     # sys/mman.h entrypoints
     libc.src.sys.mman.madvise
     libc.src.sys.mman.mmap
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index ab105e1d634472..fbfb3683197600 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -136,6 +136,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdio.scanf
     libc.src.stdio.fscanf
 
+    # sys/ioctl.h entrypoints
+    libc.src.sys.ioctl.ioctl
+
     # sys/mman.h entrypoints
     libc.src.sys.mman.madvise
     libc.src.sys.mman.mmap
diff --git a/libc/spec/linux.td b/libc/spec/linux.td
index ba5f99c12ecd11..1c6ada3ac35830 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -74,6 +74,24 @@ def Linux : StandardSpec<"Linux"> {
       []  // Functions
   >;
 
+  HeaderSpec SysMMan = HeaderSpec<
+      "sys/ioctl.h",
+      [Macro<"MAP_ANONYMOUS">],
+      [], // Types
+      [], // Enumerations
+      [
+        FunctionSpec<
+            "ioctl",
+            RetValSpec<IntType>,
+            [
+              ArgSpec<IntType>,
+              ArgSpec<UnsignedLongType>,
+              ArgSpec<VoidPtr>,
+            ]
+        >,
+      ]  // Functions
+  >;
+
   HeaderSpec SysMMan = HeaderSpec<
       "sys/mman.h",
       [Macro<"MAP_ANONYMOUS">]
diff --git a/libc/src/sys/ioctl/CMakeLists.txt b/libc/src/sys/ioctl/CMakeLists.txt
new file mode 100644
index 00000000000000..4b50c278c7871a
--- /dev/null
+++ b/libc/src/sys/ioctl/CMakeLists.txt
@@ -0,0 +1,12 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+  ioctl
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.ioctl
+)
+
+
diff --git a/libc/src/sys/ioctl/ioctl.h b/libc/src/sys/ioctl/ioctl.h
new file mode 100644
index 00000000000000..660505ace4d13e
--- /dev/null
+++ b/libc/src/sys/ioctl/ioctl.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for mmap function -----------------*- 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_IOCTL_IOCTL_H
+#define LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
+
+#include <sys/mman.h> // For size_t and off_t
+
+namespace LIBC_NAMESPACE {
+
+int ioctl(int fd, unsigned long request, ...);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MMAP_H
diff --git a/libc/src/sys/ioctl/linux/CMakeLists.txt b/libc/src/sys/ioctl/linux/CMakeLists.txt
new file mode 100644
index 00000000000000..8a23505d4e9d19
--- /dev/null
+++ b/libc/src/sys/ioctl/linux/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_entrypoint_object(
+  ioctl
+  SRCS
+    ioctl.cpp
+  HDRS
+    ../ioctl.h
+  DEPENDS
+    libc.include.sys_ioctl
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
diff --git a/libc/src/sys/ioctl/linux/ioctl.cpp b/libc/src/sys/ioctl/linux/ioctl.cpp
new file mode 100644
index 00000000000000..6df254e4fea8cf
--- /dev/null
+++ b/libc/src/sys/ioctl/linux/ioctl.cpp
@@ -0,0 +1,39 @@
+//===---------- Linux implementation of the POSIX madvise function --------===//
+//
+// 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/ioctl/ioctl.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include "src/errno/libc_errno.h"
+#include <stdarg.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+// This function is currently linux only. It has to be refactored suitably if
+// madvise is to be supported on non-linux operating systems also.
+LLVM_LIBC_FUNCTION(int, ioctl, (int fd, unsigned long request, ...)) {
+  va_list ptrToMemory;
+  va_start(ptrToMemory, 1);
+  va_arg(ptrToMemory, void *) int ret =
+      LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, request, ptrToMemory);
+  va_end(ptrToMemory);
+
+  // A negative return value indicates an error with the magnitude of the
+  // value being the error code.
+  if (ret < 0) {
+    libc_errno = -ret;
+    return -1;
+  }
+
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/sys/ioctl/CMakeLists.txt b/libc/test/src/sys/ioctl/CMakeLists.txt
new file mode 100644
index 00000000000000..b4bbe81c92ff2e
--- /dev/null
+++ b/libc/test/src/sys/ioctl/CMakeLists.txt
@@ -0,0 +1,3 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${LIBC_TARGET_OS})
+endif()
diff --git a/libc/test/src/sys/ioctl/linux/CMakeLists.txt b/libc/test/src/sys/ioctl/linux/CMakeLists.txt
new file mode 100644
index 00000000000000..d1defd3b031be6
--- /dev/null
+++ b/libc/test/src/sys/ioctl/linux/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_custom_target(libc_sys_mman_unittests)
+
+add_libc_unittest(
+  ioctl_test
+  SUITE
+    libc_sys_mman_unittests
+  SRCS
+    ioctl_test.cpp
+  DEPENDS
+    libc.include.sys_ioctl
+    libc.src.errno.errno
+    libc.test.errno_setter_matcher
+)
+
diff --git a/libc/test/src/sys/ioctl/linux/ioctl_test.cpp b/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
new file mode 100644
index 00000000000000..d53510294ccce1
--- /dev/null
+++ b/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
@@ -0,0 +1,29 @@
+//===-- Unittests for ioctl ---------------------------------------------===//
+//
+// 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/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/errno/libc_errno.h"
+#include "src/sys/ioctl/ioctl.h"
+#include "src/unistd/sysconf.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include "test/UnitTest/Test.h"
+
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+TEST(LlvmLibcIoctlTest, InvalidFileDescriptor) {
+  int fd = 10;
+  unsigned long request = 10;
+  int res = LIBC_NAMESPACE::ioctl(fd, 10, NULL);
+  EXPECT_THAT(res, Fails(EBADF, -1));
+}
\ No newline at end of file

>From c771c2774b7fdb4f3f2dd7df503c473b01f5ca86 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Sun, 24 Mar 2024 15:18:04 -0400
Subject: [PATCH 2/6] address comments

---
 libc/spec/linux.td                           | 2 +-
 libc/src/sys/CMakeLists.txt                  | 1 +
 libc/src/sys/ioctl/ioctl.h                   | 2 +-
 libc/src/sys/ioctl/linux/ioctl.cpp           | 2 +-
 libc/test/src/sys/ioctl/linux/CMakeLists.txt | 4 ++--
 libc/test/src/sys/ioctl/linux/ioctl_test.cpp | 2 +-
 6 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/libc/spec/linux.td b/libc/spec/linux.td
index 1c6ada3ac35830..7faf739433d9f2 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -74,7 +74,7 @@ def Linux : StandardSpec<"Linux"> {
       []  // Functions
   >;
 
-  HeaderSpec SysMMan = HeaderSpec<
+  HeaderSpec SysIoctl = HeaderSpec<
       "sys/ioctl.h",
       [Macro<"MAP_ANONYMOUS">],
       [], // Types
diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index bf869ddc6a23cd..2e7527f38e9406 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(ioctl)
 add_subdirectory(mman)
 add_subdirectory(random)
 add_subdirectory(resource)
diff --git a/libc/src/sys/ioctl/ioctl.h b/libc/src/sys/ioctl/ioctl.h
index 660505ace4d13e..250365181d27de 100644
--- a/libc/src/sys/ioctl/ioctl.h
+++ b/libc/src/sys/ioctl/ioctl.h
@@ -17,4 +17,4 @@ int ioctl(int fd, unsigned long request, ...);
 
 } // namespace LIBC_NAMESPACE
 
-#endif // LLVM_LIBC_SRC_SYS_MMAN_MMAP_H
+#endif // LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
diff --git a/libc/src/sys/ioctl/linux/ioctl.cpp b/libc/src/sys/ioctl/linux/ioctl.cpp
index 6df254e4fea8cf..f89e91ccd20a4c 100644
--- a/libc/src/sys/ioctl/linux/ioctl.cpp
+++ b/libc/src/sys/ioctl/linux/ioctl.cpp
@@ -1,4 +1,4 @@
-//===---------- Linux implementation of the POSIX madvise function --------===//
+//===---------- Linux implementation of the POSIX ioctl function --------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/test/src/sys/ioctl/linux/CMakeLists.txt b/libc/test/src/sys/ioctl/linux/CMakeLists.txt
index d1defd3b031be6..93e68975c4e1e2 100644
--- a/libc/test/src/sys/ioctl/linux/CMakeLists.txt
+++ b/libc/test/src/sys/ioctl/linux/CMakeLists.txt
@@ -1,9 +1,9 @@
-add_custom_target(libc_sys_mman_unittests)
+add_custom_target(libc_sys_ioctl_unittests)
 
 add_libc_unittest(
   ioctl_test
   SUITE
-    libc_sys_mman_unittests
+    libc_sys_ioctl_unittests
   SRCS
     ioctl_test.cpp
   DEPENDS
diff --git a/libc/test/src/sys/ioctl/linux/ioctl_test.cpp b/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
index d53510294ccce1..0d6c2ee491e961 100644
--- a/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
+++ b/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
@@ -26,4 +26,4 @@ TEST(LlvmLibcIoctlTest, InvalidFileDescriptor) {
   unsigned long request = 10;
   int res = LIBC_NAMESPACE::ioctl(fd, 10, NULL);
   EXPECT_THAT(res, Fails(EBADF, -1));
-}
\ No newline at end of file
+}

>From a9bdedd2fe015a4fb9381e0d5c185ffb3994e41e Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Tue, 26 Mar 2024 00:29:59 -0400
Subject: [PATCH 3/6] snake case

---
 libc/src/sys/ioctl/linux/ioctl.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libc/src/sys/ioctl/linux/ioctl.cpp b/libc/src/sys/ioctl/linux/ioctl.cpp
index f89e91ccd20a4c..9bcf69136121b7 100644
--- a/libc/src/sys/ioctl/linux/ioctl.cpp
+++ b/libc/src/sys/ioctl/linux/ioctl.cpp
@@ -20,11 +20,11 @@ namespace LIBC_NAMESPACE {
 // This function is currently linux only. It has to be refactored suitably if
 // madvise is to be supported on non-linux operating systems also.
 LLVM_LIBC_FUNCTION(int, ioctl, (int fd, unsigned long request, ...)) {
-  va_list ptrToMemory;
-  va_start(ptrToMemory, 1);
-  va_arg(ptrToMemory, void *) int ret =
-      LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, request, ptrToMemory);
-  va_end(ptrToMemory);
+  va_list ptr_to_memory;
+  va_start(ptr_to_memory, 1);
+  va_arg(ptr_to_memory, void *) int ret =
+      LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, request, ptr_to_memory);
+  va_end(ptr_to_memory);
 
   // A negative return value indicates an error with the magnitude of the
   // value being the error code.

>From c540adfebacfec182b1795399d03e970639eb4e4 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Wed, 27 Mar 2024 20:22:41 -0400
Subject: [PATCH 4/6] some changes

---
 libc/src/sys/ioctl/linux/ioctl.cpp           | 1 -
 libc/test/src/sys/ioctl/linux/ioctl_test.cpp | 4 +---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/libc/src/sys/ioctl/linux/ioctl.cpp b/libc/src/sys/ioctl/linux/ioctl.cpp
index 9bcf69136121b7..6c8ff54dc2aeef 100644
--- a/libc/src/sys/ioctl/linux/ioctl.cpp
+++ b/libc/src/sys/ioctl/linux/ioctl.cpp
@@ -10,7 +10,6 @@
 
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
-
 #include "src/errno/libc_errno.h"
 #include <stdarg.h>
 #include <sys/syscall.h> // For syscall numbers.
diff --git a/libc/test/src/sys/ioctl/linux/ioctl_test.cpp b/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
index 0d6c2ee491e961..3de3eff3e8d4c8 100644
--- a/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
+++ b/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
@@ -1,4 +1,4 @@
-//===-- Unittests for ioctl ---------------------------------------------===//
+//===-- Unittests for ioctl -----------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -9,12 +9,10 @@
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/errno/libc_errno.h"
 #include "src/sys/ioctl/ioctl.h"
-#include "src/unistd/sysconf.h"
 #include "test/UnitTest/ErrnoSetterMatcher.h"
 #include "test/UnitTest/LibcTest.h"
 #include "test/UnitTest/Test.h"
 
-#include <sys/mman.h>
 #include <sys/syscall.h>
 #include <unistd.h>
 

>From a73265f55f2dbd9ee21aaefe353d5c205cfb38a8 Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Wed, 27 Mar 2024 20:26:36 -0400
Subject: [PATCH 5/6] remove includes

---
 libc/src/sys/ioctl/ioctl.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libc/src/sys/ioctl/ioctl.h b/libc/src/sys/ioctl/ioctl.h
index 250365181d27de..2468f1481daa8e 100644
--- a/libc/src/sys/ioctl/ioctl.h
+++ b/libc/src/sys/ioctl/ioctl.h
@@ -9,7 +9,6 @@
 #ifndef LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
 #define LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
 
-#include <sys/mman.h> // For size_t and off_t
 
 namespace LIBC_NAMESPACE {
 

>From 475af7d5e2abac1af8a4a67d11def3f5959d8c8e Mon Sep 17 00:00:00 2001
From: changkhothuychung <nhat7203 at gmail.com>
Date: Wed, 27 Mar 2024 20:31:59 -0400
Subject: [PATCH 6/6] code formatter

---
 libc/src/sys/ioctl/ioctl.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libc/src/sys/ioctl/ioctl.h b/libc/src/sys/ioctl/ioctl.h
index 2468f1481daa8e..8365678276a428 100644
--- a/libc/src/sys/ioctl/ioctl.h
+++ b/libc/src/sys/ioctl/ioctl.h
@@ -8,8 +8,6 @@
 
 #ifndef LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
 #define LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
-
-
 namespace LIBC_NAMESPACE {
 
 int ioctl(int fd, unsigned long request, ...);



More information about the libc-commits mailing list