diff options
author | Nhat Nguyen <nhat7203@gmail.com> | 2024-04-09 23:38:23 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-09 23:38:23 -0400 |
commit | 289a2c380e47d64a1e626259c53fc8c7d6c2be66 (patch) | |
tree | 76c3a626eb80fef17f33a2184974a64bcb23c918 | |
parent | 8dc006ea4008c1af298e56c4db6fffe2a40a2ba9 (diff) | |
download | llvm-289a2c380e47d64a1e626259c53fc8c7d6c2be66.zip llvm-289a2c380e47d64a1e626259c53fc8c7d6c2be66.tar.gz llvm-289a2c380e47d64a1e626259c53fc8c7d6c2be66.tar.bz2 |
[libc] implement ioctl (#85890)
This PR is to work on the issue #85275
-rw-r--r-- | libc/config/linux/aarch64/entrypoints.txt | 3 | ||||
-rw-r--r-- | libc/config/linux/riscv/entrypoints.txt | 3 | ||||
-rw-r--r-- | libc/config/linux/x86_64/entrypoints.txt | 3 | ||||
-rw-r--r-- | libc/spec/linux.td | 18 | ||||
-rw-r--r-- | libc/src/sys/CMakeLists.txt | 1 | ||||
-rw-r--r-- | libc/src/sys/ioctl/CMakeLists.txt | 12 | ||||
-rw-r--r-- | libc/src/sys/ioctl/ioctl.h | 17 | ||||
-rw-r--r-- | libc/src/sys/ioctl/linux/CMakeLists.txt | 13 | ||||
-rw-r--r-- | libc/src/sys/ioctl/linux/ioctl.cpp | 38 | ||||
-rw-r--r-- | libc/test/src/sys/ioctl/CMakeLists.txt | 3 | ||||
-rw-r--r-- | libc/test/src/sys/ioctl/linux/CMakeLists.txt | 14 | ||||
-rw-r--r-- | libc/test/src/sys/ioctl/linux/ioctl_test.cpp | 27 |
12 files changed, 152 insertions, 0 deletions
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index f5f5c43..5649e3c 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 7128978..6c71932 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 6bb53cb..5880ad5 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 f91f55d..6e9b64f 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 adc666b..ac54df3 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 0000000..4b50c27 --- /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 0000000..8365678 --- /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 0000000..8a23505 --- /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 0000000..6c8ff54 --- /dev/null +++ b/libc/src/sys/ioctl/linux/ioctl.cpp @@ -0,0 +1,38 @@ +//===---------- 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, 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. + 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 0000000..b4bbe81c --- /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 0000000..93e6897 --- /dev/null +++ b/libc/test/src/sys/ioctl/linux/CMakeLists.txt @@ -0,0 +1,14 @@ +add_custom_target(libc_sys_ioctl_unittests) + +add_libc_unittest( + ioctl_test + SUITE + libc_sys_ioctl_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 0000000..3de3eff --- /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, 10, NULL); + EXPECT_THAT(res, Fails(EBADF, -1)); +} |