Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,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.mincore
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.stdlib.free
libc.src.stdlib.malloc

# sys/ioctl.h entrypoints
libc.src.sys.ioctl.ioctl

# sys/mman.h entrypoints
libc.src.sys.mman.mmap
libc.src.sys.mman.munmap
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 @@ -246,6 +246,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.mincore
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 @@ -246,6 +246,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.mincore
Expand Down
1 change: 1 addition & 0 deletions libc/src/sys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ add_subdirectory(utsname)
add_subdirectory(wait)
add_subdirectory(prctl)
add_subdirectory(uio)
add_subdirectory(ioctl)
10 changes: 10 additions & 0 deletions libc/src/sys/ioctl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
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
)
21 changes: 21 additions & 0 deletions libc/src/sys/ioctl/ioctl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for ioctl ---------------------------*-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

#include "src/__support/macros/config.h"
#include <sys/ioctl.h>

namespace LIBC_NAMESPACE_DECL {

int ioctl(int fd, unsigned long request, ...);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SYS_IOCTL_IOCTL_H
12 changes: 12 additions & 0 deletions libc/src/sys/ioctl/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
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
)
36 changes: 36 additions & 0 deletions libc/src/sys/ioctl/linux/ioctl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===---------- Linux implementation of the 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_DECL {

LLVM_LIBC_FUNCTION(int, ioctl, (int fd, unsigned long request, ...)) {
va_list vargs;
va_start(vargs, request);
void *data_pointer = va_arg(vargs, void *);
int ret =
LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, request, data_pointer);
va_end(vargs);

// Some ioctls can be expected to return positive values
if (ret >= 0)
return ret;

// If there is an error, errno is set and -1 is returned.
libc_errno = -ret;
return -1;
}

} // namespace LIBC_NAMESPACE_DECL
9 changes: 2 additions & 7 deletions libc/src/termios/linux/tcdrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,14 @@
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <sys/syscall.h> // For syscall numbers
#include <termios.h>

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, tcdrain, (int fd)) {
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, TCSBRK, 1);
if (ret < 0) {
libc_errno = -ret;
return -1;
}
return 0;
return LIBC_NAMESPACE::ioctl(fd, TCSBRK, 1);
}

} // namespace LIBC_NAMESPACE_DECL
9 changes: 2 additions & 7 deletions libc/src/termios/linux/tcflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,14 @@
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <sys/syscall.h> // For syscall numbers
#include <termios.h>

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, tcflow, (int fd, int action)) {
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, TCXONC, action);
if (ret < 0) {
libc_errno = -ret;
return -1;
}
return 0;
return LIBC_NAMESPACE::ioctl(fd, TCXONC, action);
}

} // namespace LIBC_NAMESPACE_DECL
10 changes: 2 additions & 8 deletions libc/src/termios/linux/tcflush.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,14 @@
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <sys/syscall.h> // For syscall numbers
#include <termios.h>

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, tcflush, (int fd, int queue_selector)) {
int ret =
LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, TCFLSH, queue_selector);
if (ret < 0) {
libc_errno = -ret;
return -1;
}
return 0;
return LIBC_NAMESPACE::ioctl(fd, TCFLSH, queue_selector);
}

} // namespace LIBC_NAMESPACE_DECL
9 changes: 4 additions & 5 deletions libc/src/termios/linux/tcgetattr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,18 @@
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <sys/syscall.h> // For syscall numbers
#include <termios.h>

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, tcgetattr, (int fd, struct termios *t)) {
LIBC_NAMESPACE::kernel_termios kt;
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, TCGETS, &kt);
if (ret < 0) {
libc_errno = -ret;
int ret = LIBC_NAMESPACE::ioctl(fd, TCGETS, &kt);
if (ret < 0)
return -1;
}

