Skip to content

Commit 5fad00a

Browse files
committed
[libc] add ioctl
1 parent b754e40 commit 5fad00a

File tree

13 files changed

+148
-0
lines changed

13 files changed

+148
-0
lines changed

libc/config/linux/aarch64/entrypoints.txt

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

248+
# sys/ioctl.h entrypoints
249+
libc.src.sys.ioctl.ioctl
250+
248251
# sys/mman.h entrypoints
249252
libc.src.sys.mman.madvise
250253
libc.src.sys.mman.mincore

libc/config/linux/arm/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ set(TARGET_LIBC_ENTRYPOINTS
172172
libc.src.stdlib.free
173173
libc.src.stdlib.malloc
174174

175+
# sys/ioctl.h entrypoints
176+
libc.src.sys.ioctl.ioctl
177+
175178
# sys/mman.h entrypoints
176179
libc.src.sys.mman.mmap
177180
libc.src.sys.mman.munmap

libc/config/linux/riscv/entrypoints.txt

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

249+
# sys/ioctl.h entrypoints
250+
libc.src.sys.ioctl.ioctl
251+
249252
# sys/mman.h entrypoints
250253
libc.src.sys.mman.madvise
251254
libc.src.sys.mman.mincore

libc/config/linux/x86_64/entrypoints.txt

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

249+
# sys/ioctl.h entrypoints
250+
libc.src.sys.ioctl.ioctl
251+
249252
# sys/mman.h entrypoints
250253
libc.src.sys.mman.madvise
251254
libc.src.sys.mman.mincore

libc/src/sys/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ add_subdirectory(utsname)
1313
add_subdirectory(wait)
1414
add_subdirectory(prctl)
1515
add_subdirectory(uio)
16+
add_subdirectory(ioctl)

libc/src/sys/ioctl/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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+
)

libc/src/sys/ioctl/ioctl.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for ioctl ---------------------------*-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+
12+
#include "src/__support/macros/config.h"
13+
#include <sys/ioctl.h>
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
int ioctl(int fd, unsigned long request, ...);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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+
)

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===---------- Linux implementation of the 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_DECL {
18+
19+
LLVM_LIBC_FUNCTION(int, ioctl, (int fd, unsigned long request, ...)) {
20+
va_list vargs;
21+
va_start(vargs, request);
22+
void *data_pointer = va_arg(vargs, void *);
23+
int ret =
24+
LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, request, data_pointer);
25+
va_end(vargs);
26+
27+
// From `man ioctl`:
28+
// "Usually, on success zero is returned. A few ioctl() operations
29+
// use the return value as an output parameter and return a
30+
// nonnegative value on success. On error, -1 is returned, and errno
31+
// is set to indicate the error."
32+
if (ret < 0) {
33+
libc_errno = -ret;
34+
return -1;
35+
}
36+
37+
return ret;
38+
}
39+
40+
} // namespace LIBC_NAMESPACE_DECL

libc/test/src/sys/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ add_subdirectory(auxv)
1313
add_subdirectory(epoll)
1414
add_subdirectory(uio)
1515
add_subdirectory(time)
16+
add_subdirectory(ioctl)
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.include.sys_filio
12+
libc.src.sys.ioctl.ioctl
13+
libc.src.errno.errno
14+
)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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/errno/libc_errno.h"
10+
#include "src/sys/ioctl/ioctl.h"
11+
#include "test/UnitTest/ErrnoSetterMatcher.h"
12+
#include <sys/filio.h>
13+
#include <sys/ioctl.h>
14+
15+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
16+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
17+
18+
TEST(LlvmLibcSysIoctlTest, StdinFIONREAD) {
19+
LIBC_NAMESPACE::libc_errno = 0;
20+
21+
// FIONREAD reports the number of readable bytes for fd
22+
int bytes;
23+
int ret = LIBC_NAMESPACE::ioctl(0, FIONREAD, &bytes);
24+
ASSERT_ERRNO_SUCCESS();
25+
}
26+
27+
TEST(LlvmLibcSysIoctlTest, InvalidCommandENOTTY) {
28+
LIBC_NAMESPACE::libc_errno = 0;
29+
30+
// 0xDEADBEEF is just a random nonexistent command;
31+
// calling this should always fail with ENOTTY
32+
int ret = LIBC_NAMESPACE::ioctl(3, 0xDEADBEEF, NULL);
33+
ASSERT_TRUE(ret == -1 && errno == ENOTTY);
34+
}

0 commit comments

Comments
 (0)