Skip to content

Commit 289a2c3

Browse files
[libc] implement ioctl (#85890)
This PR is to work on the issue #85275
1 parent 8dc006e commit 289a2c3

File tree

12 files changed

+152
-0
lines changed

12 files changed

+152
-0
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ set(TARGET_LIBC_ENTRYPOINTS
204204
#libc.src.stdio.scanf
205205
#libc.src.stdio.fscanf
206206

207+
# sys/ioctl.h entrypoints
208+
libc.src.sys.ioctl.ioctl
209+
207210
# sys/mman.h entrypoints
208211
libc.src.sys.mman.madvise
209212
libc.src.sys.mman.mmap

libc/config/linux/riscv/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ set(TARGET_LIBC_ENTRYPOINTS
209209
libc.src.stdio.scanf
210210
libc.src.stdio.fscanf
211211

212+
# sys/ioctl.h entrypoints
213+
libc.src.sys.ioctl.ioctl
214+
212215
# sys/mman.h entrypoints
213216
libc.src.sys.mman.madvise
214217
libc.src.sys.mman.mmap

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ set(TARGET_LIBC_ENTRYPOINTS
221221
# https://github.com/llvm/llvm-project/issues/80060
222222
# libc.src.sys.epoll.epoll_pwait2
223223

224+
# sys/ioctl.h entrypoints
225+
libc.src.sys.ioctl.ioctl
226+
224227
# sys/mman.h entrypoints
225228
libc.src.sys.mman.madvise
226229
libc.src.sys.mman.mmap

libc/spec/linux.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ def Linux : StandardSpec<"Linux"> {
7979
[] // Functions
8080
>;
8181

82+
HeaderSpec SysIoctl = HeaderSpec<
83+
"sys/ioctl.h",
84+
[Macro<"MAP_ANONYMOUS">],
85+
[], // Types
86+
[], // Enumerations
87+
[
88+
FunctionSpec<
89+
"ioctl",
90+
RetValSpec<IntType>,
91+
[
92+
ArgSpec<IntType>,
93+
ArgSpec<UnsignedLongType>,
94+
ArgSpec<VoidPtr>,
95+
]
96+
>,
97+
] // Functions
98+
>;
99+
82100
HeaderSpec SysMMan = HeaderSpec<
83101
"sys/mman.h",
84102
[Macro<"MAP_ANONYMOUS">],

libc/src/sys/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_subdirectory(auxv)
22
add_subdirectory(epoll)
3+
add_subdirectory(ioctl)
34
add_subdirectory(mman)
45
add_subdirectory(random)
56
add_subdirectory(resource)

libc/src/sys/ioctl/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
2+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
3+
endif()
4+
5+
add_entrypoint_object(
6+
ioctl
7+
ALIAS
8+
DEPENDS
9+
.${LIBC_TARGET_OS}.ioctl
10+
)
11+
12+

libc/src/sys/ioctl/ioctl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//===-- Implementation header for mmap function -----------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
10+
#define LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
11+
namespace LIBC_NAMESPACE {
12+
13+
int ioctl(int fd, unsigned long request, ...);
14+
15+
} // namespace LIBC_NAMESPACE
16+
17+
#endif // LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
add_entrypoint_object(
2+
ioctl
3+
SRCS
4+
ioctl.cpp
5+
HDRS
6+
../ioctl.h
7+
DEPENDS
8+
libc.include.sys_ioctl
9+
libc.include.sys_syscall
10+
libc.src.__support.OSUtil.osutil
11+
libc.src.errno.errno
12+
)
13+

libc/src/sys/ioctl/linux/ioctl.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===---------- Linux implementation of the POSIX ioctl function --------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/sys/ioctl/ioctl.h"
10+
11+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12+
#include "src/__support/common.h"
13+
#include "src/errno/libc_errno.h"
14+
#include <stdarg.h>
15+
#include <sys/syscall.h> // For syscall numbers.
16+
17+
namespace LIBC_NAMESPACE {
18+
19+
// This function is currently linux only. It has to be refactored suitably if
20+
// madvise is to be supported on non-linux operating systems also.
21+
LLVM_LIBC_FUNCTION(int, ioctl, (int fd, unsigned long request, ...)) {
22+
va_list ptr_to_memory;
23+
va_start(ptr_to_memory, 1);
24+
va_arg(ptr_to_memory, void *) int ret =
25+
LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, request, ptr_to_memory);
26+
va_end(ptr_to_memory);
27+
28+
// A negative return value indicates an error with the magnitude of the
29+
// value being the error code.
30+
if (ret < 0) {
31+
libc_errno = -ret;
32+
return -1;
33+
}
34+
35+
return 0;
36+
}
37+
38+
} // namespace LIBC_NAMESPACE
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
2+
add_subdirectory(${LIBC_TARGET_OS})
3+
endif()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
add_custom_target(libc_sys_ioctl_unittests)
2+
3+
add_libc_unittest(
4+
ioctl_test
5+
SUITE
6+
libc_sys_ioctl_unittests
7+
SRCS
8+
ioctl_test.cpp
9+
DEPENDS
10+
libc.include.sys_ioctl
11+
libc.src.errno.errno
12+
libc.test.errno_setter_matcher
13+
)
14+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===-- Unittests for ioctl -----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
10+
#include "src/errno/libc_errno.h"
11+
#include "src/sys/ioctl/ioctl.h"
12+
#include "test/UnitTest/ErrnoSetterMatcher.h"
13+
#include "test/UnitTest/LibcTest.h"
14+
#include "test/UnitTest/Test.h"
15+
16+
#include <sys/syscall.h>
17+
#include <unistd.h>
18+
19+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
20+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
21+
22+
TEST(LlvmLibcIoctlTest, InvalidFileDescriptor) {
23+
int fd = 10;
24+
unsigned long request = 10;
25+
int res = LIBC_NAMESPACE::ioctl(fd, 10, NULL);
26+
EXPECT_THAT(res, Fails(EBADF, -1));
27+
}

0 commit comments

Comments
 (0)