From 9eac73b23942bddab9074d4a6dc286d221071c20 Mon Sep 17 00:00:00 2001 From: wfurt Date: Wed, 11 Jan 2023 19:52:07 -0800 Subject: [PATCH 1/3] allow to set custom serial speed on Linux --- src/native/libs/Common/pal_config.h.in | 1 + .../System.IO.Ports.Native/CMakeLists.txt | 16 +++++++--- .../libs/System.IO.Ports.Native/pal_termios.c | 14 ++++++--- .../libs/System.IO.Ports.Native/pal_termios.h | 2 ++ .../System.IO.Ports.Native/pal_termios2.c | 30 +++++++++++++++++++ src/native/libs/configure.cmake | 13 ++++++++ 6 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 src/native/libs/System.IO.Ports.Native/pal_termios2.c diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index acacfb33e34a3c..66be86e51cfc69 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -136,6 +136,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..be493faecf00b1 --- /dev/null +++ b/src/native/libs/System.IO.Ports.Native/pal_termios2.c @@ -0,0 +1,30 @@ +// 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 + +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 7c5b88e96d5d0f..96154854fa0633 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -1101,6 +1101,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) From 4961dbe6d377b446c4068af354a3c4063c5a582d Mon Sep 17 00:00:00 2001 From: wfurt Date: Thu, 12 Jan 2023 15:10:09 -0800 Subject: [PATCH 2/3] fix compilation on alpine --- src/native/libs/System.IO.Ports.Native/pal_termios2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/native/libs/System.IO.Ports.Native/pal_termios2.c b/src/native/libs/System.IO.Ports.Native/pal_termios2.c index be493faecf00b1..d390cbd20c15ae 100644 --- a/src/native/libs/System.IO.Ports.Native/pal_termios2.c +++ b/src/native/libs/System.IO.Ports.Native/pal_termios2.c @@ -4,6 +4,7 @@ #include "pal_types.h" #include "pal_utilities.h" #include +#include #include int SystemIoPortsNative_Termios2SetSpeed(int fd, int speed) From 278f95dd0a5d3356b252705f77b1ba44d9298b94 Mon Sep 17 00:00:00 2001 From: wfurt Date: Mon, 16 Jan 2023 10:39:53 -0800 Subject: [PATCH 3/3] add entries for cross build --- eng/native/tryrun.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake index 6355b0988f7ca9..dd675aa3feac22 100644 --- a/eng/native/tryrun.cmake +++ b/eng/native/tryrun.cmake @@ -126,6 +126,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) @@ -144,6 +145,9 @@ 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) + else() + set_cache_value(HAVE_TERMIOS2_EXITCODE 0) endif() else() message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, armv6, arm64, loongarch64, s390x, ppc64le and x86 are supported!")