t->c_iflag = kt.c_iflag;
t->c_oflag = kt.c_oflag;
t->c_cflag = kt.c_cflag;
Expand Down
9 changes: 4 additions & 5 deletions libc/src/termios/linux/tcgetsid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <sys/syscall.h> // For syscall numbers
#include <termios.h>

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(pid_t, tcgetsid, (int fd)) {
pid_t sid;
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, TIOCGSID, &sid);
if (ret < 0) {
libc_errno = -ret;
int ret = LIBC_NAMESPACE::ioctl(fd, TIOCGSID, &sid);
if (ret < 0)
return -1;
}
return sid;
}

Expand Down
9 changes: 2 additions & 7 deletions libc/src/termios/linux/tcsendbreak.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <sys/syscall.h> // For syscall numbers
#include <termios.h>

Expand All @@ -23,12 +23,7 @@ LLVM_LIBC_FUNCTION(pid_t, tcsendbreak, (int fd, int /* unused duration */)) {
// POSIX leaves the behavior for non-zero duration implementation dependent.
// Which means that the behavior can be the same as it is when duration is
// zero. So, we just pass zero to the syscall.
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, TCSBRK, 0);
if (ret < 0) {
libc_errno = -ret;
return -1;
}
return 0;
return LIBC_NAMESPACE::ioctl(SYS_ioctl, fd, TCSBRK, 0);
}

} // namespace LIBC_NAMESPACE_DECL
9 changes: 2 additions & 7 deletions libc/src/termios/linux/tcsetattr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "src/__support/macros/config.h"
#include "src/errno/libc_errno.h"

#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
#include <sys/syscall.h> // For syscall numbers
#include <termios.h>

Expand Down Expand Up @@ -52,12 +52,7 @@ LLVM_LIBC_FUNCTION(int, tcsetattr,
kt.c_cc[i] = 0;
}

int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, cmd, &kt);
if (ret < 0) {
libc_errno = -ret;
return -1;
}
return 0;
return LIBC_NAMESPACE::ioctl(fd, cmd, &kt);
}

} // namespace LIBC_NAMESPACE_DECL
4 changes: 1 addition & 3 deletions libc/src/unistd/linux/isatty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ LLVM_LIBC_FUNCTION(int, isatty, (int fd)) {
int line_d_val = INIT_VAL;
// This gets the line dicipline of the terminal. When called on something that
// isn't a terminal it doesn't change line_d_val and returns -1.
int result =
LIBC_NAMESPACE::syscall_impl<int>(SYS_ioctl, fd, TIOCGETD, &line_d_val);
int result = LIBC_NAMESPACE::ioctl(fd, TIOCGETD, &line_d_val);
if (result == 0)
return 1;

libc_errno = -result;
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions libc/test/src/sys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ add_subdirectory(auxv)
add_subdirectory(epoll)
add_subdirectory(uio)
add_subdirectory(time)
add_subdirectory(ioctl)
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.include.sys_filio
libc.src.sys.ioctl.ioctl
libc.src.errno.errno
)
34 changes: 34 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,34 @@
//===-- 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/errno/libc_errno.h"
#include "src/sys/ioctl/ioctl.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include <sys/filio.h>
#include <sys/ioctl.h>

using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;

TEST(LlvmLibcSysIoctlTest, StdinFIONREAD) {
LIBC_NAMESPACE::libc_errno = 0;

// FIONREAD reports the number of readable bytes for fd
int bytes;
int ret = LIBC_NAMESPACE::ioctl(0, FIONREAD, &bytes);
ASSERT_ERRNO_SUCCESS();
}

TEST(LlvmLibcSysIoctlTest, InvalidCommandENOTTY) {
LIBC_NAMESPACE::libc_errno = 0;

// 0xDEADBEEF is just a random nonexistent command;
// calling this should always fail with ENOTTY
int ret = LIBC_NAMESPACE::ioctl(3, 0xDEADBEEF, NULL);
ASSERT_TRUE(ret == -1 && errno == ENOTTY);
}