diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -293,3 +293,7 @@ def SpawnAPI : PublicAPI<"spawn.h"> { let Types = ["mode_t", "pid_t", "posix_spawnattr_t", "posix_spawn_file_actions_t"]; } + +def TermiosAPI : PublicAPI<"termios.h"> { + let Types = ["cc_t", "pid_t", "speed_t", "struct termios", "tcflag_t"]; +} diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -141,6 +141,19 @@ libc.src.sys.wait.wait4 libc.src.sys.wait.waitpid + # termios.h entrypoints + libc.src.termios.cfgetispeed + libc.src.termios.cfgetospeed + libc.src.termios.cfsetispeed + libc.src.termios.cfsetospeed + libc.src.termios.tcgetattr + libc.src.termios.tcgetsid + libc.src.termios.tcdrain + libc.src.termios.tcflow + libc.src.termios.tcflush + libc.src.termios.tcsendbreak + libc.src.termios.tcsetattr + # unistd.h entrypoints libc.src.unistd.access libc.src.unistd.chdir diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -350,6 +350,19 @@ .llvm-libc-types.struct_rusage ) +add_gen_header( + termios + DEF_FILE termios.h.def + GEN_HDR termios.h + DEPENDS + .llvm_libc_common_h + .llvm-libc-macros.termios_macros + .llvm-libc-types.cc_t + .llvm-libc-types.speed_t + .llvm-libc-types.struct_termios + .llvm-libc-types.tcflag_t +) + if(NOT LLVM_LIBC_FULL_BUILD) # We don't install headers in non-fullbuild mode. return() diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -99,6 +99,14 @@ .linux.sys_wait_macros ) +add_header( + termios_macros + HDR + termios-macros.h + DEPENDS + .linux.termios_macros +) + add_header( time_macros HDR diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt --- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt @@ -69,3 +69,9 @@ HDR signal-macros.h ) + +add_header( + termios_macros + HDR + termios-macros.h +) diff --git a/libc/include/llvm-libc-macros/linux/termios-macros.h b/libc/include/llvm-libc-macros/linux/termios-macros.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-macros/linux/termios-macros.h @@ -0,0 +1,167 @@ +//===-- Definition of macros from 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 +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H +#define __LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H + +// Below are generic definitions of symbolic bit-masks, modes etc. They serve +// most architectures including x86_64, aarch64 but have to be adjusted for few +// architectures MIPS. + +#define NCCS 32 + +// Bit-masks for the c_iflag field of struct termios. +#define IGNBRK 0000001 // Ignore break condition +#define BRKINT 0000002 // Signal interrupt on break +#define IGNPAR 0000004 // Ignore characters with parity errors +#define PARMRK 0000010 // Mark parity and framing errors +#define INPCK 0000020 // Enable input parity check +#define ISTRIP 0000040 // Strip 8th bit off characters +#define INLCR 0000100 // Map NL to CR on input +#define IGNCR 0000200 // Ignore CR +#define ICRNL 0000400 // Map CR to NL on input +#define IUCLC 0001000 // Map uppercase characters to lowercase on input +#define IXON 0002000 // Enable start/stop output control +#define IXANY 0004000 // Enable any character to restart output +#define IXOFF 0010000 // Enable start/stop input control +#define IMAXBEL 0020000 // Ring bell when input queue is full +#define IUTF8 0040000 // Input is UTF8 (not in POSIX) + +// Bit-masks for the c_oflag field of struct termios. +#define OPOST 0000001 // Post-process output +#define OLCUC 0000002 // Map lowercase characters to uppercase on output +#define ONLCR 0000004 // Map NL to CR-NL on output +#define OCRNL 0000010 // Map CR to NL on output +#define ONOCR 0000020 // No CR output at column 0 +#define ONLRET 0000040 // NL performs CR function +#define OFILL 0000100 // Use fill characters for delay +#define OFDEL 0000200 // Fill is DEL +#define NLDLY 0000400 // Select newline delays +#define NL0 0000000 // Newline type 0 +#define NL1 0000400 // Newline type 1 +#define CRDLY 0003000 // Select carriage-return delays +#define CR0 0000000 // Carriage-return delay type 0 +#define CR1 0001000 // Carriage-return delay type 1 +#define CR2 0002000 // Carriage-return delay type 2 +#define CR3 0003000 // Carriage-return delay type 3 +#define TABDLY 0014000 // Select horizontal-tab delays +#define TAB0 0000000 // Horizontal-tab delay type 0 +#define TAB1 0004000 // Horizontal-tab delay type 1 +#define TAB2 0010000 // Horizontal-tab delay type 2 +#define TAB3 0014000 // Expand tabs to spaces +#define BSDLY 0020000 // Select backspace delays +#define BS0 0000000 // Backspace-delay type 0 +#define BS1 0020000 // Backspace-delay type 1 +#define FFDLY 0100000 // Select form-feed delays +#define FF0 0000000 // Form-feed delay type 0 +#define FF1 0100000 // Form-feed delay type 1 +#define VTDLY 0040000 // Select vertical-tab delays +#define VT0 0000000 // Vertical-tab delay type 0 +#define VT1 0040000 // Vertical-tab delay type 1 +#define XTABS 0014000 + +// Symbolic subscripts for the c_cc array. +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +// Baud rate related definitions +#define CBAUD 000000010017 // Baud speed mask +#define CBAUDX 000000010000 // Extra baud speed mask +#define CIBAUD 002003600000 +#define CMSPAR 010000000000 +#define CRTSCTS 020000000000 +// Baud rates with values representable by the speed_t type. +#define B0 0000000 // Implies hang-up +// A symbol B below indicates a baud rate of . +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +// Extra baud rates +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 + +// Control mode bits for use in the c_cflag field of struct termios. +#define CSIZE 0000060 // Mask for character size bits +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 // Send two bits, else one +#define CREAD 0000200 // Enable receiver +#define PARENB 0000400 // Parity enable +#define PARODD 0001000 // Odd parity, else even +#define HUPCL 0002000 // Hang up on last close +#define CLOCAL 0004000 // Ignore modem status lines + +// Local mode bits for use in the c_lflag field of struct termios. +#define ISIG 0000001 // Enable signals +#define ICANON 0000002 // Canonical input (erase and kill processing) +#define ECHO 0000010 // Enable echo +#define ECHOE 0000020 // Echo erase character as error-correcting backspace +#define ECHOK 0000040 // Echo KILL +#define ECHONL 0000100 // Echo NL +#define NOFLSH 0000200 // Disable flush after interrupt or quit +#define TOSTOP 0000400 // Send SIGTTOU for background output + +// Attribute selection +#define TCSANOW 0 // Change attributes immediately +#define TCSADRAIN 1 // Change attributes when output has drained +#define TCSAFLUSH 2 // Same as TCSADRAIN and flush pending Output + +// Symbolic constants for use with tcflush function. +#define TCIFLUSH 0 // Flush pending input +#define TCIOFLUSH 1 // Flush pending input and unstransmitted output +#define TCOFLUSH 2 // Flush unstransmitted output + +// Symbolic constantf for use with tcflow function. +#define TCOOFF 0 // Transmit a STOP character, intended to suspend input data +#define TCOON 1 // Transmit a START character, intended to restart input data +#define TCIOFF 2 // Suspend output +#define TCION 3 // Restart output + +#endif // __LLVM_LIBC_MACROS_LINUX_TERMIOS_MACROS_H diff --git a/libc/include/llvm-libc-macros/termios-macros.h b/libc/include/llvm-libc-macros/termios-macros.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-macros/termios-macros.h @@ -0,0 +1,16 @@ +//===-- Macros defined in termios.h header file ---------------------------===// +// +// 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_MACROS_TERMIOS_MACROS_H +#define __LLVM_LIBC_MACROS_TERMIOS_MACROS_H + +#ifdef __linux__ +#include "linux/termios-macros.h" +#endif + +#endif // __LLVM_LIBC_MACROS_TERMIOS_MACROS_H diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -15,6 +15,7 @@ add_header(__thread_type HDR __thread_type.h) add_header(blkcnt_t HDR blkcnt_t.h) add_header(blksize_t HDR blksize_t.h) +add_header(cc_t HDR cc_t.h) add_header(clockid_t HDR clockid_t.h) add_header(cnd_t HDR cnd_t.h) add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off64_t) @@ -74,3 +75,6 @@ add_header(tss_t HDR tss_t.h) 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) diff --git a/libc/include/llvm-libc-types/cc_t.h b/libc/include/llvm-libc-types/cc_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/cc_t.h @@ -0,0 +1,14 @@ +//===-- Definition of cc_t type -------------------------------------------===// +// +// 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_TYPES_CC_T_H__ +#define __LLVM_LIBC_TYPES_CC_T_H__ + +typedef unsigned char cc_t; + +#endif // __LLVM_LIBC_TYPES_CC_T_H__ diff --git a/libc/include/llvm-libc-types/speed_t.h b/libc/include/llvm-libc-types/speed_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/speed_t.h @@ -0,0 +1,14 @@ +//===-- Definition of speed_t type ----------------------------------------===// +// +// 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_TYPES_SPEED_T_H__ +#define __LLVM_LIBC_TYPES_SPEED_T_H__ + +typedef unsigned int speed_t; + +#endif // __LLVM_LIBC_TYPES_SPEED_T_H__ diff --git a/libc/include/llvm-libc-types/struct_termios.h b/libc/include/llvm-libc-types/struct_termios.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/struct_termios.h @@ -0,0 +1,32 @@ +//===-- Definition of struct termios --------------------------------------===// +// +// 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_TYPES_STRUCT_TERMIOS_H__ +#define __LLVM_LIBC_TYPES_STRUCT_TERMIOS_H__ + +#include +#include +#include + +struct termios { + tcflag_t c_iflag; // Input mode flags + tcflag_t c_oflag; // Output mode flags + tcflag_t c_cflag; // Control mode flags + tcflag_t c_lflag; // Local mode flags +#ifdef __linux__ + cc_t c_line; // Line discipline +#endif // __linux__ + // NCCS is defined in llvm-libc-macros/termios-macros.h. + cc_t c_cc[NCCS]; // Control characters +#ifdef __linux__ + speed_t c_ispeed; // Input speed + speed_t c_ospeed; // output speed +#endif // __linux__ +}; + +#endif // __LLVM_LIBC_TYPES_STRUCT_TERMIOS_H__ diff --git a/libc/include/llvm-libc-types/tcflag_t.h b/libc/include/llvm-libc-types/tcflag_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/tcflag_t.h @@ -0,0 +1,14 @@ +//===-- Definition of tcflag_t type ---------------------------------------===// +// +// 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_TYPES_TCFLAG_T_H__ +#define __LLVM_LIBC_TYPES_TCFLAG_T_H__ + +typedef unsigned int tcflag_t; + +#endif // __LLVM_LIBC_TYPES_TCFLAG_T_H__ diff --git a/libc/include/termios.h.def b/libc/include/termios.h.def new file mode 100644 --- /dev/null +++ b/libc/include/termios.h.def @@ -0,0 +1,17 @@ +//===-- C standard library header 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TERMIOS_H +#define LLVM_LIBC_TERMIOS_H + +#include <__llvm-libc-common.h> +#include + +%%public_api() + +#endif // LLVM_LIBC_TERMIOS_H diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -58,6 +58,13 @@ def PosixSpawnAttrT : NamedType<"posix_spawnattr_t">; def RestrictedPosixSpawnAttrTPtrType : RestrictedPtrType; +def CcT : NamedType<"cc_t">; +def SpeedT : NamedType<"speed_t">; +def StructTermios : NamedType<"struct termios">; +def StructTermiosPtr : PtrType; +def ConstStructTermiosPtr : ConstType; +def TcFlagT : NamedType<"tcflag_t">; + def POSIX : StandardSpec<"POSIX"> { PtrType CharPtr = PtrType; RestrictedPtrType RestrictedCharPtr = RestrictedPtrType; @@ -1100,6 +1107,72 @@ ] >; + HeaderSpec Termios = HeaderSpec< + "termios.h", + [ + Macro<"NCCS">, + ], + [CcT, PidT, SpeedT, StructTermios, TcFlagT], // Types + [], // Enumerations + [ + FunctionSpec< + "cfgetispeed", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "cfgetospeed", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "cfsetispeed", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "cfsetospeed", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "tcdrain", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "tcflow", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "tcflush", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "tcgetattr", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "tcgetsid", + RetValSpec, + [ArgSpec] + >, + FunctionSpec< + "tcsendbreak", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "tcsetattr", + RetValSpec, + [ArgSpec, ArgSpec, ArgSpec] + >, + ] + >; + let Headers = [ CType, Dirent, @@ -1117,6 +1190,7 @@ SysUtsName, SysWait, Time, + Termios, UniStd, String ]; diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt --- a/libc/src/CMakeLists.txt +++ b/libc/src/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory(pthread) add_subdirectory(sched) add_subdirectory(sys) + add_subdirectory(termios) add_subdirectory(unistd) endif() diff --git a/libc/src/termios/CMakeLists.txt b/libc/src/termios/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/termios/CMakeLists.txt @@ -0,0 +1,80 @@ +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) +endif() + +add_entrypoint_object( + cfgetispeed + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.cfgetispeed +) + +add_entrypoint_object( + cfsetispeed + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.cfsetispeed +) + +add_entrypoint_object( + cfgetospeed + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.cfgetospeed +) + +add_entrypoint_object( + cfsetospeed + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.cfsetospeed +) + +add_entrypoint_object( + tcgetsid + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.tcgetsid +) + +add_entrypoint_object( + tcdrain + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.tcdrain +) + +add_entrypoint_object( + tcflow + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.tcflow +) + +add_entrypoint_object( + tcflush + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.tcflush +) + +add_entrypoint_object( + tcsendbreak + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.tcsendbreak +) + +add_entrypoint_object( + tcgetattr + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.tcgetattr +) + +add_entrypoint_object( + tcsetattr + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.tcsetattr +) diff --git a/libc/src/termios/cfgetispeed.h b/libc/src/termios/cfgetispeed.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/cfgetispeed.h @@ -0,0 +1,20 @@ +//===-- Implementation header for cfgetispeed -------------------*- 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_UNISTD_CFGETISPEED_H +#define LLVM_LIBC_SRC_UNISTD_CFGETISPEED_H + +#include + +namespace __llvm_libc { + +speed_t cfgetispeed(const struct termios *t); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_CFGETISPEED_H diff --git a/libc/src/termios/cfgetospeed.h b/libc/src/termios/cfgetospeed.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/cfgetospeed.h @@ -0,0 +1,20 @@ +//===-- Implementation header for cfgetospeed -------------------*- 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_UNISTD_CFGETOSPEED_H +#define LLVM_LIBC_SRC_UNISTD_CFGETOSPEED_H + +#include + +namespace __llvm_libc { + +speed_t cfgetospeed(const struct termios *t); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_CFGETOSPEED_H diff --git a/libc/src/termios/cfsetispeed.h b/libc/src/termios/cfsetispeed.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/cfsetispeed.h @@ -0,0 +1,20 @@ +//===-- Implementation header for cfsetispeed -------------------*- 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_UNISTD_CFSETISPEED_H +#define LLVM_LIBC_SRC_UNISTD_CFSETISPEED_H + +#include + +namespace __llvm_libc { + +int cfsetispeed(struct termios *t, speed_t speed); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_CFSETISPEED_H diff --git a/libc/src/termios/cfsetospeed.h b/libc/src/termios/cfsetospeed.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/cfsetospeed.h @@ -0,0 +1,20 @@ +//===-- Implementation header for cfsetospeed -------------------*- 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_UNISTD_CFSETOSPEED_H +#define LLVM_LIBC_SRC_UNISTD_CFSETOSPEED_H + +#include + +namespace __llvm_libc { + +int cfsetospeed(struct termios *t, speed_t speed); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_CFSETOSPEED_H diff --git a/libc/src/termios/linux/CMakeLists.txt b/libc/src/termios/linux/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/CMakeLists.txt @@ -0,0 +1,144 @@ +# 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 +# same getter/setter logic. +add_entrypoint_object( + cfgetispeed + SRCS + cfgetispeed.cpp + HDRS + ../cfgetispeed.h + DEPENDS + libc.include.termios +) + +add_entrypoint_object( + cfsetispeed + SRCS + cfsetispeed.cpp + HDRS + ../cfsetispeed.h + DEPENDS + libc.include.termios + libc.src.errno.errno +) + +add_entrypoint_object( + cfgetospeed + SRCS + cfgetospeed.cpp + HDRS + ../cfgetospeed.h + DEPENDS + libc.include.termios +) + +add_entrypoint_object( + cfsetospeed + SRCS + cfsetospeed.cpp + HDRS + ../cfsetospeed.h + DEPENDS + libc.include.termios + libc.src.errno.errno +) + +add_entrypoint_object( + tcgetsid + SRCS + tcgetsid.cpp + HDRS + ../tcgetsid.h + DEPENDS + libc.include.sys_syscall + libc.include.termios + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_entrypoint_object( + tcdrain + SRCS + tcdrain.cpp + HDRS + ../tcdrain.h + DEPENDS + libc.include.sys_syscall + libc.include.termios + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_entrypoint_object( + tcflush + SRCS + tcflush.cpp + HDRS + ../tcflush.h + DEPENDS + libc.include.sys_syscall + libc.include.termios + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_entrypoint_object( + tcflow + SRCS + tcflow.cpp + HDRS + ../tcflow.h + DEPENDS + libc.include.sys_syscall + libc.include.termios + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_entrypoint_object( + tcsendbreak + SRCS + tcsendbreak.cpp + HDRS + ../tcsendbreak.h + DEPENDS + libc.include.sys_syscall + libc.include.termios + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_header_library( + kernel_termios + HDRS + kernel_termios.h +) + +add_entrypoint_object( + tcgetattr + SRCS + tcgetattr.cpp + HDRS + ../tcgetattr.h + DEPENDS + .kernel_termios + libc.include.sys_syscall + libc.include.termios + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_entrypoint_object( + tcsetattr + SRCS + tcsetattr.cpp + HDRS + ../tcsetattr.h + DEPENDS + .kernel_termios + libc.include.sys_syscall + libc.include.termios + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) diff --git a/libc/src/termios/linux/cfgetispeed.cpp b/libc/src/termios/linux/cfgetispeed.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/cfgetispeed.cpp @@ -0,0 +1,21 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/cfgetispeed.h" + +#include "src/__support/common.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(speed_t, cfgetispeed, (const struct termios *t)) { + return t->c_cflag & CBAUD; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/cfgetospeed.cpp b/libc/src/termios/linux/cfgetospeed.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/cfgetospeed.cpp @@ -0,0 +1,21 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/cfgetospeed.h" + +#include "src/__support/common.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(speed_t, cfgetospeed, (const struct termios *t)) { + return t->c_cflag & CBAUD; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/cfsetispeed.cpp b/libc/src/termios/linux/cfsetispeed.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/cfsetispeed.cpp @@ -0,0 +1,31 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/cfsetispeed.h" + +#include "src/__support/common.h" + +#include +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, cfsetispeed, (struct termios * t, speed_t speed)) { + constexpr speed_t NOT_SPEED_MASK = ~speed_t(CBAUD); + // A speed value is valid only if it is equal to one of the B values. + if (t == nullptr || ((speed & NOT_SPEED_MASK) != 0)) { + errno = EINVAL; + return -1; + } + + t->c_cflag = (t->c_cflag & NOT_SPEED_MASK) | speed; + t->c_ispeed = speed; + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/cfsetospeed.cpp b/libc/src/termios/linux/cfsetospeed.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/cfsetospeed.cpp @@ -0,0 +1,31 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/cfsetospeed.h" + +#include "src/__support/common.h" + +#include +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, cfsetospeed, (struct termios * t, speed_t speed)) { + constexpr speed_t NOT_SPEED_MASK = ~speed_t(CBAUD); + // A speed value is valid only if it is equal to one of the B values. + if (t == nullptr || ((speed & NOT_SPEED_MASK) != 0)) { + errno = EINVAL; + return -1; + } + + t->c_cflag = (t->c_cflag & NOT_SPEED_MASK) | speed; + t->c_ospeed = speed; + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/kernel_termios.h b/libc/src/termios/linux/kernel_termios.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/kernel_termios.h @@ -0,0 +1,41 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_TERMIOS_LINUX_KERNEL_TERMIOS_H +#define LLVM_LIBC_SRC_TERMIOS_LINUX_KERNEL_TERMIOS_H + +#include +#include + +namespace __llvm_libc { + +// The kernel's struct termios is different from the libc's struct termios. The +// kernel's syscalls expect the size and layout of its definition of struct +// termios. So, we define a flavor of struct termios which matches that of the +// kernel so that we can translate between the libc version and the kernel +// version when passing struct termios objects to syscalls. + +// NOTE: The definitions here are generic definitions valid for most target +// architectures including x86_64 and aarch64. Definitions on some architectures +// deviate from these generic definitions. Adjustments have to be made for those +// architectures. + +constexpr size_t KERNEL_NCCS = 19; + +struct kernel_termios { + tcflag_t c_iflag; + tcflag_t c_oflag; + tcflag_t c_cflag; + tcflag_t c_lflag; + cc_t c_line; + cc_t c_cc[KERNEL_NCCS]; +}; + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_TERMIOS_LINUX_KERNEL_TERMIOS_H diff --git a/libc/src/termios/linux/tcdrain.cpp b/libc/src/termios/linux/tcdrain.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/tcdrain.cpp @@ -0,0 +1,30 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/tcdrain.h" + +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" + +#include // Safe to include without the risk of name pollution. +#include +#include // For syscall numbers +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, tcdrain, (int fd)) { + long ret = __llvm_libc::syscall_impl(SYS_ioctl, fd, TCSBRK, 1); + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/tcflow.cpp b/libc/src/termios/linux/tcflow.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/tcflow.cpp @@ -0,0 +1,30 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/tcflow.h" + +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" + +#include // Safe to include without the risk of name pollution. +#include +#include // For syscall numbers +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, tcflow, (int fd, int action)) { + long ret = __llvm_libc::syscall_impl(SYS_ioctl, fd, TCXONC, action); + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/tcflush.cpp b/libc/src/termios/linux/tcflush.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/tcflush.cpp @@ -0,0 +1,30 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/tcflush.h" + +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" + +#include // Safe to include without the risk of name pollution. +#include +#include // For syscall numbers +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, tcflush, (int fd, int queue_selector)) { + long ret = __llvm_libc::syscall_impl(SYS_ioctl, fd, TCFLSH, queue_selector); + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/tcgetattr.cpp b/libc/src/termios/linux/tcgetattr.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/tcgetattr.cpp @@ -0,0 +1,46 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/tcgetattr.h" +#include "kernel_termios.h" + +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" + +#include // Safe to include without the risk of name pollution. +#include +#include // For syscall numbers +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, tcgetattr, (int fd, struct termios *t)) { + __llvm_libc::kernel_termios kt; + long ret = __llvm_libc::syscall_impl(SYS_ioctl, fd, TCGETS, &kt); + if (ret < 0) { + errno = -ret; + return -1; + } + t->c_iflag = kt.c_iflag; + 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; + + size_t nccs = KERNEL_NCCS <= NCCS ? KERNEL_NCCS : NCCS; + for (size_t i = 0; i < nccs; ++i) + t->c_cc[i] = kt.c_cc[i]; + if (NCCS > nccs) { + for (size_t i = nccs; i < NCCS; ++i) + t->c_cc[i] = 0; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/tcgetsid.cpp b/libc/src/termios/linux/tcgetsid.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/tcgetsid.cpp @@ -0,0 +1,31 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/tcgetsid.h" + +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" + +#include // Safe to include without the risk of name pollution. +#include +#include // For syscall numbers +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(pid_t, tcgetsid, (int fd)) { + pid_t sid; + long ret = __llvm_libc::syscall_impl(SYS_ioctl, fd, TIOCGSID, &sid); + if (ret < 0) { + errno = -ret; + return -1; + } + return sid; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/tcsendbreak.cpp b/libc/src/termios/linux/tcsendbreak.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/tcsendbreak.cpp @@ -0,0 +1,33 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/tcsendbreak.h" + +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" + +#include // Safe to include without the risk of name pollution. +#include +#include // For syscall numbers +#include + +namespace __llvm_libc { + +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. + long ret = __llvm_libc::syscall_impl(SYS_ioctl, fd, TCSBRK, 0); + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/linux/tcsetattr.cpp b/libc/src/termios/linux/tcsetattr.cpp new file mode 100644 --- /dev/null +++ b/libc/src/termios/linux/tcsetattr.cpp @@ -0,0 +1,62 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/termios/tcsetattr.h" +#include "kernel_termios.h" + +#include "src/__support/OSUtil/syscall.h" +#include "src/__support/common.h" + +#include // Safe to include without the risk of name pollution. +#include +#include // For syscall numbers +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, tcsetattr, + (int fd, int actions, const struct termios *t)) { + struct kernel_termios kt; + long cmd; + + switch (actions) { + case TCSANOW: + cmd = TCSETS; + break; + case TCSADRAIN: + cmd = TCSETSW; + break; + case TCSAFLUSH: + cmd = TCSETSF; + break; + default: + errno = EINVAL; + return -1; + } + + kt.c_iflag = t->c_iflag; + kt.c_oflag = t->c_oflag; + kt.c_cflag = t->c_cflag; + kt.c_lflag = t->c_lflag; + size_t nccs = KERNEL_NCCS <= NCCS ? KERNEL_NCCS : NCCS; + for (size_t i = 0; i < nccs; ++i) + kt.c_cc[i] = t->c_cc[i]; + if (nccs < KERNEL_NCCS) { + for (size_t i = nccs; i < KERNEL_NCCS; ++i) + kt.c_cc[i] = 0; + } + + long ret = __llvm_libc::syscall_impl(SYS_ioctl, fd, cmd, &kt); + if (ret < 0) { + errno = -ret; + return -1; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/termios/tcdrain.h b/libc/src/termios/tcdrain.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/tcdrain.h @@ -0,0 +1,20 @@ +//===-- Implementation header for tcdrain -----------------------*- 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_UNISTD_TCDRAIN_H +#define LLVM_LIBC_SRC_UNISTD_TCDRAIN_H + +#include + +namespace __llvm_libc { + +int tcdrain(int fd); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_TCDRAIN_H diff --git a/libc/src/termios/tcflow.h b/libc/src/termios/tcflow.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/tcflow.h @@ -0,0 +1,20 @@ +//===-- Implementation header for tcflow ------------------------*- 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_UNISTD_TCFLOW_H +#define LLVM_LIBC_SRC_UNISTD_TCFLOW_H + +#include + +namespace __llvm_libc { + +int tcflow(int fd, int action); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_TCFLOW_H diff --git a/libc/src/termios/tcflush.h b/libc/src/termios/tcflush.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/tcflush.h @@ -0,0 +1,20 @@ +//===-- Implementation header for tcflush -----------------------*- 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_UNISTD_TCFLUSH_H +#define LLVM_LIBC_SRC_UNISTD_TCFLUSH_H + +#include + +namespace __llvm_libc { + +int tcflush(int fd, int queue_selector); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_TCFLUSH_H diff --git a/libc/src/termios/tcgetattr.h b/libc/src/termios/tcgetattr.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/tcgetattr.h @@ -0,0 +1,20 @@ +//===-- Implementation header for tcgetattr ---------------------*- 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_TERMIOS_TCGETATTR_H +#define LLVM_LIBC_SRC_TERMIOS_TCGETATTR_H + +#include + +namespace __llvm_libc { + +int tcgetattr(int fd, struct termios *t); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_TERMIOS_TCGETATTR_H diff --git a/libc/src/termios/tcgetsid.h b/libc/src/termios/tcgetsid.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/tcgetsid.h @@ -0,0 +1,20 @@ +//===-- Implementation header for tcgetsid ----------------------*- 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_TERMIOS_TCGETSID_H +#define LLVM_LIBC_SRC_TERMIOS_TCGETSID_H + +#include + +namespace __llvm_libc { + +pid_t tcgetsid(int fd); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_TERMIOS_TCGETSID_H diff --git a/libc/src/termios/tcsendbreak.h b/libc/src/termios/tcsendbreak.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/tcsendbreak.h @@ -0,0 +1,20 @@ +//===-- Implementation header for tcsendbreak -------------------*- 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_UNISTD_TCSENDBREAK_H +#define LLVM_LIBC_SRC_UNISTD_TCSENDBREAK_H + +#include + +namespace __llvm_libc { + +int tcsendbreak(int fd, int duration); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_TCSENDBREAK_H diff --git a/libc/src/termios/tcsetattr.h b/libc/src/termios/tcsetattr.h new file mode 100644 --- /dev/null +++ b/libc/src/termios/tcsetattr.h @@ -0,0 +1,20 @@ +//===-- Implementation header for tcsetattr ---------------------*- 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_TERMIOS_TCSETATTR_H +#define LLVM_LIBC_SRC_TERMIOS_TCSETATTR_H + +#include + +namespace __llvm_libc { + +int tcsetattr(int fd, int actions, const struct termios *t); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_TERMIOS_TCSETATTR_H diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -40,6 +40,7 @@ add_subdirectory(fcntl) add_subdirectory(sched) add_subdirectory(sys) + add_subdirectory(termios) add_subdirectory(unistd) endif() diff --git a/libc/test/src/termios/CMakeLists.txt b/libc/test/src/termios/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/test/src/termios/CMakeLists.txt @@ -0,0 +1,22 @@ +add_libc_testsuite(libc_termios_unittests) + +add_libc_unittest( + termios_test + SUITE + libc_termios_unittests + SRCS + termios_test.cpp + DEPENDS + libc.include.errno + libc.include.termios + libc.src.fcntl.open + libc.src.termios.cfgetispeed + libc.src.termios.cfgetospeed + libc.src.termios.cfsetispeed + libc.src.termios.cfsetospeed + libc.src.termios.tcgetattr + libc.src.termios.tcgetsid + libc.src.termios.tcsetattr + libc.src.unistd.close + libc.test.errno_setter_matcher +) diff --git a/libc/test/src/termios/termios_test.cpp b/libc/test/src/termios/termios_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/termios/termios_test.cpp @@ -0,0 +1,61 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/fcntl/open.h" +#include "src/termios/cfgetispeed.h" +#include "src/termios/cfgetospeed.h" +#include "src/termios/cfsetispeed.h" +#include "src/termios/cfsetospeed.h" +#include "src/termios/tcgetattr.h" +#include "src/termios/tcgetsid.h" +#include "src/termios/tcsetattr.h" +#include "src/unistd/close.h" +#include "test/ErrnoSetterMatcher.h" +#include "utils/UnitTest/Test.h" + +#include +#include + +using __llvm_libc::testing::ErrnoSetterMatcher::Fails; +using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds; + +// We just list a bunch of smoke tests here as it is not possible to +// test functionality at the least because we want to run the tests +// from ninja/make which change the terminal behavior. + +TEST(LlvmLibcTermiosTest, SpeedSmokeTest) { + struct termios t; + errno = 0; + ASSERT_THAT(__llvm_libc::cfsetispeed(&t, B50), Succeeds(0)); + ASSERT_EQ(__llvm_libc::cfgetispeed(&t), speed_t(B50)); + ASSERT_THAT(__llvm_libc::cfsetospeed(&t, B75), Succeeds(0)); + ASSERT_EQ(__llvm_libc::cfgetospeed(&t), speed_t(B75)); + + errno = 0; + ASSERT_THAT(__llvm_libc::cfsetispeed(&t, ~CBAUD), Fails(EINVAL)); + errno = 0; + ASSERT_THAT(__llvm_libc::cfsetospeed(&t, ~CBAUD), Fails(EINVAL)); +} + +TEST(LlvmLibcTermiosTest, GetAttrSmokeTest) { + struct termios t; + errno = 0; + int fd = __llvm_libc::open("/dev/tty", O_RDONLY); + ASSERT_EQ(errno, 0); + ASSERT_GT(fd, 0); + ASSERT_THAT(__llvm_libc::tcgetattr(fd, &t), Succeeds(0)); + ASSERT_EQ(__llvm_libc::close(fd), 0); +} + +TEST(LlvmLibcTermiosTest, TcGetSidSmokeTest) { + int fd = __llvm_libc::open("/dev/tty", O_RDONLY); + ASSERT_EQ(errno, 0); + ASSERT_GT(fd, 0); + ASSERT_GT(__llvm_libc::tcgetsid(fd), pid_t(0)); + ASSERT_EQ(__llvm_libc::close(fd), 0); +}