[libc-commits] [libc] Reland: [libc] implement ioctl ([libc] implement ioctl #85890) (PR #90317)
via libc-commits
libc-commits at lists.llvm.org
Sat Apr 27 00:05:55 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Nhat Nguyen (changkhothuychung)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/90317.diff
13 Files Affected:
- (modified) libc/config/linux/aarch64/entrypoints.txt (+3)
- (modified) libc/config/linux/riscv/entrypoints.txt (+3)
- (modified) libc/config/linux/x86_64/entrypoints.txt (+3)
- (modified) libc/spec/linux.td (+18)
- (modified) libc/src/sys/CMakeLists.txt (+1)
- (added) libc/src/sys/ioctl/CMakeLists.txt (+12)
- (added) libc/src/sys/ioctl/ioctl.h (+17)
- (added) libc/src/sys/ioctl/linux/CMakeLists.txt (+13)
- (added) libc/src/sys/ioctl/linux/ioctl.cpp (+39)
- (modified) libc/test/src/sys/CMakeLists.txt (+5-3)
- (added) libc/test/src/sys/ioctl/CMakeLists.txt (+3)
- (added) libc/test/src/sys/ioctl/linux/CMakeLists.txt (+13)
- (added) libc/test/src/sys/ioctl/linux/ioctl_test.cpp (+27)
``````````diff
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 78da7f0b334b1fe..b5f8454081c8984 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -204,6 +204,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 5aae4e246cfb3c2..da9f0a9fb5b506d 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -209,6 +209,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 5b428e51aee6206..923946a75a24f59 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -221,6 +221,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# https://github.com/llvm/llvm-project/issues/80060
# libc.src.sys.epoll.epoll_pwait2
+ # 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 f91f55ddac78466..6e9b64f5a6b4aff 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -79,6 +79,24 @@ def Linux : StandardSpec<"Linux"> {
[] // Functions
>;
+ HeaderSpec SysIoctl = 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/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index adc666b94202f7d..ac54df35284a7b8 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -1,5 +1,6 @@
add_subdirectory(auxv)
add_subdirectory(epoll)
+add_subdirectory(ioctl)
add_subdirectory(mman)
add_subdirectory(random)
add_subdirectory(resource)
diff --git a/libc/src/sys/ioctl/CMakeLists.txt b/libc/src/sys/ioctl/CMakeLists.txt
new file mode 100644
index 000000000000000..4b50c278c7871a8
--- /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 000000000000000..8365678276a4286
--- /dev/null
+++ b/libc/src/sys/ioctl/ioctl.h
@@ -0,0 +1,17 @@
+//===-- 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
+namespace LIBC_NAMESPACE {
+
+int ioctl(int fd, unsigned long request, ...);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
diff --git a/libc/src/sys/ioctl/linux/CMakeLists.txt b/libc/src/sys/ioctl/linux/CMakeLists.txt
new file mode 100644
index 000000000000000..8a23505d4e9d19e
--- /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 000000000000000..c743cf7a9dd5969
--- /dev/null
+++ b/libc/src/sys/ioctl/linux/ioctl.cpp
@@ -0,0 +1,39 @@
+//===---------- 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.
+// 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 ptr_to_memory;
+ va_start(ptr_to_memory, request);
+ 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.
+ if (ret < 0) {
+ libc_errno = -ret;
+ return -1;
+ }
+
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index dc0aa8bf7b75dc1..b58644e60f57872 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -1,4 +1,8 @@
+add_subdirectory(auxv)
+add_subdirectory(epoll)
+add_subdirectory(ioctl)
add_subdirectory(mman)
+add_subdirectory(prctl)
add_subdirectory(random)
add_subdirectory(resource)
add_subdirectory(select)
@@ -8,6 +12,4 @@ add_subdirectory(stat)
add_subdirectory(statvfs)
add_subdirectory(utsname)
add_subdirectory(wait)
-add_subdirectory(prctl)
-add_subdirectory(auxv)
-add_subdirectory(epoll)
+
diff --git a/libc/test/src/sys/ioctl/CMakeLists.txt b/libc/test/src/sys/ioctl/CMakeLists.txt
new file mode 100644
index 000000000000000..b4bbe81c92ff2eb
--- /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 000000000000000..aa1bffec16bd672
--- /dev/null
+++ b/libc/test/src/sys/ioctl/linux/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_custom_target(libc_sys_ioctl_unittests)
+
+add_libc_unittest(
+ ioctl_test
+ SUITE
+ libc_sys_ioctl_unittests
+ SRCS
+ ioctl_test.cpp
+ DEPENDS
+ libc.src.sys.ioctl.ioctl
+ libc.src.errno.errno
+)
+
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 000000000000000..4fc76d1b3c1842c
--- /dev/null
+++ b/libc/test/src/sys/ioctl/linux/ioctl_test.cpp
@@ -0,0 +1,27 @@
+//===-- 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 "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/LibcTest.h"
+#include "test/UnitTest/Test.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, request, NULL);
+ EXPECT_THAT(res, Fails(EBADF, -1));
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/90317
More information about the libc-commits
mailing list