diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake index 48f847a1a00efe..f98ad8be3cfc08 100644 --- a/eng/native/tryrun.cmake +++ b/eng/native/tryrun.cmake @@ -102,6 +102,7 @@ elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|riscv64|s39 set_cache_value(PTHREAD_CREATE_MODIFIES_ERRNO_EXITCODE 1) set_cache_value(REALPATH_SUPPORTS_NONEXISTENT_FILES_EXITCODE 1) set_cache_value(SEM_INIT_MODIFIES_ERRNO_EXITCODE 1) + set_cache_value(HAVE_TERMIOS2_EXITCODE 0) if(ALPINE_LINUX) @@ -128,6 +129,7 @@ elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|riscv64|s39 set_cache_value(UNGETC_NOT_RETURN_EOF 0) set_cache_value(HAVE_COMPATIBLE_ILOGBNAN 1) set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0) + set_cache_value(HAVE_TERMIOS2_EXITCODE 1) elseif(ILLUMOS) set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 1) set_cache_value(HAVE_COMPATIBLE_ACOS_EXITCODE 1) @@ -146,6 +148,7 @@ elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|riscv64|s39 set_cache_value(HAVE_SET_MAX_VARIABLE 1) set_cache_value(HAVE_FULLY_FEATURED_PTHREAD_MUTEXES 1) set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0) + set_cache_value(HAVE_TERMIOS2_EXITCODE 1) elseif (TIZEN) set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0) endif() diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index 7d78597da3861c..b346c80953abc6 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -146,6 +146,7 @@ #cmakedefine01 HAVE_MAKEDEV_FILEH #cmakedefine01 HAVE_MAKEDEV_SYSMACROSH #cmakedefine01 HAVE_GETGRGID_R +#cmakedefine01 HAVE_TERMIOS2 // Mac OS X has stat64, but it is deprecated since plain stat now // provides the same 64-bit aware struct when targeting OS X > 10.5 diff --git a/src/native/libs/System.IO.Ports.Native/CMakeLists.txt b/src/native/libs/System.IO.Ports.Native/CMakeLists.txt index b78dce7aa2e0af..8c548a548273ab 100644 --- a/src/native/libs/System.IO.Ports.Native/CMakeLists.txt +++ b/src/native/libs/System.IO.Ports.Native/CMakeLists.txt @@ -1,18 +1,26 @@ project(System.IO.Ports.Native C) +set(PORTS_SOURCES + pal_termios.c + pal_serial.c +) + +if (HAVE_TERMIOS2) + list (APPEND PORTS_SOURCES pal_termios2.c) +endif () + + if (GEN_SHARED_LIB) add_library(System.IO.Ports.Native SHARED - pal_termios.c - pal_serial.c + ${PORTS_SOURCES} ${VERSION_FILE_PATH} ) endif() add_library(System.IO.Ports.Native-Static STATIC - pal_termios.c - pal_serial.c + ${PORTS_SOURCES} ) set_target_properties(System.IO.Ports.Native-Static PROPERTIES OUTPUT_NAME System.IO.Ports.Native CLEAN_DIRECT_OUTPUT 1) diff --git a/src/native/libs/System.IO.Ports.Native/pal_termios.c b/src/native/libs/System.IO.Ports.Native/pal_termios.c index 28d98f105e89b2..33f6057f695c11 100644 --- a/src/native/libs/System.IO.Ports.Native/pal_termios.c +++ b/src/native/libs/System.IO.Ports.Native/pal_termios.c @@ -355,13 +355,16 @@ int32_t SystemIoPortsNative_TermiosSetSpeed(intptr_t handle, int32_t speed) if (brate == B0) { -#if HAVE_IOSS_H // Looks like custom speed out of POSIX. Let see if we can set it via specialized call. +#if HAVE_IOSS_H brate = speed; if (ioctl(fd, IOSSIOSPEED, &brate) != -1) { return speed; } +#endif +#if HAVE_TERMIOS2 + return SystemIoPortsNative_Termios2SetSpeed(fd, speed); #endif errno = EINVAL; return -1; @@ -518,7 +521,7 @@ int32_t SystemIoPortsNative_TermiosReset(intptr_t handle, int32_t speed, int32_t brate = TermiosSpeed2Rate(speed); if (brate == B0) { -#if !HAVE_IOSS_H +#if !HAVE_IOSS_H && !HAVE_TERMIOS2 // We can try to set non-standard speed after tcsetattr(). errno = EINVAL; return -1; @@ -539,17 +542,20 @@ int32_t SystemIoPortsNative_TermiosReset(intptr_t handle, int32_t speed, int32_t return -1; } -#if HAVE_IOSS_H if (speed && brate == B0) { +#if HAVE_IOSS_H // we have deferred non-standard speed. brate = speed; if (ioctl(fd, IOSSIOSPEED, &brate) == -1) { return -1; } - } #endif +#if HAVE_TERMIOS2 + return SystemIoPortsNative_Termios2SetSpeed(fd, speed); +#endif + } return 0; } diff --git a/src/native/libs/System.IO.Ports.Native/pal_termios.h b/src/native/libs/System.IO.Ports.Native/pal_termios.h index 5ee2a7c95e9928..9d45a976347b75 100644 --- a/src/native/libs/System.IO.Ports.Native/pal_termios.h +++ b/src/native/libs/System.IO.Ports.Native/pal_termios.h @@ -4,6 +4,8 @@ #include "pal_types.h" #include "pal_compiler.h" +int SystemIoPortsNative_Termios2SetSpeed(int fd, int speed); + PALEXPORT int32_t SystemIoPortsNative_TermiosGetSignal(intptr_t fd, int32_t signal); PALEXPORT int32_t SystemIoPortsNative_TermiosSetSignal(intptr_t fd, int32_t signal, int32_t set); PALEXPORT int32_t SystemIoPortsNative_TermiosGetAllSignals(intptr_t fd); diff --git a/src/native/libs/System.IO.Ports.Native/pal_termios2.c b/src/native/libs/System.IO.Ports.Native/pal_termios2.c new file mode 100644 index 00000000000000..d390cbd20c15ae --- /dev/null +++ b/src/native/libs/System.IO.Ports.Native/pal_termios2.c @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "pal_types.h" +#include "pal_utilities.h" +#include +#include +#include + +int SystemIoPortsNative_Termios2SetSpeed(int fd, int speed) +{ + struct termios2 tio2; + if (ioctl(fd, TCGETS2, &tio2) < 0) + { + return -1; + } + + tio2.c_cflag &= ~(CBAUD | CBAUDEX | ((CBAUD | CBAUDEX) << IBSHIFT)); + tio2.c_cflag |= BOTHER | (BOTHER << IBSHIFT); + tio2.c_ospeed = speed; + tio2.c_ispeed = speed; + + if (ioctl(fd, TCSETS2, &tio2) < 0) + { + return -1; + } + + return 0; +} + + diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 87a4b430e4a10f..0b86bd6df64ed7 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -1157,6 +1157,19 @@ check_symbol_exists( grp.h HAVE_GETGRGID_R) +check_c_source_compiles( + " + #include + #include + + int main(void) + { + struct termios2 t; + return 0; + } + " + HAVE_TERMIOS2) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Common/pal_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/Common/pal_config.h)