[libc-commits] [libc] [libc] Introduce the ioctl syscall wrapper and port all callers (PR #204640)
Pavel Labath via libc-commits
libc-commits at lists.llvm.org
Tue Jun 23 00:02:31 PDT 2026
================
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for ioctl.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_IOCTL_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_IOCTL_H
+
+#include "src/__support/CPP/type_traits/enable_if.h"
+#include "src/__support/CPP/type_traits/is_integral.h"
+#include "src/__support/CPP/type_traits/is_null_pointer.h"
+#include "src/__support/CPP/type_traits/is_pointer.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/error_or.h"
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+struct IoctlArg {
+ unsigned long val;
+
+ LIBC_INLINE constexpr IoctlArg() : val(0) {}
+ LIBC_INLINE constexpr IoctlArg(cpp::nullptr_t) : val(0) {}
+
+ template <typename T, cpp::enable_if_t<cpp::is_pointer_v<T>, int> = 0>
+ LIBC_INLINE IoctlArg(T ptr) : val(reinterpret_cast<unsigned long>(ptr)) {}
+
+ template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
+ LIBC_INLINE constexpr IoctlArg(T num)
+ : val(static_cast<unsigned long>(num)) {}
+};
+
+LIBC_INLINE ErrorOr<int> ioctl(int fd, unsigned long request,
+ IoctlArg arg = {}) {
+ return syscall_checked<int>(SYS_ioctl, fd, request, arg.val);
+}
----------------
labath wrote:
The thing with unsigned long is that it makes the explicit literal zero argument ambiguous.
I'm not sure if your suggestion was to handle that by not specifying the argument (letting the implicit zero arg handle that), but I'd rather not do that, as I think it's useful explicitly specify the argument value at the call site. Plus, I like how this doesn't result in multiple instantiations of the ioctl function.
That said, I think the IoctlArg constructor overload set is a bit too verbose, so I've shrunk it (to ~two versions you suggested).
https://github.com/llvm/llvm-project/pull/204640
More information about the libc-commits
mailing list