Skip to content

Commit

Permalink
[libc] implement ioctl (llvm#85890)
Browse files Browse the repository at this point in the history
This PR is to work on the issue llvm#85275
  • Loading branch information
changkhothuychung committed Apr 10, 2024
1 parent 8dc006e commit 289a2c3
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 0 deletions.
3 changes: 3 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions libc/spec/linux.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">],
Expand Down
1 change: 1 addition & 0 deletions libc/src/sys/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_subdirectory(auxv)
add_subdirectory(epoll)
add_subdirectory(ioctl)
add_subdirectory(mman)
add_subdirectory(random)
add_subdirectory(resource)
Expand Down
12 changes: 12 additions & 0 deletions libc/src/sys/ioctl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
)


17 changes: 17 additions & 0 deletions libc/src/sys/ioctl/ioctl.h
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions libc/src/sys/ioctl/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
)

38 changes: 38 additions & 0 deletions libc/src/sys/ioctl/linux/ioctl.cpp
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions libc/test/src/sys/ioctl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()
14 changes: 14 additions & 0 deletions libc/test/src/sys/ioctl/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
)

27 changes: 27 additions & 0 deletions libc/test/src/sys/ioctl/linux/ioctl_test.cpp
Original file line number Diff line number Diff line change
@@ -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));
}

0 comments on commit 289a2c3

Please sign in to comment.