[libc][termios] Make termios hermetic and fix its compatibility with glibc 2.42 or after. (#211039)
Make termios hermetic and address its compatibility with glibc 2.42 breaking change with baud rate definitions: https://inbox.sourceware.org/libc-announce/5906001.DvuYhMxLoT@pinacolada/T/ Fixes include: - Baud rate translation utilities. - Add proxy headers for termios.h macros and types. - Update tests. Assisted-by: Gemini 3.5 Flash.
This commit is contained in:
parent
11996d6729
commit
995e2af535
38 changed files with 630 additions and 101 deletions
|
|
@ -161,7 +161,11 @@ option(LLVM_LIBC_ENABLE_EXPERIMENTAL_ENTRYPOINTS
|
|||
option(LIBC_CONFIG_PATH "The path to user provided folder that configures the build for the target system." OFF)
|
||||
|
||||
if(LIBC_TARGET_OS_IS_LINUX)
|
||||
set(kernel_headers "/usr/include")
|
||||
if(LIBC_TARGET_TRIPLE AND EXISTS "/usr/${LIBC_TARGET_TRIPLE}/include")
|
||||
set(kernel_headers "/usr/${LIBC_TARGET_TRIPLE}/include")
|
||||
else()
|
||||
set(kernel_headers "/usr/include")
|
||||
endif()
|
||||
endif()
|
||||
set(LIBC_KERNEL_HEADERS "${kernel_headers}" CACHE STRING "Path to Linux kernel headers")
|
||||
|
||||
|
|
|
|||
|
|
@ -243,11 +243,13 @@ function(_get_common_compile_options output_var flags)
|
|||
(LIBC_CC_SUPPORTS_NOSTDLIBINC OR COMPILER_RESOURCE_DIR))
|
||||
# We use -idirafter to avoid preempting libc's own headers in case the
|
||||
# directory (e.g. /usr/include) contains other headers.
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
list(APPEND compile_options "-idirafter=${LIBC_KERNEL_HEADERS}")
|
||||
else()
|
||||
list(APPEND compile_options "-idirafter${LIBC_KERNEL_HEADERS}")
|
||||
endif()
|
||||
foreach(path IN LISTS LIBC_KERNEL_HEADERS)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
list(APPEND compile_options "-idirafter=${path}")
|
||||
else()
|
||||
list(APPEND compile_options "-idirafter${path}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,14 @@ add_proxy_header_library(
|
|||
libc.include.llvm-libc-macros.sys_wait_macros
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
termios_macros
|
||||
HDRS
|
||||
termios_macros.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-macros.termios_macros
|
||||
)
|
||||
|
||||
add_header_library(unistd_overlay HDRS unistd_overlay.h)
|
||||
add_proxy_header_library(
|
||||
unistd_macros
|
||||
|
|
|
|||
27
libc/hdr/termios_macros.h
Normal file
27
libc/hdr/termios_macros.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Proxy header for macros from termios.h.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_TERMIOS_MACROS_H
|
||||
#define LLVM_LIBC_HDR_TERMIOS_MACROS_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-macros/termios-macros.h"
|
||||
|
||||
#else // Overlay mode
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TERMIOS_MACROS_H
|
||||
|
|
@ -1227,3 +1227,36 @@ add_proxy_header_library(
|
|||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-types.regmatch_t
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
speed_t
|
||||
HDRS
|
||||
speed_t.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-types.speed_t
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
struct_termios
|
||||
HDRS
|
||||
struct_termios.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-types.struct_termios
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
cc_t
|
||||
HDRS
|
||||
cc_t.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-types.cc_t
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
tcflag_t
|
||||
HDRS
|
||||
tcflag_t.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-types.tcflag_t
|
||||
)
|
||||
|
||||
|
|
|
|||
27
libc/hdr/types/cc_t.h
Normal file
27
libc/hdr/types/cc_t.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Proxy header for cc_t.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_TYPES_CC_T_H
|
||||
#define LLVM_LIBC_HDR_TYPES_CC_T_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-types/cc_t.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TYPES_CC_T_H
|
||||
27
libc/hdr/types/speed_t.h
Normal file
27
libc/hdr/types/speed_t.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Proxy header for speed_t.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_TYPES_SPEED_T_H
|
||||
#define LLVM_LIBC_HDR_TYPES_SPEED_T_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-types/speed_t.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TYPES_SPEED_T_H
|
||||
27
libc/hdr/types/struct_termios.h
Normal file
27
libc/hdr/types/struct_termios.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Proxy header for struct termios.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_TERMIOS_H
|
||||
#define LLVM_LIBC_HDR_TYPES_STRUCT_TERMIOS_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-types/struct_termios.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TYPES_STRUCT_TERMIOS_H
|
||||
27
libc/hdr/types/tcflag_t.h
Normal file
27
libc/hdr/types/tcflag_t.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Proxy header for tcflag_t.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_TYPES_TCFLAG_T_H
|
||||
#define LLVM_LIBC_HDR_TYPES_TCFLAG_T_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-types/tcflag_t.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TYPES_TCFLAG_T_H
|
||||
|
|
@ -190,7 +190,7 @@ add_header(tss_dtor_t HDR tss_dtor_t.h)
|
|||
add_header(__atexithandler_t HDR __atexithandler_t.h)
|
||||
add_header(speed_t HDR speed_t.h)
|
||||
add_header(tcflag_t HDR tcflag_t.h)
|
||||
add_header(struct_termios HDR struct_termios.h DEPENDS .cc_t .speed_t .tcflag_t)
|
||||
add_header(struct_termios HDR struct_termios.h DEPENDS .cc_t .speed_t .tcflag_t libc.include.llvm-libc-macros.termios_macros)
|
||||
add_header(struct_winsize HDR struct_winsize.h)
|
||||
add_header(__getoptargv_t HDR __getoptargv_t.h)
|
||||
add_header(wchar_t HDR wchar_t.h)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef __LLVM_LIBC_TYPES_STRUCT_TERMIOS_H__
|
||||
#define __LLVM_LIBC_TYPES_STRUCT_TERMIOS_H__
|
||||
|
||||
#include "../llvm-libc-macros/termios-macros.h"
|
||||
#include "cc_t.h"
|
||||
#include "speed_t.h"
|
||||
#include "tcflag_t.h"
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@
|
|||
#ifndef LLVM_LIBC_SRC_TERMIOS_CFGETISPEED_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_CFGETISPEED_H
|
||||
|
||||
#include "hdr/types/speed_t.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
speed_t cfgetispeed(const struct termios *t);
|
||||
speed_t cfgetispeed(const termios *t);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@
|
|||
#ifndef LLVM_LIBC_SRC_TERMIOS_CFGETOSPEED_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_CFGETOSPEED_H
|
||||
|
||||
#include "hdr/types/speed_t.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
speed_t cfgetospeed(const struct termios *t);
|
||||
speed_t cfgetospeed(const termios *t);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@
|
|||
#ifndef LLVM_LIBC_SRC_TERMIOS_CFSETISPEED_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_CFSETISPEED_H
|
||||
|
||||
#include "hdr/types/speed_t.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
int cfsetispeed(struct termios *t, speed_t speed);
|
||||
int cfsetispeed(termios *t, speed_t speed);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@
|
|||
#ifndef LLVM_LIBC_SRC_TERMIOS_CFSETOSPEED_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_CFSETOSPEED_H
|
||||
|
||||
#include "hdr/types/speed_t.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
int cfsetospeed(struct termios *t, speed_t speed);
|
||||
int cfsetospeed(termios *t, speed_t speed);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,17 @@
|
|||
# There is no difference between input and output speeds on Linux.
|
||||
# However, since POSIX requires separate functions for setting and getting
|
||||
# of the input and output speeds, we use different entrypoints wiht the
|
||||
# of the input and output speeds, we use different entrypoints with the
|
||||
# same getter/setter logic.
|
||||
|
||||
add_header_library(
|
||||
speed_utils
|
||||
HDRS
|
||||
speed_utils.h
|
||||
DEPENDS
|
||||
libc.hdr.termios_macros
|
||||
libc.hdr.types.speed_t
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
cfgetispeed
|
||||
SRCS
|
||||
|
|
@ -9,7 +19,9 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../cfgetispeed.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.hdr.types.speed_t
|
||||
libc.hdr.types.struct_termios
|
||||
libc.src.__support.macros.null_check
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
|
|
@ -19,8 +31,11 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../cfsetispeed.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
.speed_utils
|
||||
libc.hdr.types.speed_t
|
||||
libc.hdr.types.struct_termios
|
||||
libc.src.errno.errno
|
||||
libc.src.__support.macros.null_check
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
|
|
@ -30,7 +45,9 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../cfgetospeed.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.hdr.types.speed_t
|
||||
libc.hdr.types.struct_termios
|
||||
libc.src.__support.macros.null_check
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
|
|
@ -40,8 +57,11 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../cfsetospeed.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
.speed_utils
|
||||
libc.hdr.types.speed_t
|
||||
libc.hdr.types.struct_termios
|
||||
libc.src.errno.errno
|
||||
libc.src.__support.macros.null_check
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
|
|
@ -51,7 +71,7 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../tcgetsid.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.hdr.types.pid_t
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.errno.errno
|
||||
)
|
||||
|
|
@ -63,7 +83,6 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../tcdrain.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.errno.errno
|
||||
)
|
||||
|
|
@ -75,7 +94,7 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../tcflush.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.hdr.termios_macros
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.errno.errno
|
||||
)
|
||||
|
|
@ -87,7 +106,7 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../tcflow.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.hdr.termios_macros
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.errno.errno
|
||||
)
|
||||
|
|
@ -99,7 +118,6 @@ add_entrypoint_object(
|
|||
HDRS
|
||||
../tcsendbreak.h
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.errno.errno
|
||||
)
|
||||
|
|
@ -108,6 +126,9 @@ add_header_library(
|
|||
kernel_termios
|
||||
HDRS
|
||||
kernel_termios.h
|
||||
DEPENDS
|
||||
libc.hdr.types.cc_t
|
||||
libc.hdr.types.tcflag_t
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
|
|
@ -118,9 +139,12 @@ add_entrypoint_object(
|
|||
../tcgetattr.h
|
||||
DEPENDS
|
||||
.kernel_termios
|
||||
libc.include.termios
|
||||
.speed_utils
|
||||
libc.hdr.termios_macros
|
||||
libc.hdr.types.struct_termios
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.errno.errno
|
||||
libc.src.__support.macros.null_check
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
|
|
@ -131,7 +155,10 @@ add_entrypoint_object(
|
|||
../tcsetattr.h
|
||||
DEPENDS
|
||||
.kernel_termios
|
||||
libc.include.termios
|
||||
.speed_utils
|
||||
libc.hdr.termios_macros
|
||||
libc.hdr.types.struct_termios
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.errno.errno
|
||||
libc.src.__support.macros.null_check
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,27 @@
|
|||
//===-- Linux implementation of cfgetispeed -------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of cfgetispeed.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/cfgetispeed.h"
|
||||
|
||||
#include "hdr/types/speed_t.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <termios.h>
|
||||
#include "src/__support/macros/null_check.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(speed_t, cfgetispeed, (const struct termios *t)) {
|
||||
return t->c_cflag & CBAUD;
|
||||
LLVM_LIBC_FUNCTION(speed_t, cfgetispeed, (const termios *t)) {
|
||||
LIBC_CRASH_ON_NULLPTR(t);
|
||||
return t->c_ispeed;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
|
|
|||
|
|
@ -1,22 +1,27 @@
|
|||
//===-- Linux implementation of cfgetospeed -------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of cfgetospeed.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/cfgetospeed.h"
|
||||
|
||||
#include "hdr/types/speed_t.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <termios.h>
|
||||
#include "src/__support/macros/null_check.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(speed_t, cfgetospeed, (const struct termios *t)) {
|
||||
return t->c_cflag & CBAUD;
|
||||
LLVM_LIBC_FUNCTION(speed_t, cfgetospeed, (const termios *t)) {
|
||||
LIBC_CRASH_ON_NULLPTR(t);
|
||||
return t->c_ospeed;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
|
|
|||
|
|
@ -1,30 +1,35 @@
|
|||
//===-- Linux implementation of cfsetispeed -------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of cfsetispeed.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/cfsetispeed.h"
|
||||
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <termios.h>
|
||||
#include "src/__support/macros/null_check.h"
|
||||
#include "src/termios/linux/speed_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, cfsetispeed, (struct termios * t, speed_t speed)) {
|
||||
constexpr speed_t NOT_SPEED_MASK = ~speed_t(CBAUD);
|
||||
LLVM_LIBC_FUNCTION(int, cfsetispeed, (termios * t, speed_t speed)) {
|
||||
LIBC_CRASH_ON_NULLPTR(t);
|
||||
constexpr speed_t NOT_SPEED_MASK = ~static_cast<speed_t>(CBAUD);
|
||||
speed_t encoded = encode_speed(speed);
|
||||
// A speed value is valid only if it is equal to one of the B<NN+> values.
|
||||
if (t == nullptr || ((speed & NOT_SPEED_MASK) != 0)) {
|
||||
if ((encoded & NOT_SPEED_MASK) != 0) {
|
||||
libc_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
t->c_cflag = (t->c_cflag & NOT_SPEED_MASK) | speed;
|
||||
t->c_ispeed = speed;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,36 @@
|
|||
//===-- Linux implementation of cfsetospeed -------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of cfsetospeed.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/cfsetospeed.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/common.h"
|
||||
|
||||
#include <termios.h>
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/null_check.h"
|
||||
#include "src/termios/linux/speed_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, cfsetospeed, (struct termios * t, speed_t speed)) {
|
||||
constexpr speed_t NOT_SPEED_MASK = ~speed_t(CBAUD);
|
||||
LLVM_LIBC_FUNCTION(int, cfsetospeed, (termios * t, speed_t speed)) {
|
||||
LIBC_CRASH_ON_NULLPTR(t);
|
||||
constexpr speed_t NOT_SPEED_MASK = ~static_cast<speed_t>(CBAUD);
|
||||
speed_t encoded = encode_speed(speed);
|
||||
// A speed value is valid only if it is equal to one of the B<NN+> values.
|
||||
if (t == nullptr || ((speed & NOT_SPEED_MASK) != 0)) {
|
||||
if ((encoded & NOT_SPEED_MASK) != 0) {
|
||||
libc_errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
t->c_cflag = (t->c_cflag & NOT_SPEED_MASK) | speed;
|
||||
t->c_cflag = (t->c_cflag & NOT_SPEED_MASK) | encoded;
|
||||
t->c_ospeed = speed;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
//===-- Definition of kernel's version of struct termios --------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Definition of the kernel's version of struct termios.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_TERMIOS_LINUX_KERNEL_TERMIOS_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_LINUX_KERNEL_TERMIOS_H
|
||||
|
||||
#include "hdr/types/cc_t.h"
|
||||
#include "hdr/types/tcflag_t.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <stddef.h>
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
186
libc/src/termios/linux/speed_utils.h
Normal file
186
libc/src/termios/linux/speed_utils.h
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Speed translation utilities for termios.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_TERMIOS_LINUX_SPEED_UTILS_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_LINUX_SPEED_UTILS_H
|
||||
|
||||
#include "hdr/termios_macros.h"
|
||||
#include "hdr/types/speed_t.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
constexpr speed_t INVALID_SPEED = ~static_cast<speed_t>(0);
|
||||
|
||||
// glibc 2.42 changed the behavior of the termios Bxxx constants:
|
||||
// - Before glibc 2.42, the Bxxx constants correspond to the kernel speed
|
||||
// bitmasks
|
||||
// directly (e.g. B50 = 1).
|
||||
// - Starting from glibc 2.42, to support arbitrary baud rates numerically, the
|
||||
// Bxxx constants are defined as their actual integer values (e.g. B50 = 50).
|
||||
// In this case, we need to translate between the host's numerical speeds and
|
||||
// the kernel's speed bitmasks.
|
||||
// - If B50 == 1, then the host uses the kernel's bitmasks directly (no
|
||||
// translation).
|
||||
// - If B50 is not 1 (e.g. B50 == 50 in glibc >= 2.42), we apply
|
||||
// translation.
|
||||
#if (B50 == 1)
|
||||
|
||||
LIBC_INLINE constexpr speed_t encode_speed(speed_t speed) { return speed; }
|
||||
LIBC_INLINE constexpr speed_t decode_speed(speed_t speed) { return speed; }
|
||||
|
||||
#else // Overlay mode with numerical speeds (e.g. glibc)
|
||||
|
||||
LIBC_INLINE constexpr speed_t encode_speed(speed_t speed) {
|
||||
switch (speed) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 50:
|
||||
return 0000001;
|
||||
case 75:
|
||||
return 0000002;
|
||||
case 110:
|
||||
return 0000003;
|
||||
case 134:
|
||||
return 0000004;
|
||||
case 150:
|
||||
return 0000005;
|
||||
case 200:
|
||||
return 0000006;
|
||||
case 300:
|
||||
return 0000007;
|
||||
case 600:
|
||||
return 0000010;
|
||||
case 1200:
|
||||
return 0000011;
|
||||
case 1800:
|
||||
return 0000012;
|
||||
case 2400:
|
||||
return 0000013;
|
||||
case 4800:
|
||||
return 0000014;
|
||||
case 9600:
|
||||
return 0000015;
|
||||
case 19200:
|
||||
return 0000016;
|
||||
case 38400:
|
||||
return 0000017;
|
||||
case 57600:
|
||||
return 0010001;
|
||||
case 115200:
|
||||
return 0010002;
|
||||
case 230400:
|
||||
return 0010003;
|
||||
case 460800:
|
||||
return 0010004;
|
||||
case 500000:
|
||||
return 0010005;
|
||||
case 576000:
|
||||
return 0010006;
|
||||
case 921600:
|
||||
return 0010007;
|
||||
case 1000000:
|
||||
return 0010010;
|
||||
case 1152000:
|
||||
return 0010011;
|
||||
case 1500000:
|
||||
return 0010012;
|
||||
case 2000000:
|
||||
return 0010013;
|
||||
case 2500000:
|
||||
return 0010014;
|
||||
case 3000000:
|
||||
return 0010015;
|
||||
case 3500000:
|
||||
return 0010016;
|
||||
case 4000000:
|
||||
return 0010017;
|
||||
default:
|
||||
return INVALID_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
LIBC_INLINE constexpr speed_t decode_speed(speed_t kernel_speed) {
|
||||
switch (kernel_speed) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 0000001:
|
||||
return 50;
|
||||
case 0000002:
|
||||
return 75;
|
||||
case 0000003:
|
||||
return 110;
|
||||
case 0000004:
|
||||
return 134;
|
||||
case 0000005:
|
||||
return 150;
|
||||
case 0000006:
|
||||
return 200;
|
||||
case 0000007:
|
||||
return 300;
|
||||
case 0000010:
|
||||
return 600;
|
||||
case 0000011:
|
||||
return 1200;
|
||||
case 0000012:
|
||||
return 1800;
|
||||
case 0000013:
|
||||
return 2400;
|
||||
case 0000014:
|
||||
return 4800;
|
||||
case 0000015:
|
||||
return 9600;
|
||||
case 0000016:
|
||||
return 19200;
|
||||
case 0000017:
|
||||
return 38400;
|
||||
case 0010001:
|
||||
return 57600;
|
||||
case 0010002:
|
||||
return 115200;
|
||||
case 0010003:
|
||||
return 230400;
|
||||
case 0010004:
|
||||
return 460800;
|
||||
case 0010005:
|
||||
return 500000;
|
||||
case 0010006:
|
||||
return 576000;
|
||||
case 0010007:
|
||||
return 921600;
|
||||
case 0010010:
|
||||
return 1000000;
|
||||
case 0010011:
|
||||
return 1152000;
|
||||
case 0010012:
|
||||
return 1500000;
|
||||
case 0010013:
|
||||
return 2000000;
|
||||
case 0010014:
|
||||
return 2500000;
|
||||
case 0010015:
|
||||
return 3000000;
|
||||
case 0010016:
|
||||
return 3500000;
|
||||
case 0010017:
|
||||
return 4000000;
|
||||
default:
|
||||
return kernel_speed;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // (B50 == 1)
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_TERMIOS_LINUX_SPEED_UTILS_H
|
||||
|
|
@ -1,10 +1,15 @@
|
|||
//===-- Linux implementation of tcdrain -----------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of tcdrain.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/tcdrain.h"
|
||||
|
||||
|
|
@ -14,7 +19,6 @@
|
|||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
//===-- Linux implementation of tcflow -----------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of tcflow.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/tcflow.h"
|
||||
|
||||
#include "hdr/termios_macros.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
//===-- Linux implementation of tcflush -----------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of tcflush.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/tcflush.h"
|
||||
|
||||
#include "hdr/termios_macros.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,33 @@
|
|||
//===-- Linux implementation of tcgetattr ---------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of tcgetattr.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/tcgetattr.h"
|
||||
#include "hdr/termios_macros.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/CPP/algorithm.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/null_check.h"
|
||||
#include "src/termios/linux/kernel_termios.h"
|
||||
#include "src/termios/linux/speed_utils.h"
|
||||
|
||||
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, tcgetattr, (int fd, struct termios *t)) {
|
||||
LLVM_LIBC_FUNCTION(int, tcgetattr, (int fd, termios *t)) {
|
||||
LIBC_CRASH_ON_NULLPTR(t);
|
||||
LIBC_NAMESPACE::kernel_termios kt;
|
||||
auto ret = linux_syscalls::ioctl(fd, TCGETS, &kt);
|
||||
if (!ret.has_value()) {
|
||||
|
|
@ -29,10 +38,17 @@ LLVM_LIBC_FUNCTION(int, tcgetattr, (int fd, struct termios *t)) {
|
|||
t->c_oflag = kt.c_oflag;
|
||||
t->c_cflag = kt.c_cflag;
|
||||
t->c_lflag = kt.c_lflag;
|
||||
t->c_ispeed = kt.c_cflag & CBAUD;
|
||||
t->c_ospeed = kt.c_cflag & CBAUD;
|
||||
t->c_line = kt.c_line;
|
||||
|
||||
size_t nccs = KERNEL_NCCS <= NCCS ? KERNEL_NCCS : NCCS;
|
||||
speed_t ospeed_mask = kt.c_cflag & CBAUD;
|
||||
speed_t ispeed_mask = (kt.c_cflag & CIBAUD) >> 16;
|
||||
if (ispeed_mask == 0)
|
||||
ispeed_mask = ospeed_mask;
|
||||
|
||||
t->c_ospeed = decode_speed(ospeed_mask);
|
||||
t->c_ispeed = decode_speed(ispeed_mask);
|
||||
|
||||
size_t nccs = cpp::min(KERNEL_NCCS, static_cast<size_t>(NCCS));
|
||||
for (size_t i = 0; i < nccs; ++i)
|
||||
t->c_cc[i] = kt.c_cc[i];
|
||||
if (NCCS > nccs) {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
//===-- Linux implementation of tcgetsid ----------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of tcgetsid.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/tcgetsid.h"
|
||||
|
||||
#include "hdr/types/pid_t.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
//===-- Linux implementation of tcsendbreak -------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of tcsendbreak.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/tcsendbreak.h"
|
||||
|
||||
|
|
@ -14,11 +19,10 @@
|
|||
#include "src/__support/macros/config.h"
|
||||
|
||||
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(pid_t, tcsendbreak, (int fd, int /* unused duration */)) {
|
||||
LLVM_LIBC_FUNCTION(int, 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.
|
||||
|
|
|
|||
|
|
@ -1,25 +1,33 @@
|
|||
//===-- Linux implementation of tcsetattr ---------------------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Linux implementation of tcsetattr.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/termios/tcsetattr.h"
|
||||
#include "hdr/termios_macros.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/CPP/algorithm.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/null_check.h"
|
||||
#include "src/termios/linux/kernel_termios.h"
|
||||
#include "src/termios/linux/speed_utils.h"
|
||||
|
||||
#include <asm/ioctls.h> // Safe to include without the risk of name pollution.
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, tcsetattr,
|
||||
(int fd, int actions, const struct termios *t)) {
|
||||
LLVM_LIBC_FUNCTION(int, tcsetattr, (int fd, int actions, const termios *t)) {
|
||||
LIBC_CRASH_ON_NULLPTR(t);
|
||||
struct kernel_termios kt;
|
||||
long cmd;
|
||||
|
||||
|
|
@ -40,9 +48,17 @@ LLVM_LIBC_FUNCTION(int, tcsetattr,
|
|||
|
||||
kt.c_iflag = t->c_iflag;
|
||||
kt.c_oflag = t->c_oflag;
|
||||
kt.c_cflag = t->c_cflag;
|
||||
|
||||
speed_t ospeed = encode_speed(t->c_ospeed);
|
||||
speed_t ispeed = t->c_ispeed == 0 ? ospeed : encode_speed(t->c_ispeed);
|
||||
|
||||
constexpr speed_t NOT_SPEED_MASK = ~static_cast<speed_t>(CBAUD | CIBAUD);
|
||||
kt.c_cflag = (t->c_cflag & NOT_SPEED_MASK) | ospeed | (ispeed << 16);
|
||||
|
||||
kt.c_lflag = t->c_lflag;
|
||||
size_t nccs = KERNEL_NCCS <= NCCS ? KERNEL_NCCS : NCCS;
|
||||
kt.c_line = t->c_line;
|
||||
|
||||
size_t nccs = cpp::min(KERNEL_NCCS, static_cast<size_t>(NCCS));
|
||||
for (size_t i = 0; i < nccs; ++i)
|
||||
kt.c_cc[i] = t->c_cc[i];
|
||||
if (nccs < KERNEL_NCCS) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#define LLVM_LIBC_SRC_TERMIOS_TCDRAIN_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#define LLVM_LIBC_SRC_TERMIOS_TCFLOW_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#define LLVM_LIBC_SRC_TERMIOS_TCFLUSH_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
#ifndef LLVM_LIBC_SRC_TERMIOS_TCGETATTR_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_TCGETATTR_H
|
||||
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
int tcgetattr(int fd, struct termios *t);
|
||||
int tcgetattr(int fd, termios *t);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
#ifndef LLVM_LIBC_SRC_TERMIOS_TCGETSID_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_TCGETSID_H
|
||||
|
||||
#include "hdr/types/pid_t.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#define LLVM_LIBC_SRC_TERMIOS_TCSENDBREAK_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
#ifndef LLVM_LIBC_SRC_TERMIOS_TCSETATTR_H
|
||||
#define LLVM_LIBC_SRC_TERMIOS_TCSETATTR_H
|
||||
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <termios.h>
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
int tcsetattr(int fd, int actions, const struct termios *t);
|
||||
int tcsetattr(int fd, int actions, const termios *t);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ add_libc_unittest(
|
|||
termios_test.cpp
|
||||
DEPENDS
|
||||
libc.include.termios
|
||||
libc.hdr.termios_macros
|
||||
libc.hdr.types.struct_termios
|
||||
libc.src.errno.errno
|
||||
libc.src.fcntl.open
|
||||
libc.src.termios.cfgetispeed
|
||||
|
|
|
|||
|
|
@ -1,11 +1,18 @@
|
|||
//===-- Unittests for a bunch of functions in termios.h -------------------===//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
/// Unittests for functions in termios.h.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "hdr/termios_macros.h"
|
||||
#include "hdr/types/struct_termios.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/fcntl/open.h"
|
||||
#include "src/termios/cfgetispeed.h"
|
||||
|
|
@ -20,8 +27,6 @@
|
|||
#include "test/UnitTest/ErrnoSetterMatcher.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
using LlvmLibcTermiosTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
|
||||
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
|
||||
|
||||
|
|
@ -30,7 +35,7 @@ using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
|
|||
// from ninja/make which change the terminal behavior.
|
||||
|
||||
TEST_F(LlvmLibcTermiosTest, SpeedSmokeTest) {
|
||||
struct termios t;
|
||||
termios t;
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, B50), Succeeds(0));
|
||||
ASSERT_EQ(LIBC_NAMESPACE::cfgetispeed(&t), speed_t(B50));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, B75), Succeeds(0));
|
||||
|
|
@ -38,10 +43,18 @@ TEST_F(LlvmLibcTermiosTest, SpeedSmokeTest) {
|
|||
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, ~CBAUD), Fails(EINVAL));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, ~CBAUD), Fails(EINVAL));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, 12345), Fails(EINVAL));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, 12345), Fails(EINVAL));
|
||||
#if B50 != 1
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, 4096), Fails(EINVAL));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, 4096), Fails(EINVAL));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, 1), Fails(EINVAL));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, 1), Fails(EINVAL));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcTermiosTest, GetAttrSmokeTest) {
|
||||
struct termios t;
|
||||
termios t;
|
||||
int fd = LIBC_NAMESPACE::open("/dev/tty", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
// When /dev/tty is not available, no point continuing
|
||||
|
|
@ -65,3 +78,39 @@ TEST_F(LlvmLibcTermiosTest, TcGetSidSmokeTest) {
|
|||
returns(GT(pid_t(0))).with_errno(EQ(0)));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcTermiosTest, SplitSpeedTest) {
|
||||
int fd = LIBC_NAMESPACE::open("/dev/ptmx", O_RDWR);
|
||||
if (fd < 0) {
|
||||
// Gracefully skip if /dev/ptmx is not available
|
||||
libc_errno = 0;
|
||||
return;
|
||||
}
|
||||
ASSERT_ERRNO_SUCCESS();
|
||||
|
||||
termios t;
|
||||
ASSERT_THAT(LIBC_NAMESPACE::tcgetattr(fd, &t), Succeeds(0));
|
||||
|
||||
// 1. Test setting split speeds.
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t, B50), Succeeds(0));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetospeed(&t, B75), Succeeds(0));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::tcsetattr(fd, TCSANOW, &t), Succeeds(0));
|
||||
|
||||
termios t2;
|
||||
ASSERT_THAT(LIBC_NAMESPACE::tcgetattr(fd, &t2), Succeeds(0));
|
||||
ASSERT_EQ(LIBC_NAMESPACE::cfgetispeed(&t2), speed_t(B50));
|
||||
ASSERT_EQ(LIBC_NAMESPACE::cfgetospeed(&t2), speed_t(B75));
|
||||
|
||||
// 2. Test input speed 0 fallback.
|
||||
ASSERT_THAT(LIBC_NAMESPACE::cfsetispeed(&t2, 0), Succeeds(0));
|
||||
ASSERT_THAT(LIBC_NAMESPACE::tcsetattr(fd, TCSANOW, &t2), Succeeds(0));
|
||||
|
||||
termios t3;
|
||||
ASSERT_THAT(LIBC_NAMESPACE::tcgetattr(fd, &t3), Succeeds(0));
|
||||
ASSERT_EQ(LIBC_NAMESPACE::cfgetospeed(&t3), speed_t(B75));
|
||||
// Under POSIX, if input speed was set to 0, it must be the same as output
|
||||
// speed.
|
||||
ASSERT_EQ(LIBC_NAMESPACE::cfgetispeed(&t3), speed_t(B75));
|
||||
|
||||
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue