[libc] implement ioctl (#85890)

This PR is to work on the issue #85275
This commit is contained in:
Nhat Nguyen 2024-04-09 23:38:23 -04:00 committed by GitHub
parent 8dc006ea40
commit 289a2c380e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 152 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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">],

View File

@ -1,5 +1,6 @@
add_subdirectory(auxv)
add_subdirectory(epoll)
add_subdirectory(ioctl)
add_subdirectory(mman)
add_subdirectory(random)
add_subdirectory(resource)

View File

@ -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
)

View File

@ -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

View File

@ -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
)

View File

@ -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

View File

@ -0,0 +1,3 @@
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()

View File

@ -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
)

View File

@ -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));
}