From 8db7b42c73c77d7ed0cf2881b114193e08826d90 Mon Sep 17 00:00:00 2001 From: Rich Landau Date: Tue, 27 Aug 2024 13:27:41 +0000 Subject: [PATCH 01/51] Added add-to-project workflow --- .github/workflows/add-to-project.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/add-to-project.yml diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml new file mode 100644 index 000000000..b002fcfd9 --- /dev/null +++ b/.github/workflows/add-to-project.yml @@ -0,0 +1,19 @@ +name: Add issues to project + +on: + issues: + types: + - opened + +jobs: + add-to-project: + name: Add issue to project + runs-on: Linux + steps: + # This action doesn't exist in enterprise, manually added to cFS org for now + - uses: cFS/add-to-project@v1.0.2 + with: + # You can target a project in a different organization + # to the issue + project-url: https://github.com/orgs/cFS/projects/1 + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} \ No newline at end of file From fd9c520c123e2723bdb11cf050d3763faefe9f04 Mon Sep 17 00:00:00 2001 From: "Cudmore, Alan P 122454046" Date: Tue, 5 Nov 2024 13:52:33 -0500 Subject: [PATCH 02/51] [#4] first commit of VxWorks 7 RTP support - modified posix --- src/bsp/generic-vxworks-rtp/CMakeLists.txt | 20 ++ src/bsp/generic-vxworks-rtp/src/bsp_console.c | 69 ++++++ src/bsp/generic-vxworks-rtp/src/bsp_start.c | 212 ++++++++++++++++++ .../src/generic_vxworks_rtp_bsp_internal.h | 50 +++++ .../portable/os-impl-no-network-gethostid.c | 44 ++++ ...ork.c => os-impl-no-network-gethostname.c} | 11 - .../os-impl-posix-network-gethostid.c | 63 ++++++ ....c => os-impl-posix-network-gethostname.c} | 14 -- src/os/posix/CMakeLists.txt | 15 +- src/os/posix/inc/os-posix.h | 1 - src/os/posix/src/os-impl-files.c | 4 + src/os/posix/src/os-impl-filesys.c | 18 +- 12 files changed, 489 insertions(+), 32 deletions(-) create mode 100644 src/bsp/generic-vxworks-rtp/CMakeLists.txt create mode 100644 src/bsp/generic-vxworks-rtp/src/bsp_console.c create mode 100644 src/bsp/generic-vxworks-rtp/src/bsp_start.c create mode 100644 src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h create mode 100644 src/os/portable/os-impl-no-network-gethostid.c rename src/os/portable/{os-impl-no-network.c => os-impl-no-network-gethostname.c} (84%) create mode 100644 src/os/portable/os-impl-posix-network-gethostid.c rename src/os/portable/{os-impl-posix-network.c => os-impl-posix-network-gethostname.c} (86%) diff --git a/src/bsp/generic-vxworks-rtp/CMakeLists.txt b/src/bsp/generic-vxworks-rtp/CMakeLists.txt new file mode 100644 index 000000000..96b10e04b --- /dev/null +++ b/src/bsp/generic-vxworks-rtp/CMakeLists.txt @@ -0,0 +1,20 @@ +###################################################################### +# +# CMAKE build recipe for LINUX Board Support Package (BSP) +# +###################################################################### + +# This basic implementation library should be generic enough to use +# on any Linux-based processor board, as well as a standard development PC. +add_library(osal_generic-vxworks-rtp_impl OBJECT + src/bsp_start.c + src/bsp_console.c +) + +# The "-u" switch is required to ensure that the linker pulls in the OS_BSPMain entry point +target_link_libraries(osal_public_api INTERFACE -umain -uOS_Application_Run -uOS_Application_Start -uCFE_TBL_Manage -uCFE_TBL_GetAddress) + +# This BSP only works with "vxworks-rtp" OS layer. +# Confirming this reduces risk of accidental misconfiguration +set_property(TARGET osal_generic-vxworks-rtp_impl PROPERTY OSAL_EXPECTED_OSTYPE "posix") + diff --git a/src/bsp/generic-vxworks-rtp/src/bsp_console.c b/src/bsp/generic-vxworks-rtp/src/bsp_console.c new file mode 100644 index 000000000..7fe9841bd --- /dev/null +++ b/src/bsp/generic-vxworks-rtp/src/bsp_console.c @@ -0,0 +1,69 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/* + * File: bsp_console.c + * + * Purpose: + * OSAL BSP debug console abstraction + */ + +#include +#include +#include +#include +#include +#include + +#include "generic_vxworks_rtp_bsp_internal.h" +#include "bsp-impl.h" + +/**************************************************************************************** + BSP CONSOLE IMPLEMENTATION FUNCTIONS + ****************************************************************************************/ + +/*---------------------------------------------------------------- + OS_BSP_ConsoleOutput_Impl + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_ConsoleOutput_Impl(const char *Str, size_t DataLen) +{ + ssize_t WriteLen; + + while (DataLen > 0) + { + /* writes the raw data directly to STDOUT_FILENO (unbuffered) */ + WriteLen = write(STDOUT_FILENO, Str, DataLen); + if (WriteLen <= 0) + { + /* no recourse if this fails, just stop. */ + break; + } + Str += WriteLen; + DataLen -= WriteLen; + } +} + +/*---------------------------------------------------------------- + OS_BSP_ConsoleSetMode_Impl() definition + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_ConsoleSetMode_Impl(uint32 ModeBits) +{ + return; +} diff --git a/src/bsp/generic-vxworks-rtp/src/bsp_start.c b/src/bsp/generic-vxworks-rtp/src/bsp_start.c new file mode 100644 index 000000000..b222df534 --- /dev/null +++ b/src/bsp/generic-vxworks-rtp/src/bsp_start.c @@ -0,0 +1,212 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/* + * File: bsp_start.c + * + * Purpose: + * OSAL BSP main entry point. + * + * History: + * 2005/07/26 A. Cudmore | Initial version for linux + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "generic_vxworks_rtp_bsp_internal.h" + +OS_BSP_GenericVxWorksRtpGlobalData_t OS_BSP_GenericVxWorksRtpGlobal; + +/* --------------------------------------------------------- + OS_BSP_Initialize() + + Helper function to auto-create any missing FS_BASED mount + points listed in OS_VolumeTable. If these do not actually + exist then app code may fail. + --------------------------------------------------------- */ +void OS_BSP_Initialize(void) +{ + pthread_mutexattr_t mutex_attr; + int status; + + /* Initialize the low level access mutex (w/priority inheritance) */ + status = pthread_mutexattr_init(&mutex_attr); + if (status < 0) + { + BSP_DEBUG("pthread_mutexattr_init: %s\n", strerror(status)); + } + status = pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT); + if (status < 0) + { + BSP_DEBUG("pthread_mutexattr_setprotocol: %s\n", strerror(status)); + } + status = pthread_mutex_init(&OS_BSP_GenericVxWorksRtpGlobal.AccessMutex, &mutex_attr); + if (status < 0) + { + BSP_DEBUG("pthread_mutex_init: %s\n", strerror(status)); + } +} + +/*---------------------------------------------------------------- + OS_BSP_Lock_Impl + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_Lock_Impl(void) +{ + int status; + + status = pthread_mutex_lock(&OS_BSP_GenericVxWorksRtpGlobal.AccessMutex); + if (status < 0) + { + BSP_DEBUG("pthread_mutex_lock: %s\n", strerror(status)); + } + else + { + /* + * Temporarily Disable/Defer thread cancellation. + * Note that OS_BSP_ConsoleOutput_Impl() calls write() which is a cancellation point. + * So if this calling task is canceled, it risks leaving the BSP locked. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &OS_BSP_GenericVxWorksRtpGlobal.AccessCancelState); + } +} + +/*---------------------------------------------------------------- + OS_BSP_Unlock_Impl + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_Unlock_Impl(void) +{ + int status; + + status = pthread_mutex_unlock(&OS_BSP_GenericVxWorksRtpGlobal.AccessMutex); + if (status < 0) + { + BSP_DEBUG("pthread_mutex_unlock: %s\n", strerror(status)); + } + else + { + /* Restore previous cancellability state */ + pthread_setcancelstate(OS_BSP_GenericVxWorksRtpGlobal.AccessCancelState, NULL); + } +} + +/* --------------------------------------------------------- + OS_BSP_GetReturnStatus() + + Helper function to convert an OSAL status code into + a code suitable for returning to the OS. + --------------------------------------------------------- */ +int OS_BSP_GetReturnStatus(void) +{ + int retcode; + + switch (OS_BSP_Global.AppStatus) + { + case OS_SUCCESS: + /* translate OS_SUCCESS to the system EXIT_SUCCESS value (usually 0) */ + retcode = EXIT_SUCCESS; + break; + + case OS_ERROR: + /* translate OS_ERROR to the system EXIT_FAILURE value (usually 1) */ + retcode = EXIT_FAILURE; + break; + + default: + /* any other value will be passed through (implementation-defined) */ + /* Range is limited to 0-127, however */ + retcode = OS_BSP_Global.AppStatus & 0x7F; + break; + } + + return retcode; +} + +/* --------------------------------------------------------- + OS_BSP_Shutdown_Impl() + + Helper function to abort the running task + --------------------------------------------------------- */ +void OS_BSP_Shutdown_Impl(void) +{ + abort(); +} + +/****************************************************************************** +** +** Purpose: +** BSP Application entry point. +** +** Arguments: +** (none) +** +** Return: +** (none) +*/ + +int main(int argc, char *argv[]) +{ + /* + * Initially clear the global objects + */ + memset(&OS_BSP_Global, 0, sizeof(OS_BSP_Global)); + memset(&OS_BSP_GenericVxWorksRtpGlobal, 0, sizeof(OS_BSP_GenericVxWorksRtpGlobal)); + + /* + * Save the argc/argv arguments for future use. + * In particular the UT-specific logic uses this + * to control verbosity. + * + * Note that the first argument (0) is the command name. The + * first "real" argument is at position 1. + * + * However this still needs to pass it through as the application + * might still want to use library "getopt" and this expects the + * first parameter to be this way. + */ + OS_BSP_Global.ArgC = argc; + OS_BSP_Global.ArgV = argv; + + /* + * Perform any other BSP-specific initialization + */ + OS_BSP_Initialize(); + + /* + * Call application specific entry point. + * This should set up all user tasks and resources, then return + */ + OS_Application_Startup(); + + /* + * OS_Application_Run() implements the background task. + * The user application may provide this, or a default implementation + * is used which just calls OS_IdleLoop(). + */ + OS_Application_Run(); + + /* Should typically never get here */ + return OS_BSP_GetReturnStatus(); +} diff --git a/src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h b/src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h new file mode 100644 index 000000000..160f10b2d --- /dev/null +++ b/src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h @@ -0,0 +1,50 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * + * Purpose: + * Header file for internal data to the LINUX BSP + */ + +#ifndef GENERIC_VXWORKS_BSP_INTERNAL_H +#define GENERIC_VXWORKS_BSP_INTERNAL_H + +#include "osapi-common.h" +#include "osapi-bsp.h" +#include "osapi-error.h" +#include "bsp-impl.h" + +#include + +/* +** BSP types +*/ +typedef struct +{ + pthread_mutex_t AccessMutex; + int AccessCancelState; +} OS_BSP_GenericVxWorksRtpGlobalData_t; + +/* + * Global Data object + */ +extern OS_BSP_GenericVxWorksRtpGlobalData_t OS_BSP_GenericVxWorksRtpGlobal; + +#endif /* GENERIC_VXWORKS_RTP_BSP_INTERNAL_H */ diff --git a/src/os/portable/os-impl-no-network-gethostid.c b/src/os/portable/os-impl-no-network-gethostid.c new file mode 100644 index 000000000..63567751d --- /dev/null +++ b/src/os/portable/os-impl-no-network-gethostid.c @@ -0,0 +1,44 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * This file contains the network implementation for + * systems where OSAL_CONFIG_INCLUDE_NETWORK is false or otherwise + * do not provide any network functions. + * + */ + +#include "os-shared-network.h" + +/**************************************************************************************** + Network API + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_NetworkGetID_Impl(int32 *IdBuf) +{ + return OS_ERR_NOT_IMPLEMENTED; +} diff --git a/src/os/portable/os-impl-no-network.c b/src/os/portable/os-impl-no-network-gethostname.c similarity index 84% rename from src/os/portable/os-impl-no-network.c rename to src/os/portable/os-impl-no-network-gethostname.c index ba871eb3d..83513a80f 100644 --- a/src/os/portable/os-impl-no-network.c +++ b/src/os/portable/os-impl-no-network-gethostname.c @@ -32,17 +32,6 @@ Network API ***************************************************************************************/ -/*---------------------------------------------------------------- - * - * Purpose: Implemented per internal OSAL API - * See prototype for argument/return detail - * - *-----------------------------------------------------------------*/ -int32 OS_NetworkGetID_Impl(int32 *IdBuf) -{ - return OS_ERR_NOT_IMPLEMENTED; -} - /*---------------------------------------------------------------- * * Purpose: Implemented per internal OSAL API diff --git a/src/os/portable/os-impl-posix-network-gethostid.c b/src/os/portable/os-impl-posix-network-gethostid.c new file mode 100644 index 000000000..f96f61902 --- /dev/null +++ b/src/os/portable/os-impl-posix-network-gethostid.c @@ -0,0 +1,63 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * This file contains the network functionality for + * systems which implement the POSIX-defined network hostname/id functions. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +/* + * Inclusions Defined by OSAL layer. + * + * This must include whatever is required to get the prototypes of these functions: + * + * gethostid() + * + * Both of these routines should conform to X/Open 5 definition. + */ +#include +#include + +#include "os-impl-network.h" +#include "os-shared-network.h" + +/**************************************************************************************** + Network API + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_NetworkGetID_Impl(int32 *IdBuf) +{ +#ifndef VX7_RTP + /* gethostid() has no failure modes */ + *IdBuf = gethostid(); +#endif + return OS_SUCCESS; +} diff --git a/src/os/portable/os-impl-posix-network.c b/src/os/portable/os-impl-posix-network-gethostname.c similarity index 86% rename from src/os/portable/os-impl-posix-network.c rename to src/os/portable/os-impl-posix-network-gethostname.c index 5c028b50f..4f90fc744 100644 --- a/src/os/portable/os-impl-posix-network.c +++ b/src/os/portable/os-impl-posix-network-gethostname.c @@ -34,7 +34,6 @@ * This must include whatever is required to get the prototypes of these functions: * * gethostname() - * gethostid() * * Both of these routines should conform to X/Open 5 definition. */ @@ -74,16 +73,3 @@ int32 OS_NetworkGetHostName_Impl(char *host_name, size_t name_len) return return_code; } - -/*---------------------------------------------------------------- - * - * Purpose: Implemented per internal OSAL API - * See prototype for argument/return detail - * - *-----------------------------------------------------------------*/ -int32 OS_NetworkGetID_Impl(int32 *IdBuf) -{ - /* gethostid() has no failure modes */ - *IdBuf = gethostid(); - return OS_SUCCESS; -} diff --git a/src/os/posix/CMakeLists.txt b/src/os/posix/CMakeLists.txt index 9b7c1e3e5..6f1c8c715 100644 --- a/src/os/posix/CMakeLists.txt +++ b/src/os/posix/CMakeLists.txt @@ -65,11 +65,22 @@ endif () if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation - ../portable/os-impl-posix-network.c # Use POSIX-defined hostname/id implementation ) + if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation + ../portable/os-impl-posix-network-gethostid.c # Use POSIX-defined hostid implementation + ) + else() + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation + ../portable/os-impl-no-network-gethostid.c # non-implemented versions of gethostid API + ) + endif() else() list(APPEND POSIX_IMPL_SRCLIST - ../portable/os-impl-no-network.c # non-implemented versions of all network APIs + ../portable/os-impl-no-network-gethostname.c # non-implemented versions of gethostname API + ../portable/os-impl-no-network-gethostid.c # non-implemented versions of gethostid API ../portable/os-impl-no-sockets.c # non-implemented versions of all socket APIs ) endif () diff --git a/src/os/posix/inc/os-posix.h b/src/os/posix/inc/os-posix.h index c8bc190d9..1d8024da6 100644 --- a/src/os/posix/inc/os-posix.h +++ b/src/os/posix/inc/os-posix.h @@ -45,7 +45,6 @@ #include #include #include -#include /* * Use the global definitions from the shared layer diff --git a/src/os/posix/src/os-impl-files.c b/src/os/posix/src/os-impl-files.c index 601ca942c..fd51c910e 100644 --- a/src/os/posix/src/os-impl-files.c +++ b/src/os/posix/src/os-impl-files.c @@ -67,7 +67,11 @@ gid_t OS_IMPL_SELF_EGID = 0; * In turn, the implementation will utilize select() to determine * a filehandle readiness to read/write. */ +#ifdef VXWORKS_RTP +const int OS_IMPL_REGULAR_FILE_FLAGS = 0; +#else const int OS_IMPL_REGULAR_FILE_FLAGS = O_NONBLOCK; +#endif /**************************************************************************************** IMPLEMENTATION-SPECIFIC ROUTINES diff --git a/src/os/posix/src/os-impl-filesys.c b/src/os/posix/src/os-impl-filesys.c index d2d5c6c8d..3bc5b5980 100644 --- a/src/os/posix/src/os-impl-filesys.c +++ b/src/os/posix/src/os-impl-filesys.c @@ -35,10 +35,14 @@ #include #include #include + +#ifndef VXWORKS_RTP #include +#include +#endif + #include #include -#include #include "os-posix.h" #include "os-shared-filesys.h" @@ -48,7 +52,11 @@ /**************************************************************************************** DEFINES ***************************************************************************************/ - +#ifndef VXWORKS_RTP +#define STATFS statvfs +#else +#define STATFS statfs +#endif /**************************************************************************************** GLOBAL DATA ***************************************************************************************/ @@ -312,12 +320,14 @@ int32 OS_FileSysUnmountVolume_Impl(const OS_object_token_t *token) int32 OS_FileSysStatVolume_Impl(const OS_object_token_t *token, OS_statvfs_t *result) { OS_filesys_internal_record_t *local; - struct statvfs stat_buf; + struct STATFS stat_buf = {0}; local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); - if (statvfs(local->system_mountpt, &stat_buf) != 0) + if (STATFS(local->system_mountpt, &stat_buf) != 0) { + memset(result, 0, sizeof(*result)); + OS_printf("statfs/statfvs returned error, errno %d\n",errno); return OS_ERROR; } From 0398814e7446b31fb6583f7b9084331cbb8fcc00 Mon Sep 17 00:00:00 2001 From: "Cudmore, Alan P 122454046" Date: Wed, 6 Nov 2024 16:49:03 -0500 Subject: [PATCH 03/51] [#4] updated posix default file flags - changed from O_NONBLOCK to 0 for VxWorks RTPs --- src/os/posix/src/os-impl-files.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/os/posix/src/os-impl-files.c b/src/os/posix/src/os-impl-files.c index fd51c910e..d31c60f2b 100644 --- a/src/os/posix/src/os-impl-files.c +++ b/src/os/posix/src/os-impl-files.c @@ -62,16 +62,8 @@ gid_t OS_IMPL_SELF_EGID = 0; /* * Flag(s) to set on file handles for regular files - * This sets all regular filehandles to be non-blocking by default. - * - * In turn, the implementation will utilize select() to determine - * a filehandle readiness to read/write. */ -#ifdef VXWORKS_RTP const int OS_IMPL_REGULAR_FILE_FLAGS = 0; -#else -const int OS_IMPL_REGULAR_FILE_FLAGS = O_NONBLOCK; -#endif /**************************************************************************************** IMPLEMENTATION-SPECIFIC ROUTINES From f7fa9601273ed7396333a31d5c7e5ad14840968f Mon Sep 17 00:00:00 2001 From: Alan Cudmore Date: Wed, 13 Nov 2024 13:49:55 -0500 Subject: [PATCH 04/51] [#4] Created separate implementation for VxWorks 7 RTP filesys. This is selected in the CMakeLists.txt file. --- src/os/posix/CMakeLists.txt | 13 +- src/os/posix/src/os-impl-filesys-vx7rtp.c | 326 ++++++++++++++++++++++ src/os/posix/src/os-impl-filesys.c | 18 +- 3 files changed, 341 insertions(+), 16 deletions(-) create mode 100644 src/os/posix/src/os-impl-filesys-vx7rtp.c diff --git a/src/os/posix/CMakeLists.txt b/src/os/posix/CMakeLists.txt index 6f1c8c715..10bba2546 100644 --- a/src/os/posix/CMakeLists.txt +++ b/src/os/posix/CMakeLists.txt @@ -16,7 +16,6 @@ set(POSIX_BASE_SRCLIST src/os-impl-dirs.c src/os-impl-errors.c src/os-impl-files.c - src/os-impl-filesys.c src/os-impl-heap.c src/os-impl-idmap.c src/os-impl-mutex.c @@ -25,6 +24,15 @@ set(POSIX_BASE_SRCLIST src/os-impl-timebase.c ) +if (OSAL_SYSTEM_OSSUBTYPE STREQUAL "vx7rtp") + list(APPEND POSIX_BASE_SRCLIST + src/os-impl-filesys-vx7rtp.c + ) +else () + list(APPEND POSIX_BASE_SRCLIST + src/os-impl-filesys.c + ) +endif () # Use portable blocks for basic I/O set(POSIX_IMPL_SRCLIST @@ -66,7 +74,8 @@ if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation ) - if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + # if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation ../portable/os-impl-posix-network-gethostid.c # Use POSIX-defined hostid implementation diff --git a/src/os/posix/src/os-impl-filesys-vx7rtp.c b/src/os/posix/src/os-impl-filesys-vx7rtp.c new file mode 100644 index 000000000..1783352ac --- /dev/null +++ b/src/os/posix/src/os-impl-filesys-vx7rtp.c @@ -0,0 +1,326 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup posix + * \author joseph.p.hickey@nasa.gov + * + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "os-posix.h" +#include "os-shared-filesys.h" +#include "os-shared-idmap.h" +#include "os-shared-common.h" + +/**************************************************************************************** + DEFINES + ***************************************************************************************/ + +/**************************************************************************************** + GLOBAL DATA + ***************************************************************************************/ +const char OS_POSIX_DEVICEFILE_PREFIX[] = "/dev/"; + +/**************************************************************************************** + Filesys API + ***************************************************************************************/ + +/* -------------------------------------------------------------------------------------- + Name: OS_Posix_FileSysAPI_Impl_Init + + Purpose: Filesystem API global initialization + + Returns: OS_SUCCESS if success + ---------------------------------------------------------------------------------------*/ +int32 OS_Posix_FileSysAPI_Impl_Init(void) +{ + return OS_SUCCESS; +} + +/* + * System Level API + */ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysStartVolume_Impl(const OS_object_token_t *token) +{ + OS_filesys_internal_record_t *local; + struct stat stat_buf; + const char * tmpdir; + size_t mplen; + size_t vollen; + uint32 i; + enum + { + VOLATILE_DISK_LOC_ENV, + VOLATILE_DISK_LOC_TMP, + VOLATILE_DISK_LOC_MAX + }; + + local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); + + /* + * Determine basic type of filesystem, if not already known + */ + if (local->fstype == OS_FILESYS_TYPE_UNKNOWN && + strncmp(local->device_name, OS_POSIX_DEVICEFILE_PREFIX, sizeof(OS_POSIX_DEVICEFILE_PREFIX) - 1) == 0) + { + /* + * If referring to a real device in the /dev filesystem, + * then assume it is a normal disk. + */ + local->fstype = OS_FILESYS_TYPE_NORMAL_DISK; + } + + /* + * For VOLATILE volumes, there are two options: + * - Using the RAMDISK environment variable, if it exists + * - The /tmp filesystem + * + * The RAMDISK path is preferable because it should point to a ramdisk. + * The /tmp file system might be a regular persistent disk, but should always exist + * on any POSIX-compliant OS. + */ + + tmpdir = NULL; + if (local->fstype == OS_FILESYS_TYPE_VOLATILE_DISK) + { + /* find a suitable location to keep the volatile disk */ + for (i = 0; i <= VOLATILE_DISK_LOC_MAX; ++i) + { + switch (i) + { + case VOLATILE_DISK_LOC_ENV: + /* try the TMPDIR environment variable, if set */ + tmpdir = getenv("RAMDISK"); + break; + case VOLATILE_DISK_LOC_TMP: + /* use /tmp directory as a last resort */ + tmpdir = "/tmp"; + break; + default: + tmpdir = NULL; + break; + } + + if (tmpdir != NULL && stat(tmpdir, &stat_buf) == 0) + { + /* check if the user has write permission to the directory */ + if ((stat_buf.st_mode & S_IWOTH) != 0 || + ((stat_buf.st_mode & S_IWGRP) != 0 && stat_buf.st_gid == getegid()) || + ((stat_buf.st_mode & S_IWUSR) != 0 && stat_buf.st_uid == geteuid())) + { + break; + } + } + } + + if (tmpdir == NULL) + { + /* OS provides no place to put the volume */ + OS_DEBUG("No storage location for volatile volumes"); + return OS_FS_ERR_DRIVE_NOT_CREATED; + } + + /* + * Note - performing the concatenation in a single snprintf() call seems + * to trigger a (false) pointer overlap warning, because volume_name should + * always be null terminated. To get around this, calculate the + * string size and check that it is within the expected size, and do the + * append of volume_name explicitly. + */ + mplen = snprintf(local->system_mountpt, sizeof(local->system_mountpt), "%s/osal:", tmpdir); + if (mplen < sizeof(local->system_mountpt)) + { + vollen = OS_strnlen(local->volume_name, sizeof(local->volume_name)); + if ((vollen + mplen) >= sizeof(local->system_mountpt)) + { + vollen = sizeof(local->system_mountpt) - mplen - 1; + } + memcpy(&local->system_mountpt[mplen], local->volume_name, vollen); + local->system_mountpt[mplen + vollen] = 0; + } + } + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysStopVolume_Impl(const OS_object_token_t *token) +{ + /* + * This is a no-op. + * + * Volatile volumes are just directories created in the temp dir, + * and this will not remove the directories just in case something + * went wrong. + * + * If the volume is started again, the directory will be re-used. + */ + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysFormatVolume_Impl(const OS_object_token_t *token) +{ + /* + * In theory, this should wipe any existing files in the ramdisk, + * but since ramdisks here are implemented using a directory within a tmpfs, + * removal of such files could be risky if something goes wrong, + * because it might remove files that were important. + * + * So the safest option is just a no-op. + * (this is also backward compatible since POSIX mkfs was always a no-op) + */ + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysMountVolume_Impl(const OS_object_token_t *token) +{ + OS_filesys_internal_record_t *local; + struct stat stat_buf; + + local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); + /* + * This will do a mkdir() for the mount point if it does + * not already exist. + */ + if (stat(local->system_mountpt, &stat_buf) != 0) + { + if (mkdir(local->system_mountpt, 0700) < 0) + { + return OS_FS_ERR_DRIVE_NOT_CREATED; + } + } + else if (!S_ISDIR(stat_buf.st_mode)) + { + return OS_FS_ERR_DRIVE_NOT_CREATED; + } + + /* + * NOTE: The mount() system call could be used here to actually + * mount a disk, if warranted. For all current POSIX-based PSPs, + * this is not needed, because the volumes are all pre-mounted + * through the system init before OSAL starts. + * + * For volatile filesystems (ramdisk) these were created within + * a temp filesystem, so all that is needed is to ensure the + * mount point exists. For any other FS type, trigger an + * error to indicate that it is not implemented in this OSAL. + */ + if (local->fstype != OS_FILESYS_TYPE_VOLATILE_DISK && local->fstype != OS_FILESYS_TYPE_FS_BASED) + { + /* the mount command is not implemented for this FS type */ + return OS_ERR_NOT_IMPLEMENTED; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysUnmountVolume_Impl(const OS_object_token_t *token) +{ + /* + * NOTE: Mounting/Unmounting on POSIX is not implemented. + * For backward compatibility this call must return success. + * + * This is a no-op. The mount point that was created during + * the mount process can stay for the next mount. + */ + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysStatVolume_Impl(const OS_object_token_t *token, OS_statvfs_t *result) +{ + OS_filesys_internal_record_t *local; + + struct statfs stat_buf = {0}; + local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); + + if (statfs(local->system_mountpt, &stat_buf) != 0) + { + memset(result, 0, sizeof(*result)); + OS_printf("statfs/statfvs returned error, errno %d\n",errno); + return OS_ERROR; + } + + result->block_size = OSAL_SIZE_C(stat_buf.f_bsize); + result->blocks_free = OSAL_BLOCKCOUNT_C(stat_buf.f_bfree); + result->total_blocks = OSAL_BLOCKCOUNT_C(stat_buf.f_blocks); + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysCheckVolume_Impl(const OS_object_token_t *token, bool repair) +{ + return OS_ERR_NOT_IMPLEMENTED; +} diff --git a/src/os/posix/src/os-impl-filesys.c b/src/os/posix/src/os-impl-filesys.c index 3bc5b5980..d2d5c6c8d 100644 --- a/src/os/posix/src/os-impl-filesys.c +++ b/src/os/posix/src/os-impl-filesys.c @@ -35,14 +35,10 @@ #include #include #include - -#ifndef VXWORKS_RTP #include -#include -#endif - #include #include +#include #include "os-posix.h" #include "os-shared-filesys.h" @@ -52,11 +48,7 @@ /**************************************************************************************** DEFINES ***************************************************************************************/ -#ifndef VXWORKS_RTP -#define STATFS statvfs -#else -#define STATFS statfs -#endif + /**************************************************************************************** GLOBAL DATA ***************************************************************************************/ @@ -320,14 +312,12 @@ int32 OS_FileSysUnmountVolume_Impl(const OS_object_token_t *token) int32 OS_FileSysStatVolume_Impl(const OS_object_token_t *token, OS_statvfs_t *result) { OS_filesys_internal_record_t *local; + struct statvfs stat_buf; - struct STATFS stat_buf = {0}; local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); - if (STATFS(local->system_mountpt, &stat_buf) != 0) + if (statvfs(local->system_mountpt, &stat_buf) != 0) { - memset(result, 0, sizeof(*result)); - OS_printf("statfs/statfvs returned error, errno %d\n",errno); return OS_ERROR; } From 7cabfd2f7fb2ebcf48fececb97fc6c9932c7a15e Mon Sep 17 00:00:00 2001 From: "Cudmore, Alan P 122454046" Date: Wed, 13 Nov 2024 14:42:03 -0500 Subject: [PATCH 05/51] [#4] comment clean up --- src/bsp/generic-vxworks-rtp/src/bsp_start.c | 2 -- .../generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bsp/generic-vxworks-rtp/src/bsp_start.c b/src/bsp/generic-vxworks-rtp/src/bsp_start.c index b222df534..e9168eaa2 100644 --- a/src/bsp/generic-vxworks-rtp/src/bsp_start.c +++ b/src/bsp/generic-vxworks-rtp/src/bsp_start.c @@ -22,8 +22,6 @@ * Purpose: * OSAL BSP main entry point. * - * History: - * 2005/07/26 A. Cudmore | Initial version for linux */ #include diff --git a/src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h b/src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h index 160f10b2d..7651f4897 100644 --- a/src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h +++ b/src/bsp/generic-vxworks-rtp/src/generic_vxworks_rtp_bsp_internal.h @@ -20,7 +20,7 @@ * \file * * Purpose: - * Header file for internal data to the LINUX BSP + * Header file for internal data to the generic VxWorks RTP BSP */ #ifndef GENERIC_VXWORKS_BSP_INTERNAL_H From 90b0279f94e3c917647f6c13febbf9ba31279064 Mon Sep 17 00:00:00 2001 From: Alan Cudmore Date: Fri, 15 Nov 2024 09:57:54 -0500 Subject: [PATCH 06/51] [#4] created a separate OSAL implementation directory, for vxworks-rtp, splitting it from the posix implementation --- src/bsp/generic-vxworks-rtp/CMakeLists.txt | 2 +- src/os/posix/CMakeLists.txt | 25 +---- src/os/vxworks-rtp/CMakeLists.txt | 93 +++++++++++++++++++ .../src/os-impl-filesys.c} | 0 4 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 src/os/vxworks-rtp/CMakeLists.txt rename src/os/{posix/src/os-impl-filesys-vx7rtp.c => vxworks-rtp/src/os-impl-filesys.c} (100%) diff --git a/src/bsp/generic-vxworks-rtp/CMakeLists.txt b/src/bsp/generic-vxworks-rtp/CMakeLists.txt index 96b10e04b..26d3b1d01 100644 --- a/src/bsp/generic-vxworks-rtp/CMakeLists.txt +++ b/src/bsp/generic-vxworks-rtp/CMakeLists.txt @@ -16,5 +16,5 @@ target_link_libraries(osal_public_api INTERFACE -umain -uOS_Application_Run -uOS # This BSP only works with "vxworks-rtp" OS layer. # Confirming this reduces risk of accidental misconfiguration -set_property(TARGET osal_generic-vxworks-rtp_impl PROPERTY OSAL_EXPECTED_OSTYPE "posix") +set_property(TARGET osal_generic-vxworks-rtp_impl PROPERTY OSAL_EXPECTED_OSTYPE "vxworks-rtp") diff --git a/src/os/posix/CMakeLists.txt b/src/os/posix/CMakeLists.txt index 10bba2546..359e8ec48 100644 --- a/src/os/posix/CMakeLists.txt +++ b/src/os/posix/CMakeLists.txt @@ -16,6 +16,7 @@ set(POSIX_BASE_SRCLIST src/os-impl-dirs.c src/os-impl-errors.c src/os-impl-files.c + src/os-impl-filesys.c src/os-impl-heap.c src/os-impl-idmap.c src/os-impl-mutex.c @@ -24,16 +25,6 @@ set(POSIX_BASE_SRCLIST src/os-impl-timebase.c ) -if (OSAL_SYSTEM_OSSUBTYPE STREQUAL "vx7rtp") - list(APPEND POSIX_BASE_SRCLIST - src/os-impl-filesys-vx7rtp.c - ) -else () - list(APPEND POSIX_BASE_SRCLIST - src/os-impl-filesys.c - ) -endif () - # Use portable blocks for basic I/O set(POSIX_IMPL_SRCLIST ../portable/os-impl-posix-gettime.c @@ -73,19 +64,9 @@ endif () if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation + ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation + ../portable/os-impl-posix-network-gethostid.c # Use POSIX-defined hostid implementation ) - # if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - list(APPEND POSIX_IMPL_SRCLIST - ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation - ../portable/os-impl-posix-network-gethostid.c # Use POSIX-defined hostid implementation - ) - else() - list(APPEND POSIX_IMPL_SRCLIST - ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation - ../portable/os-impl-no-network-gethostid.c # non-implemented versions of gethostid API - ) - endif() else() list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-no-network-gethostname.c # non-implemented versions of gethostname API diff --git a/src/os/vxworks-rtp/CMakeLists.txt b/src/os/vxworks-rtp/CMakeLists.txt new file mode 100644 index 000000000..ae1364827 --- /dev/null +++ b/src/os/vxworks-rtp/CMakeLists.txt @@ -0,0 +1,93 @@ +###################################################################### +# +# CMAKE build recipe for POSIX OSAL implementation +# +###################################################################### + +# This CMake script generates targets specific to the POSIX implementation + +# The basic set of files which are always built +set(POSIX_BASE_SRCLIST + ../posix/src/os-impl-binsem.c + ../posix/src/os-impl-common.c + ../posix/src/os-impl-console.c + ../posix/src/os-impl-condvar.c + ../posix/src/os-impl-countsem.c + ../posix/src/os-impl-dirs.c + ../posix/src/os-impl-errors.c + ../posix/src/os-impl-files.c + ../posix/src/os-impl-heap.c + ../posix/src/os-impl-idmap.c + ../posix/src/os-impl-mutex.c + ../posix/src/os-impl-queues.c + ../posix/src/os-impl-tasks.c + ../posix/src/os-impl-timebase.c + src/os-impl-filesys.c # VxWorks RTP specific implementation +) + +# Use portable blocks for basic I/O +set(POSIX_IMPL_SRCLIST + ../portable/os-impl-posix-gettime.c + ../portable/os-impl-console-bsp.c + ../portable/os-impl-bsd-select.c + ../portable/os-impl-posix-io.c + ../portable/os-impl-posix-files.c + ../portable/os-impl-posix-dirs.c +) + +if (OSAL_CONFIG_INCLUDE_SHELL) + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-shell.c + ) +else () + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-shell.c + ) +endif () + +# If some form of module loading is configured, +# then build the module loader +if (OSAL_CONFIG_INCLUDE_DYNAMIC_LOADER) + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-loader.c + ../portable/os-impl-posix-dl-loader.c + ../portable/os-impl-posix-dl-symtab.c + ) +else () + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-no-module.c + ../portable/os-impl-no-loader.c + ../portable/os-impl-no-symtab.c + ) +endif () + +# VxWorks does not support gethostid +list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-network-gethostid.c +) + +if (OSAL_CONFIG_INCLUDE_NETWORK) + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation + ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation + ) +else() + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-network-gethostname.c # non-implemented versions of gethostname API + ../portable/os-impl-no-sockets.c # non-implemented versions of all socket APIs + ) +endif () + +# Defines an OBJECT target named "osal_posix_impl" with selected source files +add_library(osal_vxworks-rtp_impl OBJECT + ${POSIX_BASE_SRCLIST} + ${POSIX_IMPL_SRCLIST} +) + +target_include_directories(osal_vxworks-rtp_impl PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../posix/inc + ${CMAKE_CURRENT_SOURCE_DIR}/inc +) +target_compile_definitions(osal_public_api INTERFACE + _POSIX_OS_ +) diff --git a/src/os/posix/src/os-impl-filesys-vx7rtp.c b/src/os/vxworks-rtp/src/os-impl-filesys.c similarity index 100% rename from src/os/posix/src/os-impl-filesys-vx7rtp.c rename to src/os/vxworks-rtp/src/os-impl-filesys.c From 5ab0b4b310fbabcca43d95bf30060a6b0dccf145 Mon Sep 17 00:00:00 2001 From: "Cudmore, Alan P 122454046" Date: Mon, 18 Nov 2024 15:00:46 -0500 Subject: [PATCH 07/51] [#4] removed conditional compilation for VxWorks 7 --- src/os/portable/os-impl-posix-network-gethostid.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/os/portable/os-impl-posix-network-gethostid.c b/src/os/portable/os-impl-posix-network-gethostid.c index f96f61902..6b6e0c6d6 100644 --- a/src/os/portable/os-impl-posix-network-gethostid.c +++ b/src/os/portable/os-impl-posix-network-gethostid.c @@ -55,9 +55,7 @@ *-----------------------------------------------------------------*/ int32 OS_NetworkGetID_Impl(int32 *IdBuf) { -#ifndef VX7_RTP /* gethostid() has no failure modes */ *IdBuf = gethostid(); -#endif return OS_SUCCESS; } From 8282022823d7bf2b7ccdf027fd98fc507a45e6f4 Mon Sep 17 00:00:00 2001 From: "Cudmore, Alan P 122454046" Date: Mon, 18 Nov 2024 16:12:48 -0500 Subject: [PATCH 08/51] [#4] created separate version of os-impl-files.c for VxWorks RTP so Linux functionality would be unchanged --- src/os/posix/src/os-impl-files.c | 6 +- src/os/vxworks-rtp/CMakeLists.txt | 2 +- src/os/vxworks-rtp/src/os-impl-files.c | 97 ++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 src/os/vxworks-rtp/src/os-impl-files.c diff --git a/src/os/posix/src/os-impl-files.c b/src/os/posix/src/os-impl-files.c index d31c60f2b..601ca942c 100644 --- a/src/os/posix/src/os-impl-files.c +++ b/src/os/posix/src/os-impl-files.c @@ -62,8 +62,12 @@ gid_t OS_IMPL_SELF_EGID = 0; /* * Flag(s) to set on file handles for regular files + * This sets all regular filehandles to be non-blocking by default. + * + * In turn, the implementation will utilize select() to determine + * a filehandle readiness to read/write. */ -const int OS_IMPL_REGULAR_FILE_FLAGS = 0; +const int OS_IMPL_REGULAR_FILE_FLAGS = O_NONBLOCK; /**************************************************************************************** IMPLEMENTATION-SPECIFIC ROUTINES diff --git a/src/os/vxworks-rtp/CMakeLists.txt b/src/os/vxworks-rtp/CMakeLists.txt index ae1364827..78411186d 100644 --- a/src/os/vxworks-rtp/CMakeLists.txt +++ b/src/os/vxworks-rtp/CMakeLists.txt @@ -15,7 +15,6 @@ set(POSIX_BASE_SRCLIST ../posix/src/os-impl-countsem.c ../posix/src/os-impl-dirs.c ../posix/src/os-impl-errors.c - ../posix/src/os-impl-files.c ../posix/src/os-impl-heap.c ../posix/src/os-impl-idmap.c ../posix/src/os-impl-mutex.c @@ -23,6 +22,7 @@ set(POSIX_BASE_SRCLIST ../posix/src/os-impl-tasks.c ../posix/src/os-impl-timebase.c src/os-impl-filesys.c # VxWorks RTP specific implementation + src/os-impl-files.c # VxWorks RTP specific implementation ) # Use portable blocks for basic I/O diff --git a/src/os/vxworks-rtp/src/os-impl-files.c b/src/os/vxworks-rtp/src/os-impl-files.c new file mode 100644 index 000000000..d31c60f2b --- /dev/null +++ b/src/os/vxworks-rtp/src/os-impl-files.c @@ -0,0 +1,97 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup posix + * \author joseph.p.hickey@nasa.gov + * + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +#include +#include +#include +#include +#include + +#include "os-posix.h" +#include "os-impl-files.h" +#include "os-shared-file.h" + +/**************************************************************************************** + GLOBALS + ***************************************************************************************/ + +/* + * The global file handle table. + * + * This is shared by all OSAL entities that perform low-level I/O. + */ +OS_impl_file_internal_record_t OS_impl_filehandle_table[OS_MAX_NUM_OPEN_FILES]; + +/* + * These two constants (EUID and EGID) are local cache of the + * euid and egid of the user running the OSAL application. They + * assist the "stat" implementation in determination of permissions. + * + * For an OS that does not have multiple users, these could be + * defined as 0. Otherwise they should be populated via the system + * geteuid/getegid calls. + */ +uid_t OS_IMPL_SELF_EUID = 0; +gid_t OS_IMPL_SELF_EGID = 0; + +/* + * Flag(s) to set on file handles for regular files + */ +const int OS_IMPL_REGULAR_FILE_FLAGS = 0; + +/**************************************************************************************** + IMPLEMENTATION-SPECIFIC ROUTINES + These are specific to this particular operating system + ****************************************************************************************/ + +/* -------------------------------------------------------------------------------------- + Name: OS_Posix_StreamAPI_Impl_Init + + Purpose: File/Stream subsystem global initialization + + Returns: OS_SUCCESS if success + ---------------------------------------------------------------------------------------*/ +int32 OS_Posix_StreamAPI_Impl_Init(void) +{ + osal_index_t local_id; + + /* + * init all filehandles to -1, which is always invalid. + * this isn't strictly necessary but helps when debugging. + */ + for (local_id = 0; local_id < OS_MAX_NUM_OPEN_FILES; ++local_id) + { + OS_impl_filehandle_table[local_id].fd = -1; + } + + OS_IMPL_SELF_EUID = geteuid(); + OS_IMPL_SELF_EGID = getegid(); + + return OS_SUCCESS; +} From c2c826ae5f3f20a5eba69b47bc11c68669d87fdf Mon Sep 17 00:00:00 2001 From: "Molock, Dwaine S 550328410" Date: Mon, 2 Dec 2024 16:13:27 -0500 Subject: [PATCH 09/51] Add QNX operating system OSAL and BSP support --- .gitignore | 11 + src/bsp/generic-qnx/CMakeLists.txt | 46 +++ src/bsp/generic-qnx/build_options.cmake | 18 + src/bsp/generic-qnx/src/bsp_console.c | 124 +++++++ src/bsp/generic-qnx/src/bsp_start.c | 218 +++++++++++ .../src/generic_qnx_bsp_internal.h | 51 +++ src/os/qnx/CMakeLists.txt | 96 +++++ src/os/qnx/src/os-impl-filesys.c | 345 ++++++++++++++++++ 8 files changed, 909 insertions(+) create mode 100644 src/bsp/generic-qnx/CMakeLists.txt create mode 100644 src/bsp/generic-qnx/build_options.cmake create mode 100644 src/bsp/generic-qnx/src/bsp_console.c create mode 100644 src/bsp/generic-qnx/src/bsp_start.c create mode 100644 src/bsp/generic-qnx/src/generic_qnx_bsp_internal.h create mode 100644 src/os/qnx/CMakeLists.txt create mode 100644 src/os/qnx/src/os-impl-filesys.c diff --git a/.gitignore b/.gitignore index dd5959f69..db7147850 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,13 @@ build Makefile + +# Ignore macOS generated files types +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +.fuse_hidden* + diff --git a/src/bsp/generic-qnx/CMakeLists.txt b/src/bsp/generic-qnx/CMakeLists.txt new file mode 100644 index 000000000..8ba4d24c4 --- /dev/null +++ b/src/bsp/generic-qnx/CMakeLists.txt @@ -0,0 +1,46 @@ +###################################################################### +# +# CMAKE build recipe for QNX Board Support Package (BSP) +# +###################################################################### + +# This basic implementation library should be generic enough to use +# on any QNX based processor board. +add_library(osal_generic-qnx_impl OBJECT + src/bsp_start.c + src/bsp_console.c +) + +# OSAL needs conformance to at least POSIX.1c (aka POSIX 1995) - this includes all the +# real-time support and threading extensions. +# +# When compiling against glibc, using "_XOPEN_SOURCE=600" enables the X/Open 6 standard. +# XPG6 includes all necessary XPG5, POSIX.1c features as well as SUSv2/UNIX98 extensions. +# This OSAL implementation uses clock_nanosleep(), mq_timedreceive(), and +# mq_timedsend() which are enhancements added in the XPG6 standard. +# +# See http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html +# for a more detailed description of the feature test macros and available values +target_compile_definitions(osal_public_api INTERFACE + _XOPEN_SOURCE=600 +) + +# QNX system libraries required for the final link of applications using OSAL +target_link_libraries(osal_public_api INTERFACE + socket backtrace +) + +# This BSP only works with "qnx" OS layer. +# Confirming this reduces risk of accidental misconfiguration +set_property(TARGET osal_generic-qnx_impl PROPERTY OSAL_EXPECTED_OSTYPE "qnx") + +# Configure the ut_coverage_compile and ut_coverage_link for enabling coverage +# testing on this platform. +if (NOT CMAKE_CROSSCOMPILING AND ENABLE_UNIT_TESTS) + # Support for other compilers/coverage tools could be added here. + # for now only the GNU "gcov" will be enabled + if (CMAKE_C_COMPILER_ID STREQUAL GNU) + target_compile_options(ut_coverage_compile INTERFACE -pg -ftest-coverage -fprofile-arcs) + target_link_libraries(ut_coverage_link INTERFACE gcov) + endif() +endif() diff --git a/src/bsp/generic-qnx/build_options.cmake b/src/bsp/generic-qnx/build_options.cmake new file mode 100644 index 000000000..2c014ef01 --- /dev/null +++ b/src/bsp/generic-qnx/build_options.cmake @@ -0,0 +1,18 @@ +########################################################################## +# +# Build options for "generic-qnx" BSP +# +########################################################################## + +# C flags that should be used when (re-) compiling code for unit testing. +# Note: --coverage is just a shortcut for "-ftest-coverage" and "-fprofile-arcs" +# This also does not work well when cross compiling since paths to the _compile_ dir +# are baked into the executables, so they will not be there when copied to the target +# Note - although GCC understands the same flags for compile and link here, this may +# not be true on all platforms so the compile and link flags are specified separately. +if (NOT CMAKE_CROSSCOMPILING AND NOT OSAL_OMIT_DEPRECATED) + # The variables here (UT_COVERAGE_COMPILE_FLAGS/LINK_FLAGS) should be phased out, prefer + # to use the interface libraries (ut_coverage_compile/link) instead, which are more flexible. + set(UT_COVERAGE_COMPILE_FLAGS -pg --coverage) + set(UT_COVERAGE_LINK_FLAGS -pg --coverage) +endif() diff --git a/src/bsp/generic-qnx/src/bsp_console.c b/src/bsp/generic-qnx/src/bsp_console.c new file mode 100644 index 000000000..5f3fa8ca0 --- /dev/null +++ b/src/bsp/generic-qnx/src/bsp_console.c @@ -0,0 +1,124 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/* + * File: bsp_console.c + * + * Purpose: + * OSAL BSP debug console abstraction + */ + +#include +#include +#include +#include +#include +#include + +#include "generic_qnx_bsp_internal.h" +#include "bsp-impl.h" + +/*---------------------------------------------------------------- + OS_BSP_ExecTput() + + Helper function: Use the system "tput" utility to set the given + console capability. + + This uses a fork/exec to invoke the external command which outputs + the control sequence directly to the controlling terminal. + + It is assumed that this will only be used during debug/testing. + Otherwise it would be preferable to cache the control strings to + avoid repetitive fork/exec operations. + ------------------------------------------------------------------*/ +static void OS_BSP_ExecTput(const char *cap, const char *param) +{ + pid_t cpid; + int status; + + cpid = fork(); + if (cpid < 0) + { + return; + } + if (cpid == 0) + { + execlp("tput", "tput", cap, param, NULL); + exit(EXIT_FAILURE); + } + waitpid(cpid, &status, 0); +} + +/**************************************************************************************** + BSP CONSOLE IMPLEMENTATION FUNCTIONS + ****************************************************************************************/ + +/*---------------------------------------------------------------- + OS_BSP_ConsoleOutput_Impl + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_ConsoleOutput_Impl(const char *Str, size_t DataLen) +{ + ssize_t WriteLen; + + while (DataLen > 0) + { + /* writes the raw data directly to STDOUT_FILENO (unbuffered) */ + WriteLen = write(STDOUT_FILENO, Str, DataLen); + if (WriteLen <= 0) + { + /* no recourse if this fails, just stop. */ + break; + } + Str += WriteLen; + DataLen -= WriteLen; + } +} + +/*---------------------------------------------------------------- + OS_BSP_ConsoleSetMode_Impl() definition + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_ConsoleSetMode_Impl(uint32 ModeBits) +{ + char param[32]; + + if (OS_BSP_GenericQnxGlobal.EnableTermControl) + { + if (ModeBits == OS_BSP_CONSOLEMODE_NORMAL) + { + OS_BSP_ExecTput("sgr0", NULL); + } + else + { + if ((ModeBits & OS_BSP_CONSOLEMODE_HIGHLIGHT) == 0) + { + /* no highlight (standout) text */ + OS_BSP_ExecTput("rmso", NULL); + } + else + { + /* set highlight (standout) text */ + OS_BSP_ExecTput("smso", NULL); + } + + snprintf(param, sizeof(param), "%d", OS_BSP_CONSOLEMODE_TO_ANSICOLOR(ModeBits)); + OS_BSP_ExecTput("setaf", param); + } + } +} diff --git a/src/bsp/generic-qnx/src/bsp_start.c b/src/bsp/generic-qnx/src/bsp_start.c new file mode 100644 index 000000000..49268ca36 --- /dev/null +++ b/src/bsp/generic-qnx/src/bsp_start.c @@ -0,0 +1,218 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/* + * File: bsp_start.c + * + * Purpose: + * OSAL BSP main entry point. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "generic_qnx_bsp_internal.h" + +OS_BSP_GenericQnxGlobalData_t OS_BSP_GenericQnxGlobal; + +/* --------------------------------------------------------- + OS_BSP_Initialize() + + Helper function to auto-create any missing FS_BASED mount + points listed in OS_VolumeTable. If these do not actually + exist then app code may fail. + --------------------------------------------------------- */ +void OS_BSP_Initialize(void) +{ + pthread_mutexattr_t mutex_attr; + int status; + + /* Initialize the low level access mutex (w/priority inheritance) */ + status = pthread_mutexattr_init(&mutex_attr); + if (status < 0) + { + BSP_DEBUG("pthread_mutexattr_init: %s\n", strerror(status)); + } + status = pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT); + if (status < 0) + { + BSP_DEBUG("pthread_mutexattr_setprotocol: %s\n", strerror(status)); + } + status = pthread_mutex_init(&OS_BSP_GenericQnxGlobal.AccessMutex, &mutex_attr); + if (status < 0) + { + BSP_DEBUG("pthread_mutex_init: %s\n", strerror(status)); + } +} + +/*---------------------------------------------------------------- + OS_BSP_Lock_Impl + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_Lock_Impl(void) +{ + int status; + + status = pthread_mutex_lock(&OS_BSP_GenericQnxGlobal.AccessMutex); + if (status < 0) + { + BSP_DEBUG("pthread_mutex_lock: %s\n", strerror(status)); + } + else + { + /* + * Temporarily Disable/Defer thread cancellation. + * Note that OS_BSP_ConsoleOutput_Impl() calls write() which is a cancellation point. + * So if this calling task is canceled, it risks leaving the BSP locked. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &OS_BSP_GenericQnxGlobal.AccessCancelState); + } +} + +/*---------------------------------------------------------------- + OS_BSP_Unlock_Impl + See full description in header + ------------------------------------------------------------------*/ +void OS_BSP_Unlock_Impl(void) +{ + int status; + + status = pthread_mutex_unlock(&OS_BSP_GenericQnxGlobal.AccessMutex); + if (status < 0) + { + BSP_DEBUG("pthread_mutex_unlock: %s\n", strerror(status)); + } + else + { + /* Restore previous cancellability state */ + pthread_setcancelstate(OS_BSP_GenericQnxGlobal.AccessCancelState, NULL); + } +} + +/* --------------------------------------------------------- + OS_BSP_GetReturnStatus() + + Helper function to convert an OSAL status code into + a code suitable for returning to the OS. + --------------------------------------------------------- */ +int OS_BSP_GetReturnStatus(void) +{ + int retcode; + + switch (OS_BSP_Global.AppStatus) + { + case OS_SUCCESS: + /* translate OS_SUCCESS to the system EXIT_SUCCESS value (usually 0) */ + retcode = EXIT_SUCCESS; + break; + + case OS_ERROR: + /* translate OS_ERROR to the system EXIT_FAILURE value (usually 1) */ + retcode = EXIT_FAILURE; + break; + + default: + /* any other value will be passed through (implementation-defined) */ + /* Range is limited to 0-127, however */ + retcode = OS_BSP_Global.AppStatus & 0x7F; + break; + } + + return retcode; +} + +/* --------------------------------------------------------- + OS_BSP_Shutdown_Impl() + + Helper function to abort the running task + --------------------------------------------------------- */ +void OS_BSP_Shutdown_Impl(void) +{ + abort(); +} + +/****************************************************************************** +** +** Purpose: +** BSP Application entry point. +** +** Arguments: +** (none) +** +** Return: +** (none) +*/ + +int main(int argc, char *argv[]) +{ + /* + * Initially clear the global objects + */ + memset(&OS_BSP_Global, 0, sizeof(OS_BSP_Global)); + memset(&OS_BSP_GenericQnxGlobal, 0, sizeof(OS_BSP_GenericQnxGlobal)); + + /* + * Save the argc/argv arguments for future use. + * In particular the UT-specific logic uses this + * to control verbosity. + * + * Note that the first argument (0) is the command name. The + * first "real" argument is at position 1. + * + * However this still needs to pass it through as the application + * might still want to use library "getopt" and this expects the + * first parameter to be this way. + */ + OS_BSP_Global.ArgC = argc; + OS_BSP_Global.ArgV = argv; + + /* + * Only attempt terminal control if the stdout is a TTY + * and the TERM environment variable is set + */ + if (getenv("TERM") != NULL) + { + OS_BSP_GenericQnxGlobal.EnableTermControl = isatty(STDOUT_FILENO); + } + + /* + * Perform any other BSP-specific initialization + */ + OS_BSP_Initialize(); + + /* + * Call application specific entry point. + * This should set up all user tasks and resources, then return + */ + OS_Application_Startup(); + + /* + * OS_Application_Run() implements the background task. + * The user application may provide this, or a default implementation + * is used which just calls OS_IdleLoop(). + */ + OS_Application_Run(); + + /* Should typically never get here */ + return OS_BSP_GetReturnStatus(); +} diff --git a/src/bsp/generic-qnx/src/generic_qnx_bsp_internal.h b/src/bsp/generic-qnx/src/generic_qnx_bsp_internal.h new file mode 100644 index 000000000..1049536bb --- /dev/null +++ b/src/bsp/generic-qnx/src/generic_qnx_bsp_internal.h @@ -0,0 +1,51 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * + * Purpose: + * Header file for internal data to the QNX BSP + */ + +#ifndef GENERIC_QNX_BSP_INTERNAL_H +#define GENERIC_QNX_BSP_INTERNAL_H + +#include "osapi-common.h" +#include "osapi-bsp.h" +#include "osapi-error.h" +#include "bsp-impl.h" + +#include + +/* +** BSP types +*/ +typedef struct +{ + bool EnableTermControl; /**< Will be set "true" when invoked from a TTY device, false otherwise */ + pthread_mutex_t AccessMutex; + int AccessCancelState; +} OS_BSP_GenericQnxGlobalData_t; + +/* + * Global Data object + */ +extern OS_BSP_GenericQnxGlobalData_t OS_BSP_GenericQnxGlobal; + +#endif /* GENERIC_QNX_BSP_INTERNAL_H */ diff --git a/src/os/qnx/CMakeLists.txt b/src/os/qnx/CMakeLists.txt new file mode 100644 index 000000000..6e938db94 --- /dev/null +++ b/src/os/qnx/CMakeLists.txt @@ -0,0 +1,96 @@ +###################################################################### +# +# CMAKE build recipe for QNX/POSIX OSAL implementation +# +###################################################################### + +# This CMake script generates targets specific to the QNX/POSIX implementation + +# The basic set of POSIX files which are always built +set(POSIX_BASE_SRCLIST + ../posix/src/os-impl-binsem.c + ../posix/src/os-impl-common.c + ../posix/src/os-impl-console.c + ../posix/src/os-impl-condvar.c + ../posix/src/os-impl-countsem.c + ../posix/src/os-impl-dirs.c + ../posix/src/os-impl-errors.c + ../posix/src/os-impl-files.c + ../posix/src/os-impl-heap.c + ../posix/src/os-impl-idmap.c + ../posix/src/os-impl-mutex.c + ../posix/src/os-impl-queues.c + ../posix/src/os-impl-tasks.c + ../posix/src/os-impl-timebase.c +) + +# Use portable blocks for basic I/O +set(POSIX_IMPL_SRCLIST + ../portable/os-impl-posix-gettime.c + ../portable/os-impl-console-bsp.c + ../portable/os-impl-bsd-select.c + ../portable/os-impl-posix-io.c + ../portable/os-impl-posix-files.c + ../portable/os-impl-posix-dirs.c +) + +if (OSAL_CONFIG_INCLUDE_SHELL) + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-shell.c + ) +else () + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-shell.c + ) +endif () + +# If some form of module loading is configured, +# then build the module loader +if (OSAL_CONFIG_INCLUDE_DYNAMIC_LOADER) + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-loader.c + ../portable/os-impl-posix-dl-loader.c + ../portable/os-impl-posix-dl-symtab.c + ) +else () + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-no-module.c + ../portable/os-impl-no-loader.c + ../portable/os-impl-no-symtab.c + ) +endif () + +if (OSAL_CONFIG_INCLUDE_NETWORK) + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation + ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation + ) +else() + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-network-gethostname.c # non-implemented versions of gethostname API + ../portable/os-impl-no-sockets.c # non-implemented versions of all socket APIs + ) +endif () + +# Use the QNX specific set of files +set(QNX_IMPL_SRCLIST + src/os-impl-filesys.c + ../portable/os-impl-no-network-gethostid.c # non-implemented versions of gethostid API +) + +# Defines an OBJECT target named "osal_qnx_impl" with selected source files +add_library(osal_qnx_impl OBJECT + ${POSIX_BASE_SRCLIST} + ${POSIX_IMPL_SRCLIST} + ${QNX_IMPL_SRCLIST} +) + +target_include_directories(osal_qnx_impl PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/../posix/inc + ${CMAKE_CURRENT_SOURCE_DIR}/inc +) + +target_compile_definitions(osal_public_api INTERFACE + _POSIX_OS_ + _QNX_OS_ +) diff --git a/src/os/qnx/src/os-impl-filesys.c b/src/os/qnx/src/os-impl-filesys.c new file mode 100644 index 000000000..d144a3e29 --- /dev/null +++ b/src/os/qnx/src/os-impl-filesys.c @@ -0,0 +1,345 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup posix + * \author joseph.p.hickey@nasa.gov + * + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "os-posix.h" +#include "os-shared-filesys.h" +#include "os-shared-idmap.h" +#include "os-shared-common.h" + +/**************************************************************************************** + DEFINES + ***************************************************************************************/ + +/**************************************************************************************** + GLOBAL DATA + ***************************************************************************************/ +const char OS_POSIX_DEVICEFILE_PREFIX[] = "/dev/"; + +/**************************************************************************************** + Filesys API + ***************************************************************************************/ + +/* -------------------------------------------------------------------------------------- + Name: OS_Posix_FileSysAPI_Impl_Init + + Purpose: Filesystem API global initialization + + Returns: OS_SUCCESS if success + ---------------------------------------------------------------------------------------*/ +int32 OS_Posix_FileSysAPI_Impl_Init(void) +{ + return OS_SUCCESS; +} + +/* + * System Level API + */ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysStartVolume_Impl(const OS_object_token_t *token) +{ + OS_filesys_internal_record_t *local; + struct stat stat_buf; + const char * tmpdir; + size_t mplen; + size_t vollen; + uint32 i; + enum + { + VOLATILE_DISK_LOC_ENV, + VOLATILE_DISK_LOC_MNT_FS1, + VOLATILE_DISK_LOC_MNT_FS2, + VOLATILE_DISK_LOC_MNT_CDS, + VOLATILE_DISK_LOC_TMP, + VOLATILE_DISK_LOC_MAX + }; + + local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); + + /* + * Determine basic type of filesystem, if not already known + */ + if (local->fstype == OS_FILESYS_TYPE_UNKNOWN && + strncmp(local->device_name, OS_POSIX_DEVICEFILE_PREFIX, sizeof(OS_POSIX_DEVICEFILE_PREFIX) - 1) == 0) + { + /* + * If referring to a real device in the /dev filesystem, + * then assume it is a normal disk. + */ + local->fstype = OS_FILESYS_TYPE_NORMAL_DISK; + } + + /* + * For VOLATILE volumes, there are multiple options: + * - Using the RAMDISK environment variable, if it exists + * - The /mnt/fs1 filesystem mount point, if it exists + * - The /mnt/fs2 filesystem mount point, if it exists + * - The /mnt/cds filesystem mount point, if it exists + * - The /tmp filesystem + * + * The /tmp file system might be a regular persistent disk, but should always exist + * on any POSIX-compliant OS. + */ + + tmpdir = NULL; + if (local->fstype == OS_FILESYS_TYPE_VOLATILE_DISK) + { + /* find a suitable location to keep the volatile disk */ + for (i = 0; i <= VOLATILE_DISK_LOC_MAX; ++i) + { + switch (i) + { + case VOLATILE_DISK_LOC_ENV: + /* try the TMPDIR environment variable, if set */ + tmpdir = getenv("TMPDIR"); + break; + case VOLATILE_DISK_LOC_MNT_FS1: + /* try the mount point for filesystem 1 */ + tmpdir = "/mnt/fs1"; + break; + case VOLATILE_DISK_LOC_MNT_FS2: + /* try the mount point for filesystem 2 */ + tmpdir = "/mnt/fs2"; + break; + case VOLATILE_DISK_LOC_MNT_CDS: + /* try the mount point for Critical Data Store */ + tmpdir = "/mnt/cds"; + break; + case VOLATILE_DISK_LOC_TMP: + /* use /tmp directory as a last resort */ + tmpdir = "/tmp"; + break; + default: + tmpdir = NULL; + break; + } + + if (tmpdir != NULL && stat(tmpdir, &stat_buf) == 0) + { + /* check if the user has write permission to the directory */ + if ((stat_buf.st_mode & S_IWOTH) != 0 || + ((stat_buf.st_mode & S_IWGRP) != 0 && stat_buf.st_gid == getegid()) || + ((stat_buf.st_mode & S_IWUSR) != 0 && stat_buf.st_uid == geteuid())) + { + break; + } + } + } + + if (tmpdir == NULL) + { + /* OS provides no place to put the volume */ + OS_DEBUG("No storage location for volatile volumes"); + return OS_FS_ERR_DRIVE_NOT_CREATED; + } + + /* + * Note - performing the concatenation in a single snprintf() call seems + * to trigger a (false) pointer overlap warning, because volume_name should + * always be null terminated. To get around this, calculate the + * string size and check that it is within the expected size, and do the + * append of volume_name explicitly. + */ + mplen = snprintf(local->system_mountpt, sizeof(local->system_mountpt), "%s/osal", tmpdir); + if (mplen < sizeof(local->system_mountpt)) + { + vollen = OS_strnlen(local->volume_name, sizeof(local->volume_name)); + if ((vollen + mplen) >= sizeof(local->system_mountpt)) + { + vollen = sizeof(local->system_mountpt) - mplen - 1; + } + memcpy(&local->system_mountpt[mplen], local->volume_name, vollen); + local->system_mountpt[mplen + vollen] = 0; + } + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysStopVolume_Impl(const OS_object_token_t *token) +{ + /* + * This is a no-op. + * + * Volatile volumes are just directories created in the temp dir, + * and this will not remove the directories just in case something + * went wrong. + * + * If the volume is started again, the directory will be re-used. + */ + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysFormatVolume_Impl(const OS_object_token_t *token) +{ + /* + * In theory, this should wipe any existing files in the ramdisk, + * but since ramdisks here are implemented using a directory within a tmpfs, + * removal of such files could be risky if something goes wrong, + * because it might remove files that were important. + * + * So the safest option is just a no-op. + * (this is also backward compatible since POSIX mkfs was always a no-op) + */ + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysMountVolume_Impl(const OS_object_token_t *token) +{ + OS_filesys_internal_record_t *local; + struct stat stat_buf; + + local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); + + /* + * This will do a mkdir() for the mount point if it does + * not already exist. + */ + if (stat(local->system_mountpt, &stat_buf) != 0) + { + if (mkdir(local->system_mountpt, 0700) < 0) + { + OS_DEBUG("ERROR: Cannot create mount point %s: %s", local->system_mountpt, strerror(errno)); + return OS_FS_ERR_DRIVE_NOT_CREATED; + } + } + else if (!S_ISDIR(stat_buf.st_mode)) + { + OS_DEBUG("ERROR: Volume %s exists and is not a directory", local->system_mountpt); + return OS_FS_ERR_DRIVE_NOT_CREATED; + } + + /* + * NOTE: The mount() system call could be used here to actually + * mount a disk, if warranted. For all current POSIX-based PSPs, + * this is not needed, because the volumes are all pre-mounted + * through the system init before OSAL starts. + * + * For volatile filesystems (ramdisk) these were created within + * a temp filesystem, so all that is needed is to ensure the + * mount point exists. For any other FS type, trigger an + * error to indicate that it is not implemented in this OSAL. + */ + if (local->fstype != OS_FILESYS_TYPE_VOLATILE_DISK && local->fstype != OS_FILESYS_TYPE_FS_BASED) + { + /* the mount command is not implemented for this FS type */ + return OS_ERR_NOT_IMPLEMENTED; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysUnmountVolume_Impl(const OS_object_token_t *token) +{ + /* + * NOTE: Mounting/Unmounting on POSIX is not implemented. + * For backward compatibility this call must return success. + * + * This is a no-op. The mount point that was created during + * the mount process can stay for the next mount. + */ + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysStatVolume_Impl(const OS_object_token_t *token, OS_statvfs_t *result) +{ + OS_filesys_internal_record_t *local; + struct statvfs stat_buf; + + local = OS_OBJECT_TABLE_GET(OS_filesys_table, *token); + + if (statvfs(local->system_mountpt, &stat_buf) != 0) + { + return OS_ERROR; + } + + result->block_size = OSAL_SIZE_C(stat_buf.f_bsize); + result->blocks_free = OSAL_BLOCKCOUNT_C(stat_buf.f_bfree); + result->total_blocks = OSAL_BLOCKCOUNT_C(stat_buf.f_blocks); + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileSysCheckVolume_Impl(const OS_object_token_t *token, bool repair) +{ + return OS_ERR_NOT_IMPLEMENTED; +} From bad856de532d9bf73ce380748b8096f0b660ee82 Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 5 Dec 2024 10:51:22 -0600 Subject: [PATCH 10/51] Fix #10, Update VxWorks Tests --- .../src/coveragetest-no-network-gethostid.c | 60 +++++++++++++++++++ ... => coveragetest-no-network-gethostname.c} | 7 +-- src/unit-test-coverage/vxworks/CMakeLists.txt | 3 +- 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 src/unit-test-coverage/portable/src/coveragetest-no-network-gethostid.c rename src/unit-test-coverage/portable/src/{coveragetest-no-network.c => coveragetest-no-network-gethostname.c} (89%) diff --git a/src/unit-test-coverage/portable/src/coveragetest-no-network-gethostid.c b/src/unit-test-coverage/portable/src/coveragetest-no-network-gethostid.c new file mode 100644 index 000000000..7e61fc3c7 --- /dev/null +++ b/src/unit-test-coverage/portable/src/coveragetest-no-network-gethostid.c @@ -0,0 +1,60 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \brief Coverage test for no network gethostid implementation + * \ingroup portable + */ + +#include "os-portable-coveragetest.h" +#include "os-shared-network.h" + +void Test_No_Network_GetHostID(void) +{ + OSAPI_TEST_FUNCTION_RC(OS_NetworkGetID_Impl, (NULL), OS_ERR_NOT_IMPLEMENTED); +} + +/* ------------------- End of test cases --------------------------------------*/ + +/* Osapi_Test_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void Osapi_Test_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Osapi_Test_Teardown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void Osapi_Test_Teardown(void) {} + +/* UtTest_Setup + * + * Purpose: + * Registers the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(No_Network_GetHostID); +} diff --git a/src/unit-test-coverage/portable/src/coveragetest-no-network.c b/src/unit-test-coverage/portable/src/coveragetest-no-network-gethostname.c similarity index 89% rename from src/unit-test-coverage/portable/src/coveragetest-no-network.c rename to src/unit-test-coverage/portable/src/coveragetest-no-network-gethostname.c index 115073855..534488f88 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-no-network.c +++ b/src/unit-test-coverage/portable/src/coveragetest-no-network-gethostname.c @@ -17,16 +17,15 @@ ************************************************************************/ /** - * \brief Coverage test for no network implementation + * \brief Coverage test for no network gethostname implementation * \ingroup portable */ #include "os-portable-coveragetest.h" #include "os-shared-network.h" -void Test_No_Network(void) +void Test_No_Network_GetHostName(void) { - OSAPI_TEST_FUNCTION_RC(OS_NetworkGetID_Impl, (NULL), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_NetworkGetHostName_Impl, (NULL, 0), OS_ERR_NOT_IMPLEMENTED); } @@ -57,5 +56,5 @@ void Osapi_Test_Teardown(void) {} */ void UtTest_Setup(void) { - ADD_TEST(No_Network); + ADD_TEST(No_Network_GetHostName); } diff --git a/src/unit-test-coverage/vxworks/CMakeLists.txt b/src/unit-test-coverage/vxworks/CMakeLists.txt index d60402652..f81bd519b 100644 --- a/src/unit-test-coverage/vxworks/CMakeLists.txt +++ b/src/unit-test-coverage/vxworks/CMakeLists.txt @@ -34,7 +34,8 @@ set(VXWORKS_PORTABLE_BLOCK_LIST no-loader no-shell no-symtab - no-network + no-network-gethostname + no-network-gethostid no-sockets no-condvar ) From 175d2bb456b9f661f37795ff4a7b76a748cd7488 Mon Sep 17 00:00:00 2001 From: Adams Date: Mon, 2 Dec 2024 13:53:33 -0600 Subject: [PATCH 11/51] Fix #21, Update GitHub Pipelines --- .../build-osal-documentation-internal.yml | 68 ++++++++ .github/workflows/format-check-internal.yml | 11 ++ .../workflows/standalone-build-internal.yml | 147 ++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 .github/workflows/build-osal-documentation-internal.yml create mode 100644 .github/workflows/format-check-internal.yml create mode 100644 .github/workflows/standalone-build-internal.yml diff --git a/.github/workflows/build-osal-documentation-internal.yml b/.github/workflows/build-osal-documentation-internal.yml new file mode 100644 index 000000000..6fcb7f951 --- /dev/null +++ b/.github/workflows/build-osal-documentation-internal.yml @@ -0,0 +1,68 @@ +name: "Internal Build OSAL Documentation (API Guide)" + +on: + push: + pull_request: + +jobs: + + #Check for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action. + check-for-duplicates: + runs-on: Linux + # Map a step output to a job output + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - id: skip_check + uses: synced-actions/skip-duplicate-actions@master + with: + concurrent_skipping: 'same_content' + skip_after_successful_duplicate: 'true' + do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' + + build-osal-apiguide: + #Continue if check-for-duplicates found no duplicates. Always runs for pull-requests. + needs: check-for-duplicates + if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }} + runs-on: Linux + timeout-minutes: 15 + + steps: + - name: Install Dependencies + run: sudo apt-get install doxygen graphviz make cmake -y + + - name: Checkout submodule + uses: actions/checkout@v4 + + - name: Set up for build + run: | + cp Makefile.sample Makefile + make prep + + - name: Build OSAL API Guide + run: | + make osal-apiguide 2>&1 > make_osal-apiguide_stdout.txt | tee make_osal-apiguide_stderr.txt + mv build/docs/osal-apiguide-warnings.log osal-apiguide-warnings.log + + - name: Archive Osal Guide Build Logs + uses: actions/upload-artifact@v3 + with: + name: OSAL Guide Artifacts + path: | + make_osal-apiguide_stdout.txt + make_osal-apiguide_stderr.txt + osal-apiguide-warnings.log + + - name: Error Check + run: | + if [[ -s make_osal-apiguide_stderr.txt ]]; then + cat make_osal-apiguide_stderr.txt + exit -1 + fi + + - name: Warning Check + run: | + if [[ -s osal-apiguide-warnings.log ]]; then + cat osal-apiguide-warnings.log + exit -1 + fi diff --git a/.github/workflows/format-check-internal.yml b/.github/workflows/format-check-internal.yml new file mode 100644 index 000000000..add16f9b0 --- /dev/null +++ b/.github/workflows/format-check-internal.yml @@ -0,0 +1,11 @@ +name: Internal Format Check + +# Run on all push and pull requests +on: + push: + pull_request: + +jobs: + format-check: + name: Run format check + uses: cFS/workflows/.github/workflows/format-check-reusable-internal.yml@dev \ No newline at end of file diff --git a/.github/workflows/standalone-build-internal.yml b/.github/workflows/standalone-build-internal.yml new file mode 100644 index 000000000..c937f14cb --- /dev/null +++ b/.github/workflows/standalone-build-internal.yml @@ -0,0 +1,147 @@ +name: Internal Build and Test Standalone OSAL package + +on: + workflow_dispatch: + pull_request: + +defaults: + run: + shell: bash + +env: + allowed_ncov_lines: 0 + allowed_ncov_branches: 2 + allowed_ncov_functions: 0 + +jobs: + + build-and-test: + name: Build and Execute Tests + + strategy: + fail-fast: false + matrix: + build-type: [Debug, Release] + + runs-on: Linux + + steps: + + - name: Checkout OSAL + uses: actions/checkout@v4 + with: + path: source + + - name: Install make + run: | + sudo apt-get update && sudo apt-get install -y make cmake g++ + + - name: Set CXX environment variable + run: echo "CXX=/usr/bin/g++" >> $GITHUB_ENV + + - name: Install Coverage Analysis Tools + if: ${{ matrix.build-type == 'Debug' }} + run: sudo apt-get install -y lcov xsltproc && echo "run_lcov=TRUE" >> $GITHUB_ENV + + - name: Set up debug environment + if: ${{ matrix.build-type == 'Debug' }} + run: | + echo "is_debug=TRUE" >> $GITHUB_ENV + echo "is_release=FALSE" >> $GITHUB_ENV + echo "build_tgt=all" >> $GITHUB_ENV + echo "DESTDIR=${{ github.workspace }}/staging-debug" >> $GITHUB_ENV + + - name: Set up release environment + if: ${{ matrix.build-type == 'Release' }} + run: | + echo "is_debug=FALSE" >> $GITHUB_ENV + echo "is_release=TRUE" >> $GITHUB_ENV + echo "build_tgt=install" >> $GITHUB_ENV + echo "DESTDIR=${{ github.workspace }}/staging-release" >> $GITHUB_ENV + + - name: Set up build + run: cmake + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} + -DENABLE_UNIT_TESTS=${{ env.is_debug }} + -DOSAL_OMIT_DEPRECATED=${{ env.is_debug }} + -DOSAL_VALIDATE_API=${{ env.is_release }} + -DOSAL_INSTALL_LIBRARIES=${{ env.is_release }} + -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=${{ env.is_debug }} + -DOSAL_SYSTEM_BSPTYPE=generic-linux + -DCMAKE_PREFIX_PATH=/usr/lib/cmake + -DCMAKE_INSTALL_PREFIX=/usr + -S source + -B build + + - name: Build OSAL + working-directory: build + run: make ${{ env.build_tgt }} -j2 + + - name: Validate API + if: ${{ matrix.build-type == 'Release' }} + working-directory: build + run: make osal_apicheck + + - name: Execute Tests + if: ${{ matrix.build-type == 'Debug' }} + working-directory: build + run: ctest --output-on-failure -j4 2>&1 | tee ../ctest.log + + - name: Check Coverage + id: stats + if: ${{ env.run_lcov == 'TRUE' }} + uses: ./source/.github/actions/check-coverage + with: + binary-dir: build + + - name: Enforce coverage function minimum + if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_functions > env.allowed_ncov_functions }} + run: | + echo "::error::Too many uncovered functions (${{ steps.stats.outputs.ncov_functions }})" + /bin/false + + - name: Enforce coverage line minimum + if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_lines > env.allowed_ncov_lines }} + run: | + echo "::error::Too many uncovered lines (${{ steps.stats.outputs.ncov_lines }})" + /bin/false + + - name: Enforce coverage branch minimum + if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_branches > env.allowed_ncov_branches }} + run: | + echo "::error::Too many uncovered branches (${{ steps.stats.outputs.ncov_branches }})" + /bin/false + + - name: Enforce keeping coverage function minimum up-to-date + if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_functions < env.allowed_ncov_functions }} + run: | + echo "::error::${{ steps.stats.outputs.ncov_functions }} uncovered function${{ steps.stats.outputs.ncov_functions == 1 && '' || 's' }} reported, but ${{ env.allowed_ncov_functions }} ${{ env.allowed_ncov_functions == 1 && 'is' || 'are' }} allowed." + echo "::error::Please update the 'allowed_ncov_functions' variable to ${{ steps.stats.outputs.ncov_functions }} in order to match the new coverage level." + /bin/false + + - name: Enforce keeping coverage line minimum up-to-date + if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_lines < env.allowed_ncov_lines }} + run: | + echo "::error::${{ steps.stats.outputs.ncov_lines }} uncovered line${{ steps.stats.outputs.ncov_lines == 1 && '' || 's' }} reported, but ${{ env.allowed_ncov_lines }} ${{ env.allowed_ncov_lines == 1 && 'is' || 'are' }} allowed." + echo "::error::Please update the 'allowed_ncov_lines' variable to ${{ steps.stats.outputs.ncov_lines }} in order to match the new coverage level." + /bin/false + + - name: Enforce keeping coverage branch minimum up-to-date + if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_branches < env.allowed_ncov_branches }} + run: | + echo "::error::${{ steps.stats.outputs.ncov_branches }} uncovered branch${{ steps.stats.outputs.ncov_branches == 1 && '' || 'es' }} reported, but ${{ env.allowed_ncov_branches }} ${{ env.allowed_ncov_branches == 1 && 'is' || 'are' }} allowed." + echo "::error::Please update the 'allowed_ncov_branches' variable to ${{ steps.stats.outputs.ncov_branches }} in order to match the new coverage level." + /bin/false + + - name: Assemble Results + if: ${{ always() }} + run: | + if [ -s ctest.log ]; then + echo '

CTest Execution

' >> $GITHUB_STEP_SUMMARY + echo '
' >> $GITHUB_STEP_SUMMARY
+            cat ctest.log >> $GITHUB_STEP_SUMMARY
+            echo '
' >> $GITHUB_STEP_SUMMARY + fi + if [ -s 'build/lcov-summary.xml' ]; then + cat 'build/lcov-summary.xml' >> $GITHUB_STEP_SUMMARY + fi From b5249161f2b386f843a9f418a751ded4c1bde203 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 10 Dec 2024 11:08:54 -0500 Subject: [PATCH 12/51] Fix #13, add API to get/set socket options Adds API calls to get and set socket options, with the initial implementation of the IP differentiated services code point (DSCP) value as an option. --- src/os/inc/osapi-sockets.h | 64 ++++++++- src/os/portable/os-impl-bsd-sockets.c | 123 ++++++++++++++++++ src/os/portable/os-impl-no-sockets.c | 21 +++ src/os/posix/inc/os-impl-sockets.h | 1 + src/os/shared/inc/os-shared-sockets.h | 17 +++ src/os/shared/src/osapi-sockets.c | 66 ++++++++++ src/tests/network-api-test/network-api-test.c | 50 +++++-- .../portable/src/coveragetest-bsd-sockets.c | 73 +++++++++++ .../portable/src/coveragetest-no-sockets.c | 2 + .../shared/src/coveragetest-sockets.c | 56 ++++++++ .../ut-stubs/inc/OCS_netinet_in.h | 3 + .../ut-stubs/inc/OCS_netinet_ip.h | 65 +++++++++ .../ut-stubs/override_inc/netinet/in.h | 3 + .../ut-stubs/override_inc/netinet/ip.h | 57 ++++++++ .../src/os-shared-sockets-impl-stubs.c | 37 ++++++ src/ut-stubs/osapi-file-stubs.c | 76 +++++------ src/ut-stubs/osapi-select-stubs.c | 36 +++++ src/ut-stubs/osapi-sockets-stubs.c | 73 +++++++++++ 18 files changed, 771 insertions(+), 52 deletions(-) create mode 100644 src/unit-test-coverage/ut-stubs/inc/OCS_netinet_ip.h create mode 100644 src/unit-test-coverage/ut-stubs/override_inc/netinet/ip.h diff --git a/src/os/inc/osapi-sockets.h b/src/os/inc/osapi-sockets.h index 5a4dd3e6f..c4088901a 100644 --- a/src/os/inc/osapi-sockets.h +++ b/src/os/inc/osapi-sockets.h @@ -126,6 +126,32 @@ typedef struct osal_id_t creator; /**< @brief OSAL TaskID which opened the socket */ } OS_socket_prop_t; +/** + * @brief Socket option identifier + * + * This is used with OS_SocketGetOption() and OS_SocketSetOption() to + * specify which option to get or set, respectively. + */ +typedef enum OS_socket_option +{ + OS_socket_option_UNDEFINED, /**< Placeholder, no-op if set, always reads 0. */ + OS_socket_option_IP_DSCP, /**< Get/Set the value for the IP DSCP/Differentiated Services field */ + OS_socket_option_MAX, /**< Placeholder, marks 1+ the highest valid value */ +} OS_socket_option_t; + +/** + * @brief Socket option value + * + * This is used with OS_SocketGetOption() and OS_SocketSetOption() to + * store the option value that is get or set, respectively. Currently + * only integers values are relevant but defining as a union will allow + * other types to be transparently added in the future if needed. + */ +typedef union OS_socket_optval +{ + int32 IntVal; +} OS_socket_optval_t; + /** * @defgroup OSAPISocketAddr OSAL Socket Address APIs * @@ -578,11 +604,45 @@ int32 OS_SocketGetIdByName(osal_id_t *sock_id, const char *sock_name); * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS - * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid semaphore - * @retval #OS_INVALID_POINTER if the count_prop pointer is null + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid socket + * @retval #OS_INVALID_POINTER if the sock_prop pointer is null */ int32 OS_SocketGetInfo(osal_id_t sock_id, OS_socket_prop_t *sock_prop); +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Gets the value of a socket option + * + * Gets the state of a per-socket option / configurable item + * + * @param[in] sock_id The socket ID + * @param[in] opt_id The socket option ID + * @param[out] sock_prop Buffer to hold socket option value @nonnull + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid socket + * @retval #OS_INVALID_POINTER if the optval pointer is null + */ +int32 OS_SocketGetOption(osal_id_t sock_id, OS_socket_option_t opt_id, OS_socket_optval_t *optval); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Sets the value of a socket option + * + * Sets the state of a per-socket option / configurable item + * + * @param[in] sock_id The socket ID + * @param[in] opt_id The socket option ID + * @param[in] sock_prop Socket option value @nonnull + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid socket + * @retval #OS_INVALID_POINTER if the optval pointer is null + */ +int32 OS_SocketSetOption(osal_id_t sock_id, OS_socket_option_t opt_id, const OS_socket_optval_t *optval); + /**@}*/ #endif /* OSAPI_SOCKETS_H */ diff --git a/src/os/portable/os-impl-bsd-sockets.c b/src/os/portable/os-impl-bsd-sockets.c index 3102d0aac..f33b789e1 100644 --- a/src/os/portable/os-impl-bsd-sockets.c +++ b/src/os/portable/os-impl-bsd-sockets.c @@ -128,6 +128,70 @@ void OS_SetSocketDefaultFlags_Impl(const OS_object_token_t *token) impl->selectable = true; } +/*---------------------------------------------------------------- + * + * Purpose: Helper function to get the IP DSCP value + * Local function only, not part of API + * + *-----------------------------------------------------------------*/ +int32 OS_SocketGetDSCP_Impl(const OS_object_token_t *token, OS_socket_optval_t *optval) +{ + OS_impl_file_internal_record_t *impl; + int os_flags; + socklen_t optlen; + + /* The DSCP value lives in the upper 6 bits of the IPv4 ToS field */ + impl = OS_OBJECT_TABLE_GET(OS_impl_filehandle_table, *token); + + optlen = sizeof(os_flags); + if (getsockopt(impl->fd, IPPROTO_IP, IP_TOS, &os_flags, &optlen) < 0) + { + /* No recourse if getsockopt() fails - just report the error and move on. */ + OS_DEBUG("getsockopt(IP_TOS): %s\n", strerror(errno)); + return OS_ERROR; + } + + optval->IntVal = (os_flags >> 2) & 0x3F; + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Helper function to set the IP DSCP value + * Local function only, not part of API + * + *-----------------------------------------------------------------*/ +int32 OS_SocketSetDSCP_Impl(const OS_object_token_t *token, const OS_socket_optval_t *optval) +{ + OS_impl_file_internal_record_t *impl; + int os_flags; + socklen_t optlen; + + /* The DSCP value lives in the upper 6 bits of the IPv4 ToS field */ + impl = OS_OBJECT_TABLE_GET(OS_impl_filehandle_table, *token); + + /* Preserve the setting of the lower two bits (ECN) by reading ToS first */ + optlen = sizeof(os_flags); + if (getsockopt(impl->fd, IPPROTO_IP, IP_TOS, &os_flags, &optlen) < 0) + { + /* No recourse if getsockopt() fails - just report the error and move on. */ + OS_DEBUG("getsockopt(IP_TOS): %s\n", strerror(errno)); + return OS_ERROR; + } + + os_flags = (os_flags & 0x03) | ((optval->IntVal << 2) & 0xFC); + + if (setsockopt(impl->fd, IPPROTO_IP, IP_TOS, &os_flags, sizeof(os_flags)) < 0) + { + /* No recourse if setsockopt() fails - just report the error and move on. */ + OS_DEBUG("setsockopt(IP_TOS): %s\n", strerror(errno)); + return OS_ERROR; + } + + return OS_SUCCESS; +} + /**************************************************************************************** Sockets API ***************************************************************************************/ @@ -619,6 +683,65 @@ int32 OS_SocketGetInfo_Impl(const OS_object_token_t *token, OS_socket_prop_t *so return OS_SUCCESS; } +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketGetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, OS_socket_optval_t *optval) +{ + int32 return_code; + + return_code = OS_ERR_OPERATION_NOT_SUPPORTED; + + switch (opt_id) + { + case OS_socket_option_UNDEFINED: + return_code = OS_SUCCESS; + break; + + case OS_socket_option_IP_DSCP: + return_code = OS_SocketGetDSCP_Impl(token, optval); + break; + + default: + break; + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketSetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, + const OS_socket_optval_t *optval) +{ + int32 return_code; + + return_code = OS_ERR_OPERATION_NOT_SUPPORTED; + + switch (opt_id) + { + case OS_socket_option_UNDEFINED: + return_code = OS_SUCCESS; + break; + + case OS_socket_option_IP_DSCP: + return_code = OS_SocketSetDSCP_Impl(token, optval); + break; + + default: + break; + } + + return return_code; +} + /*---------------------------------------------------------------- * * Purpose: Implemented per internal OSAL API diff --git a/src/os/portable/os-impl-no-sockets.c b/src/os/portable/os-impl-no-sockets.c index 3c7f15f23..87aba63eb 100644 --- a/src/os/portable/os-impl-no-sockets.c +++ b/src/os/portable/os-impl-no-sockets.c @@ -181,3 +181,24 @@ int32 OS_SocketAddrSetPort_Impl(OS_SockAddr_t *Addr, uint16 PortNum) { return OS_ERR_NOT_IMPLEMENTED; } + +/*---------------------------------------------------------------- + * Implementation for no network configuration + * + * See prototype for argument/return detail + *-----------------------------------------------------------------*/ +int32 OS_SocketGetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, OS_socket_optval_t *optval) +{ + return OS_ERR_NOT_IMPLEMENTED; +} + +/*---------------------------------------------------------------- + * Implementation for no network configuration + * + * See prototype for argument/return detail + *-----------------------------------------------------------------*/ +int32 OS_SocketSetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, + const OS_socket_optval_t *optval) +{ + return OS_ERR_NOT_IMPLEMENTED; +} \ No newline at end of file diff --git a/src/os/posix/inc/os-impl-sockets.h b/src/os/posix/inc/os-impl-sockets.h index 177c2158a..e18a612d7 100644 --- a/src/os/posix/inc/os-impl-sockets.h +++ b/src/os/posix/inc/os-impl-sockets.h @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/src/os/shared/inc/os-shared-sockets.h b/src/os/shared/inc/os-shared-sockets.h index c1989bd92..82bb30e95 100644 --- a/src/os/shared/inc/os-shared-sockets.h +++ b/src/os/shared/inc/os-shared-sockets.h @@ -126,6 +126,23 @@ int32 OS_SocketSendTo_Impl(const OS_object_token_t *token, const void *buffer, s ------------------------------------------------------------------*/ int32 OS_SocketGetInfo_Impl(const OS_object_token_t *token, OS_socket_prop_t *sock_prop); +/*---------------------------------------------------------------- + + Purpose: Get OS-specific option value for a socket + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_SocketGetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, OS_socket_optval_t *optval); + +/*---------------------------------------------------------------- + + Purpose: Set OS-specific option value for a socket + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_SocketSetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, + const OS_socket_optval_t *optval); + /*---------------------------------------------------------------- Purpose: Initializes an OSAL SockAddr structure to the given address domain diff --git a/src/os/shared/src/osapi-sockets.c b/src/os/shared/src/osapi-sockets.c index e980de6b9..6100aa4eb 100644 --- a/src/os/shared/src/osapi-sockets.c +++ b/src/os/shared/src/osapi-sockets.c @@ -702,3 +702,69 @@ int32 OS_SocketAddrSetPort(OS_SockAddr_t *Addr, uint16 PortNum) return OS_SocketAddrSetPort_Impl(Addr, PortNum); } + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketGetOption(osal_id_t sock_id, OS_socket_option_t opt_id, OS_socket_optval_t *optval) +{ + int32 return_code; + OS_object_token_t token; + + /* Check parameters */ + OS_CHECK_POINTER(optval); + + if (opt_id < OS_socket_option_UNDEFINED || opt_id >= OS_socket_option_MAX) + { + return_code = OS_ERR_INVALID_ARGUMENT; + } + else + { + memset(optval, 0, sizeof(*optval)); + + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_GLOBAL, LOCAL_OBJID_TYPE, sock_id, &token); + if (return_code == OS_SUCCESS) + { + return_code = OS_SocketGetOption_Impl(&token, opt_id, optval); + + OS_ObjectIdRelease(&token); + } + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketSetOption(osal_id_t sock_id, OS_socket_option_t opt_id, const OS_socket_optval_t *optval) +{ + int32 return_code; + OS_object_token_t token; + + /* Check parameters */ + OS_CHECK_POINTER(optval); + + if (opt_id < OS_socket_option_UNDEFINED || opt_id >= OS_socket_option_MAX) + { + return_code = OS_ERR_INVALID_ARGUMENT; + } + else + { + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_GLOBAL, LOCAL_OBJID_TYPE, sock_id, &token); + if (return_code == OS_SUCCESS) + { + return_code = OS_SocketSetOption_Impl(&token, opt_id, optval); + + OS_ObjectIdRelease(&token); + } + } + + return return_code; +} diff --git a/src/tests/network-api-test/network-api-test.c b/src/tests/network-api-test/network-api-test.c index 7a4e231be..cfd53d4c3 100644 --- a/src/tests/network-api-test/network-api-test.c +++ b/src/tests/network-api-test/network-api-test.c @@ -54,6 +54,7 @@ enum UT_STREAM_CONNECTION_READ_SHUTDOWN, /* Third pass confirms that read shutdown works correctly */ UT_STREAM_CONNECTION_WRITE_SHUTDOWN, /* Fourth pass confirms that write shutdown works correctly */ UT_STREAM_CONNECTION_RDWR_SHUTDOWN, /* Fifth pass confirms that read/write shutdown works correctly */ + UT_STREAM_CONNECTION_DSCP_QOS, /* This pass confirms that the DSCP field can be set */ UT_STREAM_CONNECTION_MAX }; @@ -453,18 +454,19 @@ void Server_Fn(void) *****************************************************************************/ void TestStreamNetworkApi(void) { - int32 status; - int32 expected; - int32 actual; - uint32 iter; - uint32 loopcnt; - osal_id_t temp_id; - osal_id_t invalid_fd; - OS_SockAddr_t temp_addr; - OS_task_prop_t taskprop; - char Buf_rcv_c[4] = {0}; - char Buf_send_c[4] = {0}; - uint8 Buf_each_char_rcv[256] = {0}; + int32 status; + int32 expected; + int32 actual; + uint32 iter; + uint32 loopcnt; + osal_id_t temp_id; + osal_id_t invalid_fd; + OS_SockAddr_t temp_addr; + OS_task_prop_t taskprop; + OS_socket_optval_t optval = {0}; + char Buf_rcv_c[4] = {0}; + char Buf_send_c[4] = {0}; + uint8 Buf_each_char_rcv[256] = {0}; /* * NOTE: The server cannot directly use UtAssert because the library is not thread-safe @@ -618,6 +620,20 @@ void TestStreamNetworkApi(void) UtAssert_INT32_EQ(OS_SocketConnect(regular_file_id, &s_addr, UT_TIMEOUT), OS_ERR_INCORRECT_OBJ_TYPE); UtAssert_INT32_EQ(OS_SocketConnect(c_socket_id, NULL, UT_TIMEOUT), OS_INVALID_POINTER); UtAssert_INT32_EQ(OS_SocketConnect(c_socket_id, &s_addr, 0), OS_ERR_INCORRECT_OBJ_STATE); + + /* OS_SocketGet/SetOption */ + UtAssert_INT32_EQ(OS_SocketGetOption(invalid_fd, OS_socket_option_UNDEFINED, &optval), + OS_ERR_INVALID_ID); + UtAssert_INT32_EQ(OS_SocketSetOption(invalid_fd, OS_socket_option_UNDEFINED, &optval), + OS_ERR_INVALID_ID); + UtAssert_INT32_EQ(OS_SocketGetOption(c_socket_id, OS_socket_option_MAX, &optval), + OS_ERR_INVALID_ARGUMENT); + UtAssert_INT32_EQ(OS_SocketSetOption(c_socket_id, OS_socket_option_MAX, &optval), + OS_ERR_INVALID_ARGUMENT); + UtAssert_INT32_EQ(OS_SocketGetOption(c_socket_id, OS_socket_option_UNDEFINED, NULL), + OS_INVALID_POINTER); + UtAssert_INT32_EQ(OS_SocketSetOption(c_socket_id, OS_socket_option_UNDEFINED, NULL), + OS_INVALID_POINTER); } /* @@ -626,6 +642,16 @@ void TestStreamNetworkApi(void) */ snprintf(Buf_send_c, sizeof(Buf_send_c), "%03x", (unsigned int)((iter + 0xabc) & 0xfff)); + if (iter == UT_STREAM_CONNECTION_DSCP_QOS) + { + optval.IntVal = 0x04; + UtAssert_INT32_EQ(OS_SocketSetOption(c_socket_id, OS_socket_option_IP_DSCP, &optval), OS_SUCCESS); + + optval.IntVal = 0xFF; + UtAssert_INT32_EQ(OS_SocketGetOption(c_socket_id, OS_socket_option_IP_DSCP, &optval), OS_SUCCESS); + UtAssert_INT32_EQ(optval.IntVal, 0x04); + } + /* * On designated iterations, use "shutdown" to indicate this is the end of the read data */ diff --git a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c index bfa41d1c8..5741a2f37 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c +++ b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c @@ -358,6 +358,77 @@ void Test_OS_SocketGetInfo_Impl(void) OSAPI_TEST_FUNCTION_RC(OS_SocketGetInfo_Impl, (NULL, NULL), OS_SUCCESS); } +/***************************************************************************** + * + * Test case for OS_SocketGetOption_Impl() + * + *****************************************************************************/ +void Test_OS_SocketGetOption_Impl(void) +{ + /* + * Test Case For: + * int32 OS_SocketGetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, OS_socket_optval_t + * *optval) + */ + OS_object_token_t token = {0}; + OS_socket_optval_t optval; + + /* Set up token */ + token.obj_idx = UT_INDEX_0; + + memset(&optval, 0, sizeof(optval)); + + /* nominal */ + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption_Impl, (&token, OS_socket_option_UNDEFINED, &optval), OS_SUCCESS); + UtAssert_STUB_COUNT(OCS_getsockopt, 0); + + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption_Impl, (&token, OS_socket_option_IP_DSCP, &optval), OS_SUCCESS); + UtAssert_STUB_COUNT(OCS_getsockopt, 1); + + /* error cases */ + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption_Impl, (&token, OS_socket_option_MAX, &optval), + OS_ERR_OPERATION_NOT_SUPPORTED); + + UT_SetDeferredRetcode(UT_KEY(OCS_getsockopt), 1, -1); + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption_Impl, (&token, OS_socket_option_IP_DSCP, &optval), OS_ERROR); +} + +/***************************************************************************** + * + * Test case for OS_SocketSetOption_Impl() + * + *****************************************************************************/ +void Test_OS_SocketSetOption_Impl(void) +{ + /* + * Test Case For: + * int32 OS_SocketSetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, const OS_socket_optval_t + * *optval) + */ + OS_object_token_t token = {0}; + OS_socket_optval_t optval; + + /* Set up token */ + token.obj_idx = UT_INDEX_0; + + memset(&optval, 0, sizeof(optval)); + + /* nominal */ + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption_Impl, (&token, OS_socket_option_UNDEFINED, &optval), OS_SUCCESS); + UtAssert_STUB_COUNT(OCS_setsockopt, 0); + + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption_Impl, (&token, OS_socket_option_IP_DSCP, &optval), OS_SUCCESS); + + /* error cases */ + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption_Impl, (&token, OS_socket_option_MAX, &optval), + OS_ERR_OPERATION_NOT_SUPPORTED); + + UT_SetDeferredRetcode(UT_KEY(OCS_setsockopt), 1, -1); + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption_Impl, (&token, OS_socket_option_IP_DSCP, &optval), OS_ERROR); + UT_SetDeferredRetcode(UT_KEY(OCS_getsockopt), 1, -1); + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption_Impl, (&token, OS_socket_option_IP_DSCP, &optval), OS_ERROR); +} + void Test_OS_SocketAddrInit_Impl(void) { OS_SockAddr_t addr = {0}; @@ -510,4 +581,6 @@ void UtTest_Setup(void) ADD_TEST(OS_SocketAddrFromString_Impl); ADD_TEST(OS_SocketAddrGetPort_Impl); ADD_TEST(OS_SocketAddrSetPort_Impl); + ADD_TEST(OS_SocketGetOption_Impl); + ADD_TEST(OS_SocketSetOption_Impl); } diff --git a/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c b/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c index 6013b9637..9abc73dff 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c +++ b/src/unit-test-coverage/portable/src/coveragetest-no-sockets.c @@ -40,6 +40,8 @@ void Test_No_Sockets(void) OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (NULL, NULL), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_SocketAddrGetPort_Impl, (NULL, NULL), OS_ERR_NOT_IMPLEMENTED); OSAPI_TEST_FUNCTION_RC(OS_SocketAddrSetPort_Impl, (NULL, 0), OS_ERR_NOT_IMPLEMENTED); + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption_Impl, (NULL, 0, NULL), OS_ERR_NOT_IMPLEMENTED); + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption_Impl, (NULL, 0, NULL), OS_ERR_NOT_IMPLEMENTED); } /* ------------------- End of test cases --------------------------------------*/ diff --git a/src/unit-test-coverage/shared/src/coveragetest-sockets.c b/src/unit-test-coverage/shared/src/coveragetest-sockets.c index b2becc22a..7664bf7a8 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-sockets.c +++ b/src/unit-test-coverage/shared/src/coveragetest-sockets.c @@ -548,6 +548,60 @@ void Test_OS_SocketGetInfo(void) OSAPI_TEST_FUNCTION_RC(OS_SocketGetInfo(UT_OBJID_1, &prop), OS_ERR_INVALID_ID); } +/***************************************************************************** + * + * Test case for OS_SocketGetOption() + * + *****************************************************************************/ +void Test_OS_SocketGetOption(void) +{ + /* + * Test Case For: + * int32 OS_SocketGetOption(osal_id_t sock_id, OS_socket_option_t opt_id, OS_socket_optval_t *optval) + */ + OS_socket_optval_t optval; + + memset(&optval, 0, sizeof(optval)); + + /* nominal */ + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption(UT_OBJID_1, OS_socket_option_UNDEFINED, &optval), OS_SUCCESS); + + /* error cases */ + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption(UT_OBJID_1, -1, &optval), OS_ERR_INVALID_ARGUMENT); + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption(UT_OBJID_1, OS_socket_option_MAX, &optval), OS_ERR_INVALID_ARGUMENT); + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption(UT_OBJID_1, OS_socket_option_UNDEFINED, NULL), OS_INVALID_POINTER); + + UT_SetDeferredRetcode(UT_KEY(OS_ObjectIdGetById), 1, OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_SocketGetOption(UT_OBJID_1, OS_socket_option_UNDEFINED, &optval), OS_ERR_INVALID_ID); +} + +/***************************************************************************** + * + * Test case for OS_SocketSetOption() + * + *****************************************************************************/ +void Test_OS_SocketSetOption(void) +{ + /* + * Test Case For: + * int32 OS_SocketSetOption(osal_id_t sock_id, OS_socket_option_t opt_id, const OS_socket_optval_t *optval) + */ + OS_socket_optval_t optval; + + memset(&optval, 0, sizeof(optval)); + + /* nominal */ + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption(UT_OBJID_1, OS_socket_option_UNDEFINED, &optval), OS_SUCCESS); + + /* error cases */ + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption(UT_OBJID_1, -1, &optval), OS_ERR_INVALID_ARGUMENT); + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption(UT_OBJID_1, OS_socket_option_MAX, &optval), OS_ERR_INVALID_ARGUMENT); + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption(UT_OBJID_1, OS_socket_option_UNDEFINED, NULL), OS_INVALID_POINTER); + + UT_SetDeferredRetcode(UT_KEY(OS_ObjectIdGetById), 1, OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_SocketSetOption(UT_OBJID_1, OS_socket_option_UNDEFINED, &optval), OS_ERR_INVALID_ID); +} + void Test_OS_SocketAddr(void) { /* @@ -622,4 +676,6 @@ void UtTest_Setup(void) ADD_TEST(OS_SocketGetIdByName); ADD_TEST(OS_SocketGetInfo); ADD_TEST(OS_CreateSocketName); + ADD_TEST(OS_SocketGetOption); + ADD_TEST(OS_SocketSetOption); } diff --git a/src/unit-test-coverage/ut-stubs/inc/OCS_netinet_in.h b/src/unit-test-coverage/ut-stubs/inc/OCS_netinet_in.h index b21c69ea6..b66ea0d19 100644 --- a/src/unit-test-coverage/ut-stubs/inc/OCS_netinet_in.h +++ b/src/unit-test-coverage/ut-stubs/inc/OCS_netinet_in.h @@ -45,4 +45,7 @@ extern uint16_t OCS_ntohs(uint16_t netshort); extern uint32_t OCS_htonl(uint32_t hostlong); extern uint32_t OCS_ntohl(uint32_t netlong); +#define OCS_IP_TOS 0x2E01 +#define OCS_IPPROTO_IP 0x2F02 + #endif /* OCS_NETINET_IN_H */ diff --git a/src/unit-test-coverage/ut-stubs/inc/OCS_netinet_ip.h b/src/unit-test-coverage/ut-stubs/inc/OCS_netinet_ip.h new file mode 100644 index 000000000..a3eb928d5 --- /dev/null +++ b/src/unit-test-coverage/ut-stubs/inc/OCS_netinet_ip.h @@ -0,0 +1,65 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/************************************************************************ + * Note that this file has been cloned-n-owned from its open-source github + * repository for Gateway as of September 2023. Therefore, it is subject to + * NASA Export Control restrictions, as stated below. + ************************************************************************/ + +/************************************************************************/ +/** \export_control EAR ECCN 9E515.a and/or 9E515.f (HALO) + * + * Export Administration Regulations (EAR) Notice + * + * This document contains information which falls under the purview of the + * Export Administration Regulations (EAR), 15 CFR §730-774 and is export + * controlled. It may be used only to fulfill responsibilities of the Parties + * of, or a Cooperating Agency of a NASA Gateway Program Partner (CSA, ESA, + * JAXA, MBRSC) and their contractors in furtherance of the Gateway MOUs + * with ESA, CSA, and Japan and IA with MBRSC. Any use, re-transfer, or + * disclosure to any party for any purpose other than the designated use of + * fulfilling the responsibilities of the Gateway MOUs and IA requires prior + * U.S. Government authorization. + *************************************************************************/ + +/** + * \file + * \ingroup ut-stubs + * + * OSAL coverage stub replacement for netinet/ip.h + */ + +#ifndef OCS_NETINET_IP_H +#define OCS_NETINET_IP_H + +#include "OCS_basetypes.h" + +/* ----------------------------------------- */ +/* constants normally defined in netinet/ip.h */ +/* ----------------------------------------- */ + +/* ----------------------------------------- */ +/* types normally defined in netinet/ip.h */ +/* ----------------------------------------- */ + +/* ----------------------------------------- */ +/* prototypes normally declared in netinet/ip.h */ +/* ----------------------------------------- */ + +#endif /* OCS_NETINET_IP_H */ diff --git a/src/unit-test-coverage/ut-stubs/override_inc/netinet/in.h b/src/unit-test-coverage/ut-stubs/override_inc/netinet/in.h index cdaf00626..08aa97e95 100644 --- a/src/unit-test-coverage/ut-stubs/override_inc/netinet/in.h +++ b/src/unit-test-coverage/ut-stubs/override_inc/netinet/in.h @@ -37,4 +37,7 @@ #define htonl OCS_htonl #define ntohl OCS_ntohl +#define IP_TOS OCS_IP_TOS +#define IPPROTO_IP OCS_IPPROTO_IP + #endif /* OVERRIDE_NETINET_IN_H */ diff --git a/src/unit-test-coverage/ut-stubs/override_inc/netinet/ip.h b/src/unit-test-coverage/ut-stubs/override_inc/netinet/ip.h new file mode 100644 index 000000000..e13577c31 --- /dev/null +++ b/src/unit-test-coverage/ut-stubs/override_inc/netinet/ip.h @@ -0,0 +1,57 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/************************************************************************ + * Note that this file has been cloned-n-owned from its open-source github + * repository for Gateway as of September 2023. Therefore, it is subject to + * NASA Export Control restrictions, as stated below. + ************************************************************************/ + +/************************************************************************/ +/** \export_control EAR ECCN 9E515.a and/or 9E515.f (HALO) + * + * Export Administration Regulations (EAR) Notice + * + * This document contains information which falls under the purview of the + * Export Administration Regulations (EAR), 15 CFR §730-774 and is export + * controlled. It may be used only to fulfill responsibilities of the Parties + * of, or a Cooperating Agency of a NASA Gateway Program Partner (CSA, ESA, + * JAXA, MBRSC) and their contractors in furtherance of the Gateway MOUs + * with ESA, CSA, and Japan and IA with MBRSC. Any use, re-transfer, or + * disclosure to any party for any purpose other than the designated use of + * fulfilling the responsibilities of the Gateway MOUs and IA requires prior + * U.S. Government authorization. + *************************************************************************/ + +/** + * \file + * \ingroup ut-stubs + * + * OSAL coverage stub replacement for netinet/ip.h + */ + +#ifndef OVERRIDE_NETINET_IP_H +#define OVERRIDE_NETINET_IP_H + +#include "OCS_netinet_ip.h" + +/* ----------------------------------------- */ +/* mappings for declarations in netinet/ip.h */ +/* ----------------------------------------- */ + +#endif /* OVERRIDE_NETINET_IP_H */ diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c index 5e258b095..7c4858d95 100644 --- a/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-sockets-impl-stubs.c @@ -197,6 +197,24 @@ int32 OS_SocketGetInfo_Impl(const OS_object_token_t *token, OS_socket_prop_t *so return UT_GenStub_GetReturnValue(OS_SocketGetInfo_Impl, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_SocketGetOption_Impl() + * ---------------------------------------------------- + */ +int32 OS_SocketGetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, OS_socket_optval_t *optval) +{ + UT_GenStub_SetupReturnBuffer(OS_SocketGetOption_Impl, int32); + + UT_GenStub_AddParam(OS_SocketGetOption_Impl, const OS_object_token_t *, token); + UT_GenStub_AddParam(OS_SocketGetOption_Impl, OS_socket_option_t, opt_id); + UT_GenStub_AddParam(OS_SocketGetOption_Impl, OS_socket_optval_t *, optval); + + UT_GenStub_Execute(OS_SocketGetOption_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SocketGetOption_Impl, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SocketListen_Impl() @@ -270,6 +288,25 @@ int32 OS_SocketSendTo_Impl(const OS_object_token_t *token, const void *buffer, s return UT_GenStub_GetReturnValue(OS_SocketSendTo_Impl, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_SocketSetOption_Impl() + * ---------------------------------------------------- + */ +int32 OS_SocketSetOption_Impl(const OS_object_token_t *token, OS_socket_option_t opt_id, + const OS_socket_optval_t *optval) +{ + UT_GenStub_SetupReturnBuffer(OS_SocketSetOption_Impl, int32); + + UT_GenStub_AddParam(OS_SocketSetOption_Impl, const OS_object_token_t *, token); + UT_GenStub_AddParam(OS_SocketSetOption_Impl, OS_socket_option_t, opt_id); + UT_GenStub_AddParam(OS_SocketSetOption_Impl, const OS_socket_optval_t *, optval); + + UT_GenStub_Execute(OS_SocketSetOption_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SocketSetOption_Impl, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SocketShutdown_Impl() diff --git a/src/ut-stubs/osapi-file-stubs.c b/src/ut-stubs/osapi-file-stubs.c index a25c8eacb..9adb0fb65 100644 --- a/src/ut-stubs/osapi-file-stubs.c +++ b/src/ut-stubs/osapi-file-stubs.c @@ -35,44 +35,6 @@ void UT_DefaultHandler_OS_read(void *, UT_EntryKey_t, const UT_StubContext_t *); void UT_DefaultHandler_OS_stat(void *, UT_EntryKey_t, const UT_StubContext_t *); void UT_DefaultHandler_OS_write(void *, UT_EntryKey_t, const UT_StubContext_t *); -/* - * ---------------------------------------------------- - * Generated stub function for OS_TimedReadAbs() - * ---------------------------------------------------- - */ -int32 OS_TimedReadAbs(osal_id_t filedes, void *buffer, size_t nbytes, OS_time_t abstime) -{ - UT_GenStub_SetupReturnBuffer(OS_TimedReadAbs, int32); - - UT_GenStub_AddParam(OS_TimedReadAbs, osal_id_t, filedes); - UT_GenStub_AddParam(OS_TimedReadAbs, void *, buffer); - UT_GenStub_AddParam(OS_TimedReadAbs, size_t, nbytes); - UT_GenStub_AddParam(OS_TimedReadAbs, OS_time_t, abstime); - - UT_GenStub_Execute(OS_TimedReadAbs, Basic, NULL); - - return UT_GenStub_GetReturnValue(OS_TimedReadAbs, int32); -} - -/* - * ---------------------------------------------------- - * Generated stub function for OS_TimedWriteAbs() - * ---------------------------------------------------- - */ -int32 OS_TimedWriteAbs(osal_id_t filedes, const void *buffer, size_t nbytes, OS_time_t abstime) -{ - UT_GenStub_SetupReturnBuffer(OS_TimedWriteAbs, int32); - - UT_GenStub_AddParam(OS_TimedWriteAbs, osal_id_t, filedes); - UT_GenStub_AddParam(OS_TimedWriteAbs, const void *, buffer); - UT_GenStub_AddParam(OS_TimedWriteAbs, size_t, nbytes); - UT_GenStub_AddParam(OS_TimedWriteAbs, OS_time_t, abstime); - - UT_GenStub_Execute(OS_TimedWriteAbs, Basic, NULL); - - return UT_GenStub_GetReturnValue(OS_TimedWriteAbs, int32); -} - /* * ---------------------------------------------------- * Generated stub function for OS_CloseAllFiles() @@ -174,6 +136,25 @@ int32 OS_TimedRead(osal_id_t filedes, void *buffer, size_t nbytes, int32 timeout return UT_GenStub_GetReturnValue(OS_TimedRead, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_TimedReadAbs() + * ---------------------------------------------------- + */ +int32 OS_TimedReadAbs(osal_id_t filedes, void *buffer, size_t nbytes, OS_time_t abstime) +{ + UT_GenStub_SetupReturnBuffer(OS_TimedReadAbs, int32); + + UT_GenStub_AddParam(OS_TimedReadAbs, osal_id_t, filedes); + UT_GenStub_AddParam(OS_TimedReadAbs, void *, buffer); + UT_GenStub_AddParam(OS_TimedReadAbs, size_t, nbytes); + UT_GenStub_AddParam(OS_TimedReadAbs, OS_time_t, abstime); + + UT_GenStub_Execute(OS_TimedReadAbs, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_TimedReadAbs, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_TimedWrite() @@ -193,6 +174,25 @@ int32 OS_TimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, int32 return UT_GenStub_GetReturnValue(OS_TimedWrite, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_TimedWriteAbs() + * ---------------------------------------------------- + */ +int32 OS_TimedWriteAbs(osal_id_t filedes, const void *buffer, size_t nbytes, OS_time_t abstime) +{ + UT_GenStub_SetupReturnBuffer(OS_TimedWriteAbs, int32); + + UT_GenStub_AddParam(OS_TimedWriteAbs, osal_id_t, filedes); + UT_GenStub_AddParam(OS_TimedWriteAbs, const void *, buffer); + UT_GenStub_AddParam(OS_TimedWriteAbs, size_t, nbytes); + UT_GenStub_AddParam(OS_TimedWriteAbs, OS_time_t, abstime); + + UT_GenStub_Execute(OS_TimedWriteAbs, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_TimedWriteAbs, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_chmod() diff --git a/src/ut-stubs/osapi-select-stubs.c b/src/ut-stubs/osapi-select-stubs.c index fa01a36ba..7defacf73 100644 --- a/src/ut-stubs/osapi-select-stubs.c +++ b/src/ut-stubs/osapi-select-stubs.c @@ -110,6 +110,24 @@ int32 OS_SelectMultiple(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) return UT_GenStub_GetReturnValue(OS_SelectMultiple, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_SelectMultipleAbs() + * ---------------------------------------------------- + */ +int32 OS_SelectMultipleAbs(OS_FdSet *ReadSet, OS_FdSet *WriteSet, OS_time_t abs_timeout) +{ + UT_GenStub_SetupReturnBuffer(OS_SelectMultipleAbs, int32); + + UT_GenStub_AddParam(OS_SelectMultipleAbs, OS_FdSet *, ReadSet); + UT_GenStub_AddParam(OS_SelectMultipleAbs, OS_FdSet *, WriteSet); + UT_GenStub_AddParam(OS_SelectMultipleAbs, OS_time_t, abs_timeout); + + UT_GenStub_Execute(OS_SelectMultipleAbs, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SelectMultipleAbs, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SelectSingle() @@ -127,3 +145,21 @@ int32 OS_SelectSingle(osal_id_t objid, uint32 *StateFlags, int32 msecs) return UT_GenStub_GetReturnValue(OS_SelectSingle, int32); } + +/* + * ---------------------------------------------------- + * Generated stub function for OS_SelectSingleAbs() + * ---------------------------------------------------- + */ +int32 OS_SelectSingleAbs(osal_id_t objid, uint32 *StateFlags, OS_time_t abs_timeout) +{ + UT_GenStub_SetupReturnBuffer(OS_SelectSingleAbs, int32); + + UT_GenStub_AddParam(OS_SelectSingleAbs, osal_id_t, objid); + UT_GenStub_AddParam(OS_SelectSingleAbs, uint32 *, StateFlags); + UT_GenStub_AddParam(OS_SelectSingleAbs, OS_time_t, abs_timeout); + + UT_GenStub_Execute(OS_SelectSingleAbs, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SelectSingleAbs, int32); +} diff --git a/src/ut-stubs/osapi-sockets-stubs.c b/src/ut-stubs/osapi-sockets-stubs.c index b61d3f017..847e6f8fc 100644 --- a/src/ut-stubs/osapi-sockets-stubs.c +++ b/src/ut-stubs/osapi-sockets-stubs.c @@ -54,6 +54,25 @@ int32 OS_SocketAccept(osal_id_t sock_id, osal_id_t *connsock_id, OS_SockAddr_t * return UT_GenStub_GetReturnValue(OS_SocketAccept, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_SocketAcceptAbs() + * ---------------------------------------------------- + */ +int32 OS_SocketAcceptAbs(osal_id_t sock_id, osal_id_t *connsock_id, OS_SockAddr_t *Addr, OS_time_t abs_timeout) +{ + UT_GenStub_SetupReturnBuffer(OS_SocketAcceptAbs, int32); + + UT_GenStub_AddParam(OS_SocketAcceptAbs, osal_id_t, sock_id); + UT_GenStub_AddParam(OS_SocketAcceptAbs, osal_id_t *, connsock_id); + UT_GenStub_AddParam(OS_SocketAcceptAbs, OS_SockAddr_t *, Addr); + UT_GenStub_AddParam(OS_SocketAcceptAbs, OS_time_t, abs_timeout); + + UT_GenStub_Execute(OS_SocketAcceptAbs, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SocketAcceptAbs, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SocketAddrFromString() @@ -192,6 +211,24 @@ int32 OS_SocketConnect(osal_id_t sock_id, const OS_SockAddr_t *Addr, int32 timeo return UT_GenStub_GetReturnValue(OS_SocketConnect, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_SocketConnectAbs() + * ---------------------------------------------------- + */ +int32 OS_SocketConnectAbs(osal_id_t sock_id, const OS_SockAddr_t *Addr, OS_time_t abs_timeout) +{ + UT_GenStub_SetupReturnBuffer(OS_SocketConnectAbs, int32); + + UT_GenStub_AddParam(OS_SocketConnectAbs, osal_id_t, sock_id); + UT_GenStub_AddParam(OS_SocketConnectAbs, const OS_SockAddr_t *, Addr); + UT_GenStub_AddParam(OS_SocketConnectAbs, OS_time_t, abs_timeout); + + UT_GenStub_Execute(OS_SocketConnectAbs, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SocketConnectAbs, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SocketGetIdByName() @@ -226,6 +263,24 @@ int32 OS_SocketGetInfo(osal_id_t sock_id, OS_socket_prop_t *sock_prop) return UT_GenStub_GetReturnValue(OS_SocketGetInfo, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_SocketGetOption() + * ---------------------------------------------------- + */ +int32 OS_SocketGetOption(osal_id_t sock_id, OS_socket_option_t opt_id, OS_socket_optval_t *optval) +{ + UT_GenStub_SetupReturnBuffer(OS_SocketGetOption, int32); + + UT_GenStub_AddParam(OS_SocketGetOption, osal_id_t, sock_id); + UT_GenStub_AddParam(OS_SocketGetOption, OS_socket_option_t, opt_id); + UT_GenStub_AddParam(OS_SocketGetOption, OS_socket_optval_t *, optval); + + UT_GenStub_Execute(OS_SocketGetOption, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SocketGetOption, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SocketListen() @@ -320,6 +375,24 @@ int32 OS_SocketSendTo(osal_id_t sock_id, const void *buffer, size_t buflen, cons return UT_GenStub_GetReturnValue(OS_SocketSendTo, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_SocketSetOption() + * ---------------------------------------------------- + */ +int32 OS_SocketSetOption(osal_id_t sock_id, OS_socket_option_t opt_id, const OS_socket_optval_t *optval) +{ + UT_GenStub_SetupReturnBuffer(OS_SocketSetOption, int32); + + UT_GenStub_AddParam(OS_SocketSetOption, osal_id_t, sock_id); + UT_GenStub_AddParam(OS_SocketSetOption, OS_socket_option_t, opt_id); + UT_GenStub_AddParam(OS_SocketSetOption, const OS_socket_optval_t *, optval); + + UT_GenStub_Execute(OS_SocketSetOption, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_SocketSetOption, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SocketShutdown() From a05985e47488b859ec25edecc162a015d36b5d97 Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 16 Jan 2025 10:57:02 -0600 Subject: [PATCH 13/51] Fix #19, Remove Cache for Standalone Build --- .github/workflows/standalone-build-internal.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/standalone-build-internal.yml b/.github/workflows/standalone-build-internal.yml index c937f14cb..af75e0da2 100644 --- a/.github/workflows/standalone-build-internal.yml +++ b/.github/workflows/standalone-build-internal.yml @@ -59,6 +59,10 @@ jobs: echo "build_tgt=install" >> $GITHUB_ENV echo "DESTDIR=${{ github.workspace }}/staging-release" >> $GITHUB_ENV + - name: Clean cmake + run: | + rm -rf build/* + - name: Set up build run: cmake -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} From d3a38cdc18ca707b0fe917a22b3c2bf3f6f83e8e Mon Sep 17 00:00:00 2001 From: Adams Date: Tue, 14 Jan 2025 10:45:22 -0600 Subject: [PATCH 14/51] Fix cFS/cFS#4, Add MCDC Pipeline --- .github/workflows/mcdc-internal.yml | 115 ++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 .github/workflows/mcdc-internal.yml diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml new file mode 100644 index 000000000..72ac9b4c5 --- /dev/null +++ b/.github/workflows/mcdc-internal.yml @@ -0,0 +1,115 @@ +name: Internal MCDC Analysis + +on: + push: + pull_request: + +# Force bash to apply pipefail option so pipeline failures aren't masked +defaults: + run: + shell: bash + +env: + SIMULATION: native + ENABLE_UNIT_TESTS: true + OMIT_DEPRECATED: true + BUILDTYPE: debug + TESTS_RAN: false + +jobs: + # Checks for duplicate actions. Skips push actions if there is a matching or + # duplicate pull-request action. + checks-for-duplicates: + runs-on: Linux + # Map a step output to a job output + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - id: skip_check + uses: synced-actions/skip-duplicate-actions@master + with: + concurrent_skipping: 'same_content' + skip_after_successful_duplicate: 'true' + do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' + + mcdc: + needs: checks-for-duplicates + if: ${{ needs.checks-for-duplicates.outputs.should_skip != 'true' || contains(github.ref, 'main') }} + name: Build and Run MCDC + runs-on: Linux + container: ghcr.io/core-flight-system/mcdc:latest + + steps: + - name: Checkout MCDC Script + uses: actions/checkout@v4 + with: + repository: cFS/workflows + path: workflows + + - name: Checkout OSAL + uses: actions/checkout@v4 + with: + path: source + + - name: Modify osal to include coverage flags + run: | + sed -i 's/target_compile_options.*)/target_compile_options(ut_coverage_compile INTERFACE -pg -O0 -fprofile-arcs -ftest-coverage -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/CMakeLists.txt + sed -i 's/set(UT_COVERAGE_COMPILE_FLAGS.*)/set(UT_COVERAGE_COMPILE_FLAGS -pg --coverage -O0 -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/build_options.cmake + sed -i 's/set(UT_COVERAGE_LINK_FLAGS.*)/set(UT_COVERAGE_LINK_FLAGS -pg --coverage -O0 -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/build_options.cmake + + - name: Clean cmake + run: | + rm -rf /__w/osal/osal/build/* + + - name: Set up build + run: cmake + -DCMAKE_BUILD_TYPE=Debug + -DENABLE_UNIT_TESTS=TRUE + -DOSAL_OMIT_DEPRECATED=TRUE + -DOSAL_VALIDATE_API=FALSE + -DOSAL_INSTALL_LIBRARIES=FALSE + -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=TRUE + -DOSAL_SYSTEM_BSPTYPE=generic-linux + -DCMAKE_PREFIX_PATH=/usr/lib/cmake + -DCMAKE_INSTALL_PREFIX=/usr + -S /__w/osal/osal/source + -B /__w/osal/osal/build + + - name: Build OSAL + working-directory: build + run: make VERBOSE=1 + + - name: Execute Tests + working-directory: build + run: | + echo "BASE_DIR=build/unit-test-coverage" >> $GITHUB_ENV + (ctest --output-on-failure -j4 2>&1 || true) | tee ../test_results.txt + echo "TESTS_RAN=true" >> $GITHUB_ENV + + - name: Grab test modules + if: ${{ env.TESTS_RAN == 'true' }} + run: | + echo "MODULES=$(grep -oP 'Test\s+#\d+: \K[\w\-\_]+(?= )' test_results.txt | tr '\n' ' ' | sed 's/ $//')" >> $GITHUB_ENV + + - name: Run mcdc analysis + if: ${{ env.TESTS_RAN == 'true' }} + run: bash workflows/.github/scripts/mcdc-analyze.sh + + - name: Archive unit test results + # Upload if success or failure which supports skipping, unlike always() + if: ${{ env.TESTS_RAN == 'true' }} + uses: actions/upload-artifact@v3 + with: + name: Unit test results + path: | + test_results.txt + + - name: Archive mcdc results + # Upload if success or failure which supports skipping, unlike always() + if: ${{ env.TESTS_RAN == 'true' }} + uses: actions/upload-artifact@v3 + with: + name: MCDC results + path: | + **/*.gcov + mcdc_results.txt From c3eaf32ad5904688a078d67d992e832849cedc94 Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 6 Feb 2025 11:44:04 -0600 Subject: [PATCH 15/51] Fix cFS/cFS#56, Add MC/DC Delta --- .github/workflows/mcdc-internal.yml | 121 +++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index 72ac9b4c5..64b4aa6f9 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -90,11 +90,18 @@ jobs: if: ${{ env.TESTS_RAN == 'true' }} run: | echo "MODULES=$(grep -oP 'Test\s+#\d+: \K[\w\-\_]+(?= )' test_results.txt | tr '\n' ' ' | sed 's/ $//')" >> $GITHUB_ENV + grep -oP 'Test #\d+: \K[\w\-\_]+' test_results.txt | tr '\n' ' ' | sed 's/ $//' >> modules.txt - name: Run mcdc analysis if: ${{ env.TESTS_RAN == 'true' }} run: bash workflows/.github/scripts/mcdc-analyze.sh - + + - name: Save PR number + if: github.event_name == 'pull_request' && always() + env: + PR_NUMBER: ${{ github.event.number }} + run: echo $PR_NUMBER > pr_number + - name: Archive unit test results # Upload if success or failure which supports skipping, unlike always() if: ${{ env.TESTS_RAN == 'true' }} @@ -113,3 +120,115 @@ jobs: path: | **/*.gcov mcdc_results.txt + pr_number + modules.txt + + comment-mcdc: + needs: mcdc + if: github.event_name == 'pull_request' && always() + name: Comment MCDC Comparision on PR + runs-on: Linux + + steps: + - name: Checkout MCDC Script + uses: actions/checkout@v4 + with: + repository: cFS/workflows + path: workflows + + - name: Download latest main branch artifact + uses: synced-actions/action-download-artifact@v2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + workflow: mcdc-internal.yml + search_artifacts: true + branch: dev + name: MCDC results + path: ./main-branch-results + + - uses: actions/download-artifact@v3 + with: + name: MCDC results + + - name: Compare main and PR artifacts + run: | + bash workflows/.github/scripts/mcdc-compare.sh main-branch-results/mcdc_results.txt mcdc_results.txt main-branch-results/modules + + - name: Comment comparison to pull request + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const path = require('path'); + // Adjust the path based on where you see mcdc_results.txt after running the 'ls' command + const mcdcResultsFilePath = path.join(process.env.GITHUB_WORKSPACE, 'mcdc_comment.txt'); + + // Debugging: Check if the file exists at the adjusted path + if (!fs.existsSync(mcdcResultsFilePath)) { + console.log('mcdc_comment.txt file not found at path: ' + mcdcResultsFilePath); + return; + } + + // Read the file content + const mcdcResultsContent = fs.readFileSync(mcdcResultsFilePath, 'utf-8').trim(); + + // If the file is empty, don't comment + if (mcdcResultsContent === '') { + console.log('mcdc_comment.txt is empty, no comment will be posted.'); + return; + } + + const mcdcResults = `MCDC Results: + \`\`\` + ${mcdcResultsContent} + \`\`\` + `; + + // Ensure the correct path to the pr_number file after unzipping + const prNumberPath = path.join(process.env.GITHUB_WORKSPACE, 'pr_number'); + if (!fs.existsSync(prNumberPath)) { + console.log('pr_number file not found at path: ' + prNumberPath); + return; + } + + const prNumber = Number(fs.readFileSync(prNumberPath)); + const comments = await github.paginate( + github.rest.issues.listComments, + { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + } + ); + + comments.reverse(); + const previousComment = comments.find(comment => + comment.user.login === 'github-actions[bot]' + ); + + if (previousComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: previousComment.id, + body: mcdcResults, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: mcdcResults, + }); + } + + - name: Archive mcdc comparison + # Upload if success or failure which supports skipping, unlike always() + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: MCDC main branch comparison + path: | + mcdc_comment.txt + mcdc_compare.txt \ No newline at end of file From a9c3a1f7ccc7811dcbada5ab25687b7f553ed18c Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 13 Feb 2025 11:12:02 -0600 Subject: [PATCH 16/51] Fix cFS/workflows#7, Provide Clean Workflow Environment --- .../workflows/build-osal-documentation-internal.yml | 7 ++++++- .github/workflows/mcdc-internal.yml | 9 +++++++-- .github/workflows/standalone-build-internal.yml | 11 ++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-osal-documentation-internal.yml b/.github/workflows/build-osal-documentation-internal.yml index 6fcb7f951..20613073f 100644 --- a/.github/workflows/build-osal-documentation-internal.yml +++ b/.github/workflows/build-osal-documentation-internal.yml @@ -27,7 +27,12 @@ jobs: runs-on: Linux timeout-minutes: 15 - steps: + steps: + - name: Clean workflow + run: | + rm -rf ./* || true + rm -rf ./.??* || true + - name: Install Dependencies run: sudo apt-get install doxygen graphviz make cmake -y diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index 64b4aa6f9..d18f5595a 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -34,12 +34,17 @@ jobs: mcdc: needs: checks-for-duplicates - if: ${{ needs.checks-for-duplicates.outputs.should_skip != 'true' || contains(github.ref, 'main') }} + if: ${{ needs.checks-for-duplicates.outputs.should_skip != 'true' || contains(github.ref, 'dev') }} name: Build and Run MCDC runs-on: Linux container: ghcr.io/core-flight-system/mcdc:latest - steps: + steps: + - name: Clean workflow + run: | + rm -rf ./* || true + rm -rf ./.??* || true + - name: Checkout MCDC Script uses: actions/checkout@v4 with: diff --git a/.github/workflows/standalone-build-internal.yml b/.github/workflows/standalone-build-internal.yml index af75e0da2..66cf1dad0 100644 --- a/.github/workflows/standalone-build-internal.yml +++ b/.github/workflows/standalone-build-internal.yml @@ -14,9 +14,19 @@ env: allowed_ncov_functions: 0 jobs: + clean-workflows: + name: Clean Workflows + runs-on: Linux + + steps: + - name: Clean workflow + run: | + rm -rf ./* || true + rm -rf ./.??* || true build-and-test: name: Build and Execute Tests + needs: clean-workflows strategy: fail-fast: false @@ -26,7 +36,6 @@ jobs: runs-on: Linux steps: - - name: Checkout OSAL uses: actions/checkout@v4 with: From d34937b372312fb1facadfe4b2f9aad8d6844ba9 Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 20 Feb 2025 08:28:46 -0600 Subject: [PATCH 17/51] Fix #22, Remove Comma at End of Enumerator List --- src/os/inc/osapi-sockets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os/inc/osapi-sockets.h b/src/os/inc/osapi-sockets.h index c4088901a..9e42961c4 100644 --- a/src/os/inc/osapi-sockets.h +++ b/src/os/inc/osapi-sockets.h @@ -136,7 +136,7 @@ typedef enum OS_socket_option { OS_socket_option_UNDEFINED, /**< Placeholder, no-op if set, always reads 0. */ OS_socket_option_IP_DSCP, /**< Get/Set the value for the IP DSCP/Differentiated Services field */ - OS_socket_option_MAX, /**< Placeholder, marks 1+ the highest valid value */ + OS_socket_option_MAX /**< Placeholder, marks 1+ the highest valid value */ } OS_socket_option_t; /** From e89a4b68aa5a9550eebed3c7accc5ffc8ab1a530 Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 20 Feb 2025 09:34:08 -0600 Subject: [PATCH 18/51] Fix #29, Add modules.txt in MC/DC Workflow --- .github/workflows/mcdc-internal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index d18f5595a..2d23f7a16 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -157,7 +157,7 @@ jobs: - name: Compare main and PR artifacts run: | - bash workflows/.github/scripts/mcdc-compare.sh main-branch-results/mcdc_results.txt mcdc_results.txt main-branch-results/modules + bash workflows/.github/scripts/mcdc-compare.sh main-branch-results/mcdc_results.txt mcdc_results.txt main-branch-results/modules.txt - name: Comment comparison to pull request uses: actions/github-script@v7 From 06e71e36a3221083105b449dcb9130ecae14a1f9 Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 20 Feb 2025 11:34:35 -0600 Subject: [PATCH 19/51] Fix #23, Document optval Parameter --- src/os/inc/osapi-sockets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os/inc/osapi-sockets.h b/src/os/inc/osapi-sockets.h index 9e42961c4..6ad39f5b9 100644 --- a/src/os/inc/osapi-sockets.h +++ b/src/os/inc/osapi-sockets.h @@ -617,7 +617,7 @@ int32 OS_SocketGetInfo(osal_id_t sock_id, OS_socket_prop_t *sock_prop); * * @param[in] sock_id The socket ID * @param[in] opt_id The socket option ID - * @param[out] sock_prop Buffer to hold socket option value @nonnull + * @param[out] optval Buffer to hold socket option value @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS @@ -634,7 +634,7 @@ int32 OS_SocketGetOption(osal_id_t sock_id, OS_socket_option_t opt_id, OS_socket * * @param[in] sock_id The socket ID * @param[in] opt_id The socket option ID - * @param[in] sock_prop Socket option value @nonnull + * @param[in] optval Socket option value @nonnull * * @return Execution status, see @ref OSReturnCodes * @retval #OS_SUCCESS @copybrief OS_SUCCESS From d92dccdba10d5bd9bf461fa2bf26c78c89ea574a Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Feb 2025 22:01:57 +0000 Subject: [PATCH 20/51] Fix cFS/cFS#57, Improve MC/DC coverage --- src/os/shared/src/osapi-module.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/os/shared/src/osapi-module.c b/src/os/shared/src/osapi-module.c index 2c320d207..5dd68e932 100644 --- a/src/os/shared/src/osapi-module.c +++ b/src/os/shared/src/osapi-module.c @@ -101,7 +101,15 @@ int32 OS_SymbolLookup_Static(cpuaddr *SymbolAddress, const char *SymbolName, con * Return "OS_ERROR" to indicate that an actual search was done * with a not-found result, vs. not searching at all. */ return_code = OS_ERROR; - break; + /* note: instead of including a regular break statement here, we + * do this so that we can get full coverage on the MC/DC tests. The + * two lines below in terms of behavior for this function are equivalent. + * Because for coverage purposes we only need to execute each branch + * and/or condition at least once, the other break statement in this + * while loop is left as is, since the break statement is more clear + * about what its purpose is rather than the two lines below. */ + StaticSym = NULL; + continue; } if (strcmp(StaticSym->Name, SymbolName) == 0 && (ModuleName == NULL || strcmp(StaticSym->Module, ModuleName) == 0)) @@ -134,7 +142,10 @@ int32 OS_ModuleLoad_Static(const char *ModuleName) if (StaticSym->Name == NULL) { /* end of list */ - break; + /* see comment in OS_SymbolLookup_Static regarding similar + * statement @author lukas.n.kebuladze@nasa.gov */ + StaticSym = NULL; + continue; } if (StaticSym->Module != NULL && strcmp(StaticSym->Module, ModuleName) == 0) { From a989eee0d0160e85e9b3d9bd8b9fa07aaa6757e0 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 25 Feb 2025 16:43:32 +0000 Subject: [PATCH 21/51] Fix cFS/osal#16, Add void keyword to function definitions --- src/os/posix/src/os-impl-tasks.c | 2 +- src/os/rtems/src/os-impl-common.c | 4 +-- src/os/rtems/src/os-impl-tasks.c | 2 +- src/os/shared/src/osapi-common.c | 2 +- src/os/shared/src/osapi-task.c | 2 +- src/os/vxworks/src/os-impl-tasks.c | 2 +- .../shared/src/coveragetest-task.c | 2 +- .../vxworks/src/coveragetest-common.c | 4 +-- .../vxworks/src/coveragetest-tasks.c | 2 +- src/unit-tests/README.md | 2 +- .../oscore-test/ut_oscore_binsem_test.c | 14 ++++---- .../oscore-test/ut_oscore_countsem_test.c | 12 +++---- .../oscore-test/ut_oscore_misc_test.c | 14 ++++---- .../oscore-test/ut_oscore_mutex_test.c | 12 +++---- .../oscore-test/ut_oscore_queue_test.c | 12 +++---- .../oscore-test/ut_oscore_task_test.c | 16 ++++----- src/unit-tests/oscore-test/ut_oscore_test.c | 22 ++++++------ .../osfile-test/ut_osfile_dirio_test.c | 12 +++---- .../osfile-test/ut_osfile_fileio_test.c | 36 +++++++++---------- src/unit-tests/osfile-test/ut_osfile_test.c | 4 +-- .../osfilesys-test/ut_osfilesys_diskio_test.c | 16 ++++----- .../osfilesys-test/ut_osfilesys_test.c | 2 +- .../osloader-test/ut_osloader_module_test.c | 6 ++-- .../osloader-test/ut_osloader_symtable_test.c | 6 ++-- .../osnetwork-test/ut_osnetwork_misc_test.c | 4 +-- src/unit-tests/ostimer-test/ut_ostimer_test.c | 12 +++---- .../ostimer-test/ut_ostimer_timerio_test.c | 12 +++---- 27 files changed, 118 insertions(+), 118 deletions(-) diff --git a/src/os/posix/src/os-impl-tasks.c b/src/os/posix/src/os-impl-tasks.c index f1dacf62a..c031b983e 100644 --- a/src/os/posix/src/os-impl-tasks.c +++ b/src/os/posix/src/os-impl-tasks.c @@ -707,7 +707,7 @@ int32 OS_TaskDelete_Impl(const OS_object_token_t *token) * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -void OS_TaskExit_Impl() +void OS_TaskExit_Impl(void) { pthread_exit(NULL); } diff --git a/src/os/rtems/src/os-impl-common.c b/src/os/rtems/src/os-impl-common.c index a148a7c19..0848bbdd7 100644 --- a/src/os/rtems/src/os-impl-common.c +++ b/src/os/rtems/src/os-impl-common.c @@ -106,7 +106,7 @@ int32 OS_API_Impl_Init(osal_objtype_t idtype) * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -void OS_IdleLoop_Impl() +void OS_IdleLoop_Impl(void) { RTEMS_GlobalVars.IdleTaskId = rtems_task_self(); rtems_task_suspend(RTEMS_SELF); @@ -118,7 +118,7 @@ void OS_IdleLoop_Impl() * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -void OS_ApplicationShutdown_Impl() +void OS_ApplicationShutdown_Impl(void) { /* Note that setting the IdleTaskId and suspending * the idle task is not an atomic operation, so there diff --git a/src/os/rtems/src/os-impl-tasks.c b/src/os/rtems/src/os-impl-tasks.c index 10e09943b..fb61e08c7 100644 --- a/src/os/rtems/src/os-impl-tasks.c +++ b/src/os/rtems/src/os-impl-tasks.c @@ -187,7 +187,7 @@ int32 OS_TaskDetach_Impl(const OS_object_token_t *token) * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -void OS_TaskExit_Impl() +void OS_TaskExit_Impl(void) { rtems_task_delete(RTEMS_SELF); } diff --git a/src/os/shared/src/osapi-common.c b/src/os/shared/src/osapi-common.c index c669ed594..0a25bdc75 100644 --- a/src/os/shared/src/osapi-common.c +++ b/src/os/shared/src/osapi-common.c @@ -390,7 +390,7 @@ void OS_DeleteAllObjects(void) * See description in API and header file for detail * *-----------------------------------------------------------------*/ -void OS_IdleLoop() +void OS_IdleLoop(void) { /* * Wait until the shutdown value is set to the shutdown number diff --git a/src/os/shared/src/osapi-task.c b/src/os/shared/src/osapi-task.c index 22b89512c..38ed13382 100644 --- a/src/os/shared/src/osapi-task.c +++ b/src/os/shared/src/osapi-task.c @@ -250,7 +250,7 @@ int32 OS_TaskDelete(osal_id_t task_id) * See description in API and header file for detail * *-----------------------------------------------------------------*/ -void OS_TaskExit() +void OS_TaskExit(void) { osal_id_t task_id; OS_object_token_t token; diff --git a/src/os/vxworks/src/os-impl-tasks.c b/src/os/vxworks/src/os-impl-tasks.c index 9e5eef498..fb9054e2e 100644 --- a/src/os/vxworks/src/os-impl-tasks.c +++ b/src/os/vxworks/src/os-impl-tasks.c @@ -296,7 +296,7 @@ int32 OS_TaskDetach_Impl(const OS_object_token_t *token) * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -void OS_TaskExit_Impl() +void OS_TaskExit_Impl(void) { taskExit(0); } diff --git a/src/unit-test-coverage/shared/src/coveragetest-task.c b/src/unit-test-coverage/shared/src/coveragetest-task.c index 02e75f463..3b3f1cee7 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-task.c +++ b/src/unit-test-coverage/shared/src/coveragetest-task.c @@ -159,7 +159,7 @@ void Test_OS_TaskExit(void) { /* * Test Case For: - * void OS_TaskExit() + * void OS_TaskExit(void) */ OS_TaskExit(); diff --git a/src/unit-test-coverage/vxworks/src/coveragetest-common.c b/src/unit-test-coverage/vxworks/src/coveragetest-common.c index e2a5f4c66..756448c1f 100644 --- a/src/unit-test-coverage/vxworks/src/coveragetest-common.c +++ b/src/unit-test-coverage/vxworks/src/coveragetest-common.c @@ -58,7 +58,7 @@ void Test_OS_IdleLoop_Impl(void) { /* * Test Case For: - * void OS_IdleLoop_Impl() + * void OS_IdleLoop_Impl(void) */ /* just call the function for coverage */ OS_IdleLoop_Impl(); @@ -68,7 +68,7 @@ void Test_OS_ApplicationShutdown_Impl(void) { /* * Test Case For: - * void OS_ApplicationShutdown_Impl() + * void OS_ApplicationShutdown_Impl(void) */ /* just call the function for coverage */ OS_ApplicationShutdown_Impl(); diff --git a/src/unit-test-coverage/vxworks/src/coveragetest-tasks.c b/src/unit-test-coverage/vxworks/src/coveragetest-tasks.c index 88b3baa54..780ed6807 100644 --- a/src/unit-test-coverage/vxworks/src/coveragetest-tasks.c +++ b/src/unit-test-coverage/vxworks/src/coveragetest-tasks.c @@ -153,7 +153,7 @@ void Test_OS_TaskExit_Impl(void) { /* * Test Case For: - * void OS_TaskExit_Impl() + * void OS_TaskExit_Impl(void) */ /* just call the function for coverage */ OS_TaskExit_Impl(); diff --git a/src/unit-tests/README.md b/src/unit-tests/README.md index 53b490ff0..8973f8a21 100644 --- a/src/unit-tests/README.md +++ b/src/unit-tests/README.md @@ -20,7 +20,7 @@ Use the following structure for your unit test cases: ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_somethingcreate() +void UT_os_somethingcreate(void) { int i; char name[UT_OS_NAME_BUFF_SIZE]; diff --git a/src/unit-tests/oscore-test/ut_oscore_binsem_test.c b/src/unit-tests/oscore-test/ut_oscore_binsem_test.c index e40f41dcb..d5a621e87 100644 --- a/src/unit-tests/oscore-test/ut_oscore_binsem_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_binsem_test.c @@ -63,7 +63,7 @@ ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_bin_sem_create_test() +void UT_os_bin_sem_create_test(void) { int i; char sem_name[UT_OS_NAME_BUFF_SIZE]; @@ -128,7 +128,7 @@ void UT_os_bin_sem_create_test() ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_bin_sem_delete_test() +void UT_os_bin_sem_delete_test(void) { osal_id_t bin_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -152,7 +152,7 @@ void UT_os_bin_sem_delete_test() ** array of semaphores defined by the system ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_bin_sem_flush_test() +void UT_os_bin_sem_flush_test(void) { osal_id_t bin_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -177,7 +177,7 @@ void UT_os_bin_sem_flush_test() ** array of semaphores defined by the system ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_bin_sem_give_test() +void UT_os_bin_sem_give_test(void) { osal_id_t bin_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -203,7 +203,7 @@ void UT_os_bin_sem_give_test() ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_bin_sem_take_test() +void UT_os_bin_sem_take_test(void) { osal_id_t bin_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -228,7 +228,7 @@ void UT_os_bin_sem_take_test() ** OS_SEM_TIMEOUT if the semaphore was not relinquished in time ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_bin_sem_timed_wait_test() +void UT_os_bin_sem_timed_wait_test(void) { osal_id_t bin_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -261,7 +261,7 @@ void UT_os_bin_sem_timed_wait_test() ** semaphore table ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_bin_sem_get_id_by_name_test() +void UT_os_bin_sem_get_id_by_name_test(void) { osal_id_t bin_sem_id = OS_OBJECT_ID_UNDEFINED; char long_sem_name[UT_OS_NAME_BUFF_SIZE]; diff --git a/src/unit-tests/oscore-test/ut_oscore_countsem_test.c b/src/unit-tests/oscore-test/ut_oscore_countsem_test.c index 8d9f8df4f..3f8c8bcfa 100644 --- a/src/unit-tests/oscore-test/ut_oscore_countsem_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_countsem_test.c @@ -63,7 +63,7 @@ ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_count_sem_create_test() +void UT_os_count_sem_create_test(void) { int i; osal_id_t count_sem_ids[OS_MAX_COUNT_SEMAPHORES + 1]; @@ -157,7 +157,7 @@ void UT_os_count_sem_create_test() ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_count_sem_delete_test() +void UT_os_count_sem_delete_test(void) { osal_id_t count_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -186,7 +186,7 @@ void UT_os_count_sem_delete_test() ** array of semaphores defined by the system ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_count_sem_give_test() +void UT_os_count_sem_give_test(void) { osal_id_t count_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -217,7 +217,7 @@ void UT_os_count_sem_give_test() ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_count_sem_take_test() +void UT_os_count_sem_take_test(void) { osal_id_t count_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -247,7 +247,7 @@ void UT_os_count_sem_take_test() ** OS_SEM_TIMEOUT if the semaphore was not relinquished in time ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_count_sem_timed_wait_test() +void UT_os_count_sem_timed_wait_test(void) { osal_id_t count_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -291,7 +291,7 @@ void UT_os_count_sem_timed_wait_test() ** semaphore table ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_count_sem_get_id_by_name_test() +void UT_os_count_sem_get_id_by_name_test(void) { osal_id_t count_sem_id = OS_OBJECT_ID_UNDEFINED; char long_sem_name[UT_OS_NAME_BUFF_SIZE]; diff --git a/src/unit-tests/oscore-test/ut_oscore_misc_test.c b/src/unit-tests/oscore-test/ut_oscore_misc_test.c index 00ebc160e..0dd7e787b 100644 --- a/src/unit-tests/oscore-test/ut_oscore_misc_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_misc_test.c @@ -84,7 +84,7 @@ ** 4) Expect the returned value from those routines to be ** (a) OS_SUCCESS *--------------------------------------------------------------------------------*/ -void UT_os_apiinit_test() +void UT_os_apiinit_test(void) { osal_id_t qId = OS_OBJECT_ID_UNDEFINED; osal_blockcount_t qDepth = OSAL_BLOCKCOUNT_C(10); @@ -135,7 +135,7 @@ int32 UT_os_eventhandler(OS_Event_t event, osal_id_t object_id, void *data) return OS_SUCCESS; } -void UT_os_registereventhandler_test() +void UT_os_registereventhandler_test(void) { /*-----------------------------------------------------*/ /* #1 Null-pointer-arg */ @@ -158,7 +158,7 @@ void UT_os_registereventhandler_test() ** 2) Call this routine to print a text string. ** 3) Visually observe that the text string in #2 did get print. **--------------------------------------------------------------------------------*/ -void UT_os_printf_test() +void UT_os_printf_test(void) { OS_printf_enable(); UT_MIR_VOID(OS_printf("OS_printf() - #1 Nominal [This is the expected stdout output after API call]\n")); @@ -176,7 +176,7 @@ void UT_os_printf_test() ** 4) Call OS_printf to print a text string that's different than #2 ** 5) Visually observe that text string in #2 did not print, but text string in #4 did. **--------------------------------------------------------------------------------*/ -void UT_os_printfenable_test() +void UT_os_printfenable_test(void) { OS_printf_disable(); @@ -196,7 +196,7 @@ void UT_os_printfenable_test() ** 4) Call OS_printf() to print a text string that's different than #2 ** 5) Visually observe that text string in #2 did get print, but text string in #4 did not. **--------------------------------------------------------------------------------*/ -void UT_os_printfdisable_test() +void UT_os_printfdisable_test(void) { OS_printf_enable(); UT_MIR_VOID(OS_printf("OS_printf_disable() - #1 Nominal [This is the expected stdout output before API call]\n")); @@ -241,7 +241,7 @@ void UT_os_printfdisable_test() ** 2) Expect the returned value to be ** (a) OS_SUCCESS (although results are not directly observable) **--------------------------------------------------------------------------------*/ -void UT_os_getlocaltime_test() +void UT_os_getlocaltime_test(void) { OS_time_t time_struct; int32 i = 0; @@ -307,7 +307,7 @@ void UT_os_getlocaltime_test() ** - Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_setlocaltime_test() +void UT_os_setlocaltime_test(void) { OS_time_t time_struct; int32 i = 0; diff --git a/src/unit-tests/oscore-test/ut_oscore_mutex_test.c b/src/unit-tests/oscore-test/ut_oscore_mutex_test.c index 62ebd5207..5f2f64c07 100644 --- a/src/unit-tests/oscore-test/ut_oscore_mutex_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_mutex_test.c @@ -63,7 +63,7 @@ ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_mut_sem_create_test() +void UT_os_mut_sem_create_test(void) { int i; osal_id_t mut_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -139,7 +139,7 @@ void UT_os_mut_sem_create_test() ** OS_SEM_FAILURE if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_mut_sem_delete_test() +void UT_os_mut_sem_delete_test(void) { osal_id_t mut_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -167,7 +167,7 @@ void UT_os_mut_sem_delete_test() ** array of semaphores defined by the system ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_mut_sem_give_test() +void UT_os_mut_sem_give_test(void) { osal_id_t mut_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -200,7 +200,7 @@ void UT_os_mut_sem_give_test() ** array of semaphores defined by the system ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_mut_sem_take_test() +void UT_os_mut_sem_take_test(void) { osal_id_t mut_sem_id = OS_OBJECT_ID_UNDEFINED; @@ -231,7 +231,7 @@ void UT_os_mut_sem_take_test() ** OS_ERR_NAME_NOT_FOUND if the name was not found in the mutex semaphore table ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_mut_sem_get_id_by_name_test() +void UT_os_mut_sem_get_id_by_name_test(void) { osal_id_t mut_sem_id = OS_OBJECT_ID_UNDEFINED; char long_sem_name[UT_OS_NAME_BUFF_SIZE]; @@ -276,7 +276,7 @@ void UT_os_mut_sem_get_id_by_name_test() ** OS_ERR_INVALID_ID if the id passed in is not a valid binary semaphore id ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_mut_sem_get_info_test() +void UT_os_mut_sem_get_info_test(void) { osal_id_t mut_sem_id = OS_OBJECT_ID_UNDEFINED; OS_mut_sem_prop_t mut_sem_prop; diff --git a/src/unit-tests/oscore-test/ut_oscore_queue_test.c b/src/unit-tests/oscore-test/ut_oscore_queue_test.c index 0d858dc66..1ac72c82e 100644 --- a/src/unit-tests/oscore-test/ut_oscore_queue_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_queue_test.c @@ -67,7 +67,7 @@ ** OS_ERROR if the OS create call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_queue_create_test() +void UT_os_queue_create_test(void) { int i = 0; osal_id_t queue_id = OS_OBJECT_ID_UNDEFINED; @@ -151,7 +151,7 @@ void UT_os_queue_create_test() ** OS_ERROR if the OS call to delete the queue failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_queue_delete_test() +void UT_os_queue_delete_test(void) { osal_id_t queue_id = OS_OBJECT_ID_UNDEFINED; @@ -181,7 +181,7 @@ void UT_os_queue_delete_test() ** OS_QUEUE_INVALID_SIZE if the size copied from the queue is incorrect ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_queue_get_test() +void UT_os_queue_get_test(void) { osal_id_t queue_id = OS_OBJECT_ID_UNDEFINED; uint32 queue_data_out; @@ -296,7 +296,7 @@ void UT_os_queue_get_test() ** OS_ERROR if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_queue_put_test() +void UT_os_queue_put_test(void) { osal_id_t queue_id = OS_OBJECT_ID_UNDEFINED; uint32 queue_data_out = 0; @@ -362,7 +362,7 @@ void UT_os_queue_put_test() ** OS_ERR_NAME_NOT_FOUND if the name was not found in the queue table ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_queue_get_id_by_name_test() +void UT_os_queue_get_id_by_name_test(void) { osal_id_t queue_id = OS_OBJECT_ID_UNDEFINED; char long_queue_name[UT_OS_NAME_BUFF_SIZE]; @@ -408,7 +408,7 @@ void UT_os_queue_get_id_by_name_test() ** OS_ERR_INVALID_ID if the id passed in does not exist ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_queue_get_info_test() +void UT_os_queue_get_info_test(void) { osal_id_t queue_id = OS_OBJECT_ID_UNDEFINED; OS_queue_prop_t queue_prop; diff --git a/src/unit-tests/oscore-test/ut_oscore_task_test.c b/src/unit-tests/oscore-test/ut_oscore_task_test.c index 71f5369ce..9ab6b0248 100644 --- a/src/unit-tests/oscore-test/ut_oscore_task_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_task_test.c @@ -102,7 +102,7 @@ void generic_test_task(void) ** OS_ERROR if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_task_create_test() +void UT_os_task_create_test(void) { int32 i = 0; char task_name[UT_OS_NAME_BUFF_SIZE]; @@ -217,7 +217,7 @@ void UT_os_task_create_test() ** OS_ERROR if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_task_delete_test() +void UT_os_task_delete_test(void) { /*-----------------------------------------------------*/ /* #1 Invalid-ID-arg */ @@ -390,7 +390,7 @@ void UT_os_task_exit_test(void) ** Returns: OS_ERROR if sleep failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_task_delay_test() +void UT_os_task_delay_test(void) { OS_time_t before_time; OS_time_t after_time; @@ -434,7 +434,7 @@ void UT_os_task_delay_test() ** OS_ERROR if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_task_set_priority_test() +void UT_os_task_set_priority_test(void) { /*-----------------------------------------------------*/ /* #1 Invalid-ID-arg */ @@ -481,7 +481,7 @@ void getid_test_task(void) ** Parameters: To-be-filled-in ** Returns: Task id of the task that calls this routine **--------------------------------------------------------------------------------*/ -void UT_os_task_get_id_test() +void UT_os_task_get_id_test(void) { /* * Note this function does not return a normal status code, @@ -512,7 +512,7 @@ void UT_os_task_get_id_test() ** OS_ERR_NAME_NOT_FOUND if the name passed in is not in the task table ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_task_get_id_by_name_test() +void UT_os_task_get_id_by_name_test(void) { /*-----------------------------------------------------*/ /* #1 Invalid-pointer-arg-1 */ @@ -559,7 +559,7 @@ void UT_os_task_get_id_by_name_test() ** OS_ERR_INVALID_ID if the id passed in is not a valid task id ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_task_get_info_test() +void UT_os_task_get_info_test(void) { OS_task_prop_t task_prop; @@ -605,7 +605,7 @@ void UT_os_task_get_info_test() ** Syntax: OS_TaskFindIdBySystemData ** Purpose: Finds the abstract OSAL task ID from the system ID data **--------------------------------------------------------------------------------*/ -void UT_os_task_getid_by_sysdata_test() +void UT_os_task_getid_by_sysdata_test(void) { uint8 sysdata = 0; osal_id_t task_id; diff --git a/src/unit-tests/oscore-test/ut_oscore_test.c b/src/unit-tests/oscore-test/ut_oscore_test.c index 5cf5afc0f..7fbe57b23 100644 --- a/src/unit-tests/oscore-test/ut_oscore_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_test.c @@ -71,7 +71,7 @@ void UT_os_init_task_get_info_test(void); ** Local function definitions **--------------------------------------------------------------------------------*/ -void UT_os_init_task_misc() +void UT_os_init_task_misc(void) { memset(g_long_task_name, 'X', sizeof(g_long_task_name)); g_long_task_name[sizeof(g_long_task_name) - 1] = '\0'; @@ -79,7 +79,7 @@ void UT_os_init_task_misc() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_create_test() +void UT_os_init_task_create_test(void) { g_task_names[0] = "Create_NotImpl"; g_task_names[1] = "Create_NullPtr1"; @@ -95,7 +95,7 @@ void UT_os_init_task_create_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_delete_test() +void UT_os_init_task_delete_test(void) { g_task_names[0] = "Delete_NotImpl"; g_task_names[1] = "Delete_InvArg"; @@ -105,7 +105,7 @@ void UT_os_init_task_delete_test() /*--------------------------------------------------------------------------------*/ -void UT_os_setup_install_delete_handler_test() +void UT_os_setup_install_delete_handler_test(void) { g_task_names[0] = "DelHandler_NotImpl"; g_task_names[1] = "DelHandler_InvArg"; @@ -114,7 +114,7 @@ void UT_os_setup_install_delete_handler_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_exit_test() +void UT_os_init_task_exit_test(void) { g_task_names[0] = "Exit_NotImpl"; g_task_names[1] = "Exit_Nominal"; @@ -122,7 +122,7 @@ void UT_os_init_task_exit_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_delay_test() +void UT_os_init_task_delay_test(void) { g_task_names[0] = "Delay_NotImpl"; g_task_names[1] = "Delay_OsErr"; @@ -131,7 +131,7 @@ void UT_os_init_task_delay_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_set_priority_test() +void UT_os_init_task_set_priority_test(void) { g_task_names[0] = "SetPrio_NotImpl"; g_task_names[1] = "SetPrio_InvArg"; @@ -142,7 +142,7 @@ void UT_os_init_task_set_priority_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_register_test() +void UT_os_init_task_register_test(void) { g_task_names[0] = "Register_NotImpl"; g_task_names[1] = "Register_InvArg"; @@ -152,7 +152,7 @@ void UT_os_init_task_register_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_get_id_test() +void UT_os_init_task_get_id_test(void) { g_task_names[0] = "GetId_NotImpl"; g_task_names[1] = "GetId_Nominal"; @@ -160,7 +160,7 @@ void UT_os_init_task_get_id_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_get_id_by_name_test() +void UT_os_init_task_get_id_by_name_test(void) { g_task_names[0] = "GetIdByName_NotImpl"; g_task_names[1] = "GetIdByName_InvPtr1"; @@ -172,7 +172,7 @@ void UT_os_init_task_get_id_by_name_test() /*--------------------------------------------------------------------------------*/ -void UT_os_init_task_get_info_test() +void UT_os_init_task_get_info_test(void) { g_task_names[0] = "GetInfo_NotImpl"; g_task_names[1] = "GetInfo_InvId"; diff --git a/src/unit-tests/osfile-test/ut_osfile_dirio_test.c b/src/unit-tests/osfile-test/ut_osfile_dirio_test.c index 17c452a05..4aee500b2 100644 --- a/src/unit-tests/osfile-test/ut_osfile_dirio_test.c +++ b/src/unit-tests/osfile-test/ut_osfile_dirio_test.c @@ -122,7 +122,7 @@ void UT_os_read_n_sort_dirs(osal_id_t); ** 4) Expect the returned value to be ** (a) a file descriptor value greater than or equal to 0 **--------------------------------------------------------------------------------*/ -void UT_os_makedir_test() +void UT_os_makedir_test(void) { osal_id_t fileDesc = OS_OBJECT_ID_UNDEFINED; @@ -203,7 +203,7 @@ void UT_os_makedir_test() ** 4) Expect the returned value to be ** (a) a directory descriptor pointer that is __not__ NULL **--------------------------------------------------------------------------------*/ -void UT_os_opendir_test() +void UT_os_opendir_test(void) { osal_id_t dirh = OS_OBJECT_ID_UNDEFINED; @@ -276,7 +276,7 @@ void UT_os_opendir_test() ** 7) Call OS_DirectoryRead() with the directory descriptor pointer returned in #3 as argument ** 8) Expect to not get OS_SUCCESS (closed directory) **--------------------------------------------------------------------------------*/ -void UT_os_closedir_test() +void UT_os_closedir_test(void) { osal_id_t dirh = OS_OBJECT_ID_UNDEFINED; os_dirent_t dirEntry; @@ -345,7 +345,7 @@ void UT_os_closedir_test() ** (a) a directory entry pointer __and__ ** (b) the directory name to be ".." **--------------------------------------------------------------------------------*/ -void UT_os_readdir_test() +void UT_os_readdir_test(void) { osal_id_t dirh = OS_OBJECT_ID_UNDEFINED; os_dirent_t dirent; @@ -438,7 +438,7 @@ void UT_os_readdir_test() ** (a) a directory entry pointer __and__ ** (b) the directory name to be "." **--------------------------------------------------------------------------------*/ -void UT_os_rewinddir_test() +void UT_os_rewinddir_test(void) { osal_id_t dirh = OS_OBJECT_ID_UNDEFINED; @@ -541,7 +541,7 @@ void UT_os_rewinddir_test() ** 10) Expect the returned value to be ** (a) a file descriptor value less than 0 **--------------------------------------------------------------------------------*/ -void UT_os_removedir_test() +void UT_os_removedir_test(void) { osal_id_t fileDesc = OS_OBJECT_ID_UNDEFINED; diff --git a/src/unit-tests/osfile-test/ut_osfile_fileio_test.c b/src/unit-tests/osfile-test/ut_osfile_fileio_test.c index 9a8050228..8fc51767e 100644 --- a/src/unit-tests/osfile-test/ut_osfile_fileio_test.c +++ b/src/unit-tests/osfile-test/ut_osfile_fileio_test.c @@ -101,7 +101,7 @@ char g_writeBuff[UT_OS_IO_BUFF_SIZE]; ** 4) Expect the returned value from those routines to be ** (a) OS_SUCCESS *--------------------------------------------------------------------------------*/ -void UT_os_initfs_test() +void UT_os_initfs_test(void) { UT_NOMINAL(OS_API_Init()); } @@ -165,7 +165,7 @@ void UT_os_initfs_test() ** 6) Expect both returned values to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_createfile_test() +void UT_os_createfile_test(void) { int32 i = 0, j = 0; osal_id_t fd; @@ -302,7 +302,7 @@ void UT_os_createfile_test() ** 6) Expect both returned values to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_openfile_test() +void UT_os_openfile_test(void) { int32 i = 0, j = 0; osal_id_t fd; @@ -445,7 +445,7 @@ void UT_os_openfile_test() ** 6) Expect both returned value to be ** (a) OS_ERR_INVALID_ID **--------------------------------------------------------------------------------*/ -void UT_os_closefile_test() +void UT_os_closefile_test(void) { char tmpBuff[UT_OS_IO_BUFF_SIZE]; @@ -526,7 +526,7 @@ void UT_os_closefile_test() ** (a) the number of bytes read that is equal to the number of bytes written in #3 __and__ ** (b) the read buffer content is the same as the write buffer content in #3 **--------------------------------------------------------------------------------*/ -void UT_os_readfile_test() +void UT_os_readfile_test(void) { size_t expected_len; @@ -634,7 +634,7 @@ void UT_os_readfile_test() ** (a) the number of bytes read that is equal to the number of bytes written in #3 __and__ ** (b) the read buffer content is the same as the write buffer content in #3 **--------------------------------------------------------------------------------*/ -void UT_os_writefile_test() +void UT_os_writefile_test(void) { size_t expected_len; @@ -739,7 +739,7 @@ void UT_os_writefile_test() ** 6) Expect the returned value each time to be ** (a) the expected file position value given the arguments **--------------------------------------------------------------------------------*/ -void UT_os_lseekfile_test() +void UT_os_lseekfile_test(void) { size_t buffLen; int32 pos1 = 0, pos2 = 0, pos3 = 0; @@ -797,7 +797,7 @@ void UT_os_lseekfile_test() ** 2) If the returned value is OS_ERR_NOT_IMPLEMENTED, then exit test ** 3) Otherwise, continue **--------------------------------------------------------------------------------*/ -void UT_os_chmodfile_test() +void UT_os_chmodfile_test(void) { UT_RETVAL(OS_chmod(NULL, OS_READ_WRITE), OS_INVALID_POINTER); @@ -876,7 +876,7 @@ void UT_os_chmodfile_test() ** (a) OS_SUCCESS __and__ ** (b) fstats1 returned in #3 and fstats2 returned in #9 to be not equal **--------------------------------------------------------------------------------*/ -void UT_os_statfile_test() +void UT_os_statfile_test(void) { os_fstat_t fstats1; os_fstat_t fstats2; @@ -980,7 +980,7 @@ void UT_os_statfile_test() ** 6) Expect the returned values to be ** (a) OS_ERROR **--------------------------------------------------------------------------------*/ -void UT_os_removefile_test() +void UT_os_removefile_test(void) { os_fstat_t fstats; @@ -1077,7 +1077,7 @@ void UT_os_removefile_test() ** 6) Expect the returned values to be ** (a) OS_ERROR **--------------------------------------------------------------------------------*/ -void UT_os_renamefile_test() +void UT_os_renamefile_test(void) { os_fstat_t fstats; @@ -1192,7 +1192,7 @@ void UT_os_renamefile_test() ** 8) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_copyfile_test() +void UT_os_copyfile_test(void) { os_fstat_t fstats; @@ -1316,7 +1316,7 @@ void UT_os_copyfile_test() ** 10) Expect the returned value to be ** (a) not OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_movefile_test() +void UT_os_movefile_test(void) { os_fstat_t fstats; @@ -1428,7 +1428,7 @@ void UT_os_movefile_test() ** (a) number of bytes greater than 0 __and__ ** (b) the read string is the same as the string returned from getevn("HOME") call **--------------------------------------------------------------------------------*/ -void UT_os_outputtofile_test() +void UT_os_outputtofile_test(void) { /*-----------------------------------------------------*/ /* #2 Invalid-file-desc-arg */ @@ -1521,7 +1521,7 @@ void UT_os_outputtofile_test() ** 8) Expect the returned value to be ** (a) OS_ERR_INVALID_ID **--------------------------------------------------------------------------------*/ -void UT_os_getfdinfo_test() +void UT_os_getfdinfo_test(void) { OS_file_prop_t fdProps; const char * fileName = "GetInfo_Nom.txt"; @@ -1594,7 +1594,7 @@ void UT_os_getfdinfo_test() ** 4) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_checkfileopen_test() +void UT_os_checkfileopen_test(void) { /*-----------------------------------------------------*/ /* #1 Null-pointer-arg */ @@ -1655,7 +1655,7 @@ void UT_os_checkfileopen_test() ** 6) Expect all returned values to be ** (a) OS_ERROR **--------------------------------------------------------------------------------*/ -void UT_os_closeallfiles_test() +void UT_os_closeallfiles_test(void) { /*-----------------------------------------------------*/ /* #2 Nominal */ @@ -1731,7 +1731,7 @@ void UT_os_closeallfiles_test() ** 6) Expect the returned value to be ** (a) OS_ERROR **--------------------------------------------------------------------------------*/ -void UT_os_closefilebyname_test() +void UT_os_closefilebyname_test(void) { /*-----------------------------------------------------*/ /* #1 Null-pointer-arg */ diff --git a/src/unit-tests/osfile-test/ut_osfile_test.c b/src/unit-tests/osfile-test/ut_osfile_test.c index d5231b780..0f19083ac 100644 --- a/src/unit-tests/osfile-test/ut_osfile_test.c +++ b/src/unit-tests/osfile-test/ut_osfile_test.c @@ -94,7 +94,7 @@ int32 UT_os_setup_fs() /*--------------------------------------------------------------------------------*/ -void UT_os_teardown_fs() +void UT_os_teardown_fs(void) { OS_unmount(g_mntName); OS_rmfs(g_devName); @@ -102,7 +102,7 @@ void UT_os_teardown_fs() /*--------------------------------------------------------------------------------*/ -void UT_os_init_file_misc() +void UT_os_init_file_misc(void) { memset(g_longPathName, 'Y', sizeof(g_longPathName)); g_longPathName[0] = '/'; diff --git a/src/unit-tests/osfilesys-test/ut_osfilesys_diskio_test.c b/src/unit-tests/osfilesys-test/ut_osfilesys_diskio_test.c index 36106e888..50c8d3d3f 100644 --- a/src/unit-tests/osfilesys-test/ut_osfilesys_diskio_test.c +++ b/src/unit-tests/osfilesys-test/ut_osfilesys_diskio_test.c @@ -121,7 +121,7 @@ extern char g_mntNames[UT_OS_FILESYS_LIST_LEN][UT_OS_FILE_BUFF_SIZE]; ** 5) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_initfs_test() +void UT_os_initfs_test(void) { int32 i = 0, j = 0; @@ -236,7 +236,7 @@ void UT_os_initfs_test() ** 5) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_makefs_test() +void UT_os_makefs_test(void) { int32 i = 0, j = 0; @@ -333,7 +333,7 @@ void UT_os_makefs_test() ** 6) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_removefs_test() +void UT_os_removefs_test(void) { /*-----------------------------------------------------*/ /* API not implemented */ @@ -409,7 +409,7 @@ void UT_os_removefs_test() ** 8) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_mount_test() +void UT_os_mount_test(void) { /*-----------------------------------------------------*/ /* API not implemented */ @@ -494,7 +494,7 @@ void UT_os_mount_test() ** 8) Expect the returned value to be ** (a) OS_ERR_NAME_NOT_FOUND **--------------------------------------------------------------------------------*/ -void UT_os_unmount_test() +void UT_os_unmount_test(void) { /*-----------------------------------------------------*/ /* API not implemented */ @@ -581,7 +581,7 @@ void UT_os_unmount_test() ** 6) Expect the returned value to be ** (a) OS_SUCCESS ** --------------------------------------------------------------------------------*/ -void UT_os_getphysdrivename_test() +void UT_os_getphysdrivename_test(void) { char physDevName[UT_OS_PHYS_NAME_BUFF_SIZE]; @@ -721,7 +721,7 @@ void UT_os_getfsinfo_test(void) ** (a) OS_SUCCESS __and__ ** (b) the returned local path to be ? ** --------------------------------------------------------------------------------*/ -void UT_os_translatepath_test() +void UT_os_translatepath_test(void) { char localPath[UT_OS_LOCAL_PATH_BUFF_SIZE]; char virtPath[OS_MAX_PATH_LEN]; @@ -807,7 +807,7 @@ void UT_os_translatepath_test() ** Test #4: Nominal condition ** 1) Currently only applicable to vxworks platform ** --------------------------------------------------------------------------------*/ -void UT_os_checkfs_test() +void UT_os_checkfs_test(void) { char driveName[UT_OS_PATH_BUFF_SIZE]; diff --git a/src/unit-tests/osfilesys-test/ut_osfilesys_test.c b/src/unit-tests/osfilesys-test/ut_osfilesys_test.c index 7921c40f8..5c586b8ac 100644 --- a/src/unit-tests/osfilesys-test/ut_osfilesys_test.c +++ b/src/unit-tests/osfilesys-test/ut_osfilesys_test.c @@ -69,7 +69,7 @@ void UT_os_init_fs_misc(void); ** Local function definitions **--------------------------------------------------------------------------------*/ -void UT_os_init_fs_misc() +void UT_os_init_fs_misc(void) { memset(g_fsLongName, 'X', sizeof(g_fsLongName)); g_fsLongName[0] = '/'; diff --git a/src/unit-tests/osloader-test/ut_osloader_module_test.c b/src/unit-tests/osloader-test/ut_osloader_module_test.c index 99863af52..c8cfb8150 100644 --- a/src/unit-tests/osloader-test/ut_osloader_module_test.c +++ b/src/unit-tests/osloader-test/ut_osloader_module_test.c @@ -63,7 +63,7 @@ ** OS_ERROR if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_module_load_test() +void UT_os_module_load_test(void) { int i; osal_id_t module_id = OS_OBJECT_ID_UNDEFINED; @@ -167,7 +167,7 @@ void UT_os_module_load_test() ** OS_ERROR if the OS call failed ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_module_unload_test() +void UT_os_module_unload_test(void) { osal_id_t module_id = OS_OBJECT_ID_UNDEFINED; @@ -206,7 +206,7 @@ void UT_os_module_unload_test() ** OS_ERR_INVALID_ID if the id passed in is not a valid module id ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_module_info_test() +void UT_os_module_info_test(void) { osal_id_t module_id = OS_OBJECT_ID_UNDEFINED; OS_module_prop_t module_info; diff --git a/src/unit-tests/osloader-test/ut_osloader_symtable_test.c b/src/unit-tests/osloader-test/ut_osloader_symtable_test.c index 4f1b6f72a..91d2f2a55 100644 --- a/src/unit-tests/osloader-test/ut_osloader_symtable_test.c +++ b/src/unit-tests/osloader-test/ut_osloader_symtable_test.c @@ -70,7 +70,7 @@ ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_symbol_lookup_test() +void UT_os_symbol_lookup_test(void) { cpuaddr symbol_addr; osal_id_t module_id = OS_OBJECT_ID_UNDEFINED; @@ -134,7 +134,7 @@ void UT_os_symbol_lookup_test() ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_module_symbol_lookup_test() +void UT_os_module_symbol_lookup_test(void) { cpuaddr symbol_addr; osal_id_t module_id = OS_OBJECT_ID_UNDEFINED; @@ -186,7 +186,7 @@ void UT_os_module_symbol_lookup_test() ** OS_ERROR if there was any problem writing the symbol table to the file ** OS_SUCCESS if succeeded **--------------------------------------------------------------------------------*/ -void UT_os_symbol_table_dump_test() +void UT_os_symbol_table_dump_test(void) { int32 status; /* diff --git a/src/unit-tests/osnetwork-test/ut_osnetwork_misc_test.c b/src/unit-tests/osnetwork-test/ut_osnetwork_misc_test.c index 0455db70b..aa681dfde 100644 --- a/src/unit-tests/osnetwork-test/ut_osnetwork_misc_test.c +++ b/src/unit-tests/osnetwork-test/ut_osnetwork_misc_test.c @@ -76,7 +76,7 @@ ** (a) OS_ERR_NOT_IMPLEMENTED __or__ ** (b) host id of value greater than 0 **--------------------------------------------------------------------------------*/ -void UT_os_networkgetid_test() +void UT_os_networkgetid_test(void) { /*-----------------------------------------------------*/ /* API Not implemented */ @@ -133,7 +133,7 @@ void UT_os_networkgetid_test() ** (a) OS_SUCCESS, _and_ ** (b) the returned buffer to be non-empty **--------------------------------------------------------------------------------*/ -void UT_os_networkgethostname_test() +void UT_os_networkgethostname_test(void) { char buffer[UT_OS_IO_BUFF_SIZE]; diff --git a/src/unit-tests/ostimer-test/ut_ostimer_test.c b/src/unit-tests/ostimer-test/ut_ostimer_test.c index 0ee3e4f50..c1260af0b 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_test.c @@ -115,7 +115,7 @@ void UT_os_timercallback(osal_id_t timerId) /*--------------------------------------------------------------------------------*/ -void UT_os_init_timer_misc() +void UT_os_init_timer_misc(void) { memset(g_longTimerName, 'Y', sizeof(g_longTimerName)); g_longTimerName[sizeof(g_longTimerName) - 1] = '\0'; @@ -123,7 +123,7 @@ void UT_os_init_timer_misc() /*--------------------------------------------------------------------------------*/ -void UT_os_setup_timercreate_test() +void UT_os_setup_timercreate_test(void) { memset(g_longTimerName, 'Y', sizeof(g_longTimerName)); g_longTimerName[sizeof(g_longTimerName) - 1] = '\0'; @@ -140,7 +140,7 @@ void UT_os_setup_timercreate_test() /*--------------------------------------------------------------------------------*/ -void UT_os_setup_timerdelete_test() +void UT_os_setup_timerdelete_test(void) { g_timerNames[0] = "Delete_NotImpl"; g_timerNames[1] = "Delete_InvArg"; @@ -150,7 +150,7 @@ void UT_os_setup_timerdelete_test() /*--------------------------------------------------------------------------------*/ -void UT_os_setup_timergetidbyname_test() +void UT_os_setup_timergetidbyname_test(void) { g_timerNames[0] = "GetId_NotImpl"; g_timerNames[1] = "GetId_NullPtr"; @@ -161,7 +161,7 @@ void UT_os_setup_timergetidbyname_test() /*--------------------------------------------------------------------------------*/ -void UT_os_setup_timergetinfo_test() +void UT_os_setup_timergetinfo_test(void) { g_timerNames[0] = "GetInfo_NotImpl"; g_timerNames[1] = "GetInfo_NullPtr"; @@ -171,7 +171,7 @@ void UT_os_setup_timergetinfo_test() /*--------------------------------------------------------------------------------*/ -void UT_os_setup_timerset_test() +void UT_os_setup_timerset_test(void) { g_timerNames[0] = "Set_NotImpl"; g_timerNames[1] = "Set_InvArg"; diff --git a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c b/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c index a6bea2528..3314772a0 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c @@ -168,7 +168,7 @@ void UT_os_reconftimercallback(osal_id_t timerId, void *arg) ** 6) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_timercreate_test() +void UT_os_timercreate_test(void) { int32 i = 0, j = 0; char tmpStr[UT_OS_NAME_BUFF_SIZE]; @@ -251,7 +251,7 @@ void UT_os_timercreate_test() ** Test case to confirm that attempts to (re-)configure a timer from the context ** of a callback function should fail with OS_ERR_INCORRECT_OBJ_STATE **--------------------------------------------------------------------------------*/ -void UT_os_timerreconf_test() +void UT_os_timerreconf_test(void) { UT_reconf_status_t reconf; @@ -323,7 +323,7 @@ void UT_os_timerreconf_test() ** 8) Expect the returned value to be ** (a) OS_SUCCESS **--------------------------------------------------------------------------------*/ -void UT_os_timerdelete_test() +void UT_os_timerdelete_test(void) { /*-----------------------------------------------------*/ /* #1 Invalid-id-arg */ @@ -399,7 +399,7 @@ void UT_os_timerdelete_test() ** is within +/- 5% of the set interval time ** 5) Exit test when the timer callback registered in #1 gets call 10 times **--------------------------------------------------------------------------------*/ -void UT_os_timerset_test() +void UT_os_timerset_test(void) { uint32 startTime = 0, intervalTime = 0; @@ -513,7 +513,7 @@ void UT_os_timerset_test() ** (a) OS_SUCCESS __and__ ** (b) the returned timer id is the same as the timer id returned in #1 **--------------------------------------------------------------------------------*/ -void UT_os_timergetidbyname_test() +void UT_os_timergetidbyname_test(void) { /*-----------------------------------------------------*/ /* #1 Null-pointer-arg */ @@ -583,7 +583,7 @@ void UT_os_timergetidbyname_test() ** (a) OS_SUCCESS __and__ ** (b) timer name returned for timer properties is the same as timer name used in #1 **--------------------------------------------------------------------------------*/ -void UT_os_timergetinfo_test() +void UT_os_timergetinfo_test(void) { OS_timer_prop_t timerProps; From 851ebfd71031b9320c699b4a3d2d1e91a75c52d7 Mon Sep 17 00:00:00 2001 From: Adams Date: Wed, 26 Feb 2025 08:58:41 -0600 Subject: [PATCH 22/51] Fix #33, Update Coverage Level --- .github/workflows/standalone-build-internal.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/standalone-build-internal.yml b/.github/workflows/standalone-build-internal.yml index 66cf1dad0..305235299 100644 --- a/.github/workflows/standalone-build-internal.yml +++ b/.github/workflows/standalone-build-internal.yml @@ -10,7 +10,7 @@ defaults: env: allowed_ncov_lines: 0 - allowed_ncov_branches: 2 + allowed_ncov_branches: 0 allowed_ncov_functions: 0 jobs: From fca9748a684e86ec991a4907441a2231b73d7797 Mon Sep 17 00:00:00 2001 From: Anh D Van Date: Fri, 14 Feb 2025 18:22:06 +0000 Subject: [PATCH 23/51] Fix #24, Address Sanitizer Issue in Osal Core Test Fix #24, add placeholder in TestTaskData structure to let the task_stack be 64bits aligned. --- src/tests/osal-core-test/osal-core-test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/osal-core-test/osal-core-test.c b/src/tests/osal-core-test/osal-core-test.c index 846312095..e22680d9f 100644 --- a/src/tests/osal-core-test/osal-core-test.c +++ b/src/tests/osal-core-test/osal-core-test.c @@ -148,6 +148,8 @@ void task_test_stackptr_0(void) typedef struct { osal_id_t task_id; + uint32 Padding; + uint64 Placholder; /* Used to align task_stack */ uint32 task_stack[TASK_0_STACK_SIZE]; } TestTaskData; From 40fe0a419029938fbe39749159d742c123d17268 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 4 Mar 2025 09:07:38 -0500 Subject: [PATCH 24/51] Fix #37, revise timer test logic to be more reliable The timer test logic was relying on undefined/non-guaranteed behavior in that it was programming an interval that was too short (5us) and expecting a certain result. --- src/unit-tests/ostimer-test/ut_ostimer_test.c | 78 ++++++++++--------- src/unit-tests/ostimer-test/ut_ostimer_test.h | 28 +++++-- .../ostimer-test/ut_ostimer_timerio_test.c | 71 ++++++++++++----- 3 files changed, 116 insertions(+), 61 deletions(-) diff --git a/src/unit-tests/ostimer-test/ut_ostimer_test.c b/src/unit-tests/ostimer-test/ut_ostimer_test.c index c1260af0b..7cec5f440 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_test.c @@ -47,11 +47,9 @@ const char *g_timerNames[UT_OS_TIMER_LIST_LEN]; char g_longTimerName[UT_OS_NAME_BUFF_SIZE]; -uint32 g_cbLoopCntMax = 5; -uint32 g_toleranceVal = 0; -uint32 g_timerFirst = 0; -int32 g_status = 0; -osal_id_t g_timerId; +volatile UT_TimerGlobal_t g_timerGlobal; + +int deltatimes[25]; /*--------------------------------------------------------------------------------* ** Local function prototypes @@ -72,43 +70,53 @@ void UT_os_setup_timerset_test(void); void UT_os_timercallback(osal_id_t timerId) { - int deltaTime = 0; - static int32 loopCnt = 0, res = 0; - static uint32 prevIntervalTime = 0; - static uint32 currIntervalTime = 0; - static OS_time_t currTime = {0}, endTime = {0}; + OS_time_t currTime; + int64 currIntervalTime; - if (OS_ObjectIdEqual(timerId, g_timerId)) + if (OS_ObjectIdEqual(timerId, g_timerGlobal.timerId) && g_timerGlobal.state != UT_TimerState_FINISHED) { - if (g_timerFirst) - { - g_timerFirst = 0; - g_status = 0; - prevIntervalTime = 0; - res = 0; - loopCnt = 0; - OS_GetLocalTime(&currTime); - } + OS_GetLocalTime(&currTime); - OS_GetLocalTime(&endTime); + if (g_timerGlobal.state == UT_TimerState_INIT) + { + /* initialization mode, first tick after a new test case starts */ + g_timerGlobal.callbackCount = 0; + g_timerGlobal.status = 0; - currIntervalTime = OS_TimeGetTotalMicroseconds(OS_TimeSubtract(endTime, currTime)); + g_timerGlobal.minDiff = INT32_MAX; + g_timerGlobal.maxDiff = INT32_MIN; - if (currIntervalTime >= prevIntervalTime) - deltaTime = currIntervalTime - prevIntervalTime; + g_timerGlobal.startTime = currTime; + g_timerGlobal.finishTime = currTime; + g_timerGlobal.state = UT_TimerState_ACTIVE; + } else - deltaTime = prevIntervalTime - currIntervalTime; - - if ((deltaTime > g_toleranceVal) && (loopCnt > 1)) - res = -1; - - loopCnt++; - currTime = endTime; - prevIntervalTime = currIntervalTime; - - if (loopCnt == g_cbLoopCntMax) { - g_status = (res == 0) ? 1 : -1; + /* normal mode (actively monitoring) */ + currIntervalTime = OS_TimeGetTotalMicroseconds(OS_TimeSubtract(currTime, g_timerGlobal.finishTime)); + + if (currIntervalTime < g_timerGlobal.minDiff) + { + g_timerGlobal.minDiff = currIntervalTime; + } + if (currIntervalTime > g_timerGlobal.maxDiff) + { + g_timerGlobal.maxDiff = currIntervalTime; + } + + g_timerGlobal.finishTime = currTime; + + if (g_timerGlobal.callbackCount < 25) + { + deltatimes[g_timerGlobal.callbackCount] = currIntervalTime; + } + + ++g_timerGlobal.callbackCount; + + if (g_timerGlobal.callbackCount >= g_timerGlobal.callbackMax) + { + g_timerGlobal.state = UT_TimerState_FINISHED; + } } } } diff --git a/src/unit-tests/ostimer-test/ut_ostimer_test.h b/src/unit-tests/ostimer-test/ut_ostimer_test.h index 5f704b165..eb40deef9 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_test.h +++ b/src/unit-tests/ostimer-test/ut_ostimer_test.h @@ -49,11 +49,29 @@ extern const char *g_timerNames[UT_OS_TIMER_LIST_LEN]; extern char g_longTimerName[UT_OS_NAME_BUFF_SIZE]; -extern uint32 g_cbLoopCntMax; -extern uint32 g_toleranceVal; -extern uint32 g_timerFirst; -extern int32 g_status; -extern osal_id_t g_timerId; +typedef enum UT_TimerState +{ + UT_TimerState_INIT, + UT_TimerState_ACTIVE, + UT_TimerState_FINISHED +} UT_TimerState_t; + +typedef struct UT_TimerGlobal +{ + UT_TimerState_t state; + + uint32 callbackCount; + uint32 callbackMax; + osal_id_t timerId; + int32 status; + OS_time_t startTime; + OS_time_t finishTime; + int32 minDiff; + int32 maxDiff; + +} UT_TimerGlobal_t; + +volatile extern UT_TimerGlobal_t g_timerGlobal; extern int32 TimerCreateRc; extern int32 TimerDeleteRc; diff --git a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c b/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c index 3314772a0..f1f741bf9 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_timerio_test.c @@ -399,9 +399,11 @@ void UT_os_timerdelete_test(void) ** is within +/- 5% of the set interval time ** 5) Exit test when the timer callback registered in #1 gets call 10 times **--------------------------------------------------------------------------------*/ -void UT_os_timerset_test(void) +extern int deltatimes[25]; +void UT_os_timerset_test(void) { uint32 startTime = 0, intervalTime = 0; + int64 totalTime; /*-----------------------------------------------------*/ /* #1 Invalid-id-arg */ @@ -419,23 +421,37 @@ void UT_os_timerset_test(void) { UT_RETVAL(OS_TimerSet(g_timerIds[3], 0, 0), OS_TIMER_ERR_INVALID_ARGS); - g_status = 0; - g_timerId = g_timerIds[3]; - g_timerFirst = 1; - g_cbLoopCntMax = 10; - startTime = 1000; - intervalTime = 5; - g_toleranceVal = 0; + g_timerGlobal.timerId = g_timerIds[3]; + g_timerGlobal.callbackMax = 100; + g_timerGlobal.state = UT_TimerState_INIT; + + /* + * This is programming the timer with a very short interval (5 usec) which is likely + * to be shorter than the period of the timer tick of the kernel. What happens here + * is going to vary per system, it may give you the minimum interval, or it may give + * you a very jittery result, or in some cases it could even possibly work. + */ + startTime = 1000; + intervalTime = 5; UtPrintf("\nOS_TimerSet() - #3 Interval-too-short (clk_accuracy=%d)\n", (int)g_clkAccuracy); if (UT_NOMINAL(OS_TimerSet(g_timerIds[3], startTime, intervalTime))) { - while (g_status == 0) + while (g_timerGlobal.state != UT_TimerState_FINISHED) { - OS_TaskDelay(1); + OS_TaskDelay(5); } - UtAssert_True(g_status < 0, "4# Nominal - callback status %d", (int)g_status); + /* it should have produced the correct number of callbacks */ + UtAssert_UINT32_EQ(g_timerGlobal.callbackCount, g_timerGlobal.callbackMax); + + UtPrintf("The following MIR test cases characterize a timer configuration with the interval set to 5us " + "(too short/invalid)"); + UtAssert_MIR("Minimum Interval = %d usec", (int)g_timerGlobal.minDiff); + UtAssert_MIR("Maximum Interval = %d usec", (int)g_timerGlobal.maxDiff); + totalTime = OS_TimeGetTotalMicroseconds(OS_TimeSubtract(g_timerGlobal.finishTime, g_timerGlobal.startTime)); + UtAssert_MIR("Total elapsed for %u ticks = %ld usec\n", (unsigned int)g_timerGlobal.callbackMax, + (long)totalTime); } /* Reset test environment */ @@ -447,23 +463,36 @@ void UT_os_timerset_test(void) if (UT_SETUP(OS_TimerCreate(&g_timerIds[4], g_timerNames[4], &g_clkAccuracy, &UT_os_timercallback))) { - g_status = 0; - g_timerId = g_timerIds[4]; - g_timerFirst = 1; - g_cbLoopCntMax = 10; - startTime = 1000; - intervalTime = 500000; - g_toleranceVal = intervalTime / 20; /* 5% */ + g_timerGlobal.timerId = g_timerIds[4]; + g_timerGlobal.callbackMax = 10; + g_timerGlobal.state = UT_TimerState_INIT; + + startTime = 1000; + intervalTime = 500000; UtPrintf("\nOS_TimerSet() - #4 Nominal condition (clk_accuracy=%d)\n", (int)g_clkAccuracy); if (UT_NOMINAL(OS_TimerSet(g_timerIds[4], startTime, intervalTime))) { - while (g_status == 0) + while (g_timerGlobal.state != UT_TimerState_FINISHED) { - OS_TaskDelay(1); + OS_TaskDelay(5); } - UtAssert_True(g_status > 0, "4# Nominal - callback status %d", (int)g_status); + /* it should have produced the correct number of callbacks */ + UtAssert_UINT32_EQ(g_timerGlobal.callbackCount, g_timerGlobal.callbackMax); + + /* + * Ensure that the intervals were all within +/- 5% of the expected interval time + * This should be a very low bar for a native RTOS to meet, but this also could be + * running on a VM in a shared/loaded server, which needs more relaxed constraints. + */ + UtAssert_INT32_GT(g_timerGlobal.minDiff, intervalTime - (intervalTime / 20)); + UtAssert_INT32_LT(g_timerGlobal.maxDiff, intervalTime + (intervalTime / 20)); + + /* The average interval time should be closer to the target, as this averages out the jitter error */ + totalTime = OS_TimeGetTotalMicroseconds(OS_TimeSubtract(g_timerGlobal.finishTime, g_timerGlobal.startTime)); + UtAssert_INT32_GT(totalTime / g_timerGlobal.callbackMax, intervalTime - (intervalTime / 200)); + UtAssert_INT32_LT(totalTime / g_timerGlobal.callbackMax, intervalTime + (intervalTime / 200)); } /* Reset test environment */ From 40457365df8742dd4aed32c8203eaa00601627c8 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Thu, 19 Dec 2024 09:25:48 -0500 Subject: [PATCH 25/51] Fix #5, Add monotonic time abstraction to OSAL Adds a new API to get the monotonic time from the operating system. For operating systems that do not have such a thing, this also includes an implementation option that returns OS_ERR_NOT_IMPLEMENTED. --- src/os/inc/osapi-clock.h | 32 +++++++ .../os-impl-posix-gettime-monotonic.c | 88 +++++++++++++++++++ .../os-impl-posix-gettime-no-monotonic.c | 60 +++++++++++++ src/os/portable/os-impl-posix-gettime.c | 6 +- src/os/posix/CMakeLists.txt | 1 + src/os/posix/inc/os-impl-gettime.h | 10 ++- src/os/rtems/CMakeLists.txt | 1 + src/os/rtems/inc/os-impl-gettime.h | 2 +- src/os/shared/inc/os-shared-clock.h | 8 ++ src/os/shared/src/osapi-clock.c | 14 +++ src/os/vxworks/CMakeLists.txt | 1 + src/os/vxworks/inc/os-impl-gettime.h | 2 +- .../shared/src/coveragetest-clock.c | 14 +++ .../ut-stubs/src/os-shared-clock-impl-stubs.c | 16 ++++ src/ut-stubs/osapi-clock-stubs.c | 16 ++++ 15 files changed, 265 insertions(+), 6 deletions(-) create mode 100644 src/os/portable/os-impl-posix-gettime-monotonic.c create mode 100644 src/os/portable/os-impl-posix-gettime-no-monotonic.c diff --git a/src/os/inc/osapi-clock.h b/src/os/inc/osapi-clock.h index 619dfe62b..35b25e18f 100644 --- a/src/os/inc/osapi-clock.h +++ b/src/os/inc/osapi-clock.h @@ -93,6 +93,38 @@ enum * @{ */ +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Get the monotonic time + * + * This function gets the monotonic time from the underlying OS. + * + * Monotonic time differs from local or real (wall-clock) time in that it cannot be set. + * As a result, the time is always guaranteed to be increasing, and never moves + * backwards or has discontinuities (with some exceptions - see POSIX documentation). + * + * The Epoch is undefined- In many implementations, the epoch is the system boot time, + * and the clock increases indefinitely so long as the system remains powered on. + * + * @note Sometimes a monotonic clock is implemented in the operating system and sometimes + * it is implemented in platform-specific hardware. + * + * If the operating system does not provide a monotonic clock, then this function may + * return #OS_ERR_NOT_IMPLEMENTED. However, a platform-specific monotonic clock may + * still exist, in the form of a CPU register or external oscillator. This API only + * accesses a monotonic clock if one is provided by the operating system. + * + * To read a platform-specific monotonic clock in CFE, see CFE_PSP_GetTime(). + * + * @param[out] time_struct An OS_time_t that will be set to the monotonic time @nonnull + * + * @return Get monotonic time status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_INVALID_POINTER if time_struct is null + * @retval #OS_ERR_NOT_IMPLEMENTED if operating system does not implement a monotonic clock + */ +int32 OS_GetMonotonicTime(OS_time_t *time_struct); + /*-------------------------------------------------------------------------------------*/ /** * @brief Get the local time diff --git a/src/os/portable/os-impl-posix-gettime-monotonic.c b/src/os/portable/os-impl-posix-gettime-monotonic.c new file mode 100644 index 000000000..410dbde47 --- /dev/null +++ b/src/os/portable/os-impl-posix-gettime-monotonic.c @@ -0,0 +1,88 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * This file contains implementation for OS_GetLocalTime() and OS_SetLocalTime() + * that map to the C library clock_gettime() and clock_settime() calls. + * This should be usable on any OS that supports those standard calls. + * The OS-specific code must \#include the correct headers that define the + * prototypes for these functions before including this implementation file. + * + * NOTE: The OS-specific header must also define which POSIX clock ID to use - + * this specifies the clockid_t parameter to use with clock_gettime(). In + * most cases this should be CLOCK_REALTIME to allow the clock to be set, and + * so the application will also see any manual/administrative clock changes. + * + * The clock ID is selected by defining the #OSAL_GETTIME_LOCAL_CLOCK macro. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +/* + * Inclusions Defined by OSAL layer. + * + * This must provide the prototypes of these functions: + * + * clock_gettime() + * clock_settime() + * + * and the "struct timespec" definition + */ +#include +#include + +#include "osapi-clock.h" +#include "os-impl-gettime.h" +#include "os-shared-clock.h" + +/**************************************************************************************** + FUNCTIONS + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_GetMonotonicTime_Impl(OS_time_t *time_struct) +{ + int Status; + int32 ReturnCode; + struct timespec TimeSp; + + Status = clock_gettime(OSAL_GETTIME_MONOTONIC_CLOCK, &TimeSp); + + if (Status == 0) + { + *time_struct = OS_TimeAssembleFromNanoseconds(TimeSp.tv_sec, TimeSp.tv_nsec); + ReturnCode = OS_SUCCESS; + } + else + { + OS_DEBUG("Error calling clock_gettime: %s\n", strerror(errno)); + ReturnCode = OS_ERROR; + } + + return ReturnCode; +} diff --git a/src/os/portable/os-impl-posix-gettime-no-monotonic.c b/src/os/portable/os-impl-posix-gettime-no-monotonic.c new file mode 100644 index 000000000..98305ef6f --- /dev/null +++ b/src/os/portable/os-impl-posix-gettime-no-monotonic.c @@ -0,0 +1,60 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * This file contains implementation for OS_GetLocalTime() and OS_SetLocalTime() + * that map to the C library clock_gettime() and clock_settime() calls. + * This should be usable on any OS that supports those standard calls. + * The OS-specific code must \#include the correct headers that define the + * prototypes for these functions before including this implementation file. + * + * NOTE: The OS-specific header must also define which POSIX clock ID to use - + * this specifies the clockid_t parameter to use with clock_gettime(). In + * most cases this should be CLOCK_REALTIME to allow the clock to be set, and + * so the application will also see any manual/administrative clock changes. + * + * The clock ID is selected by defining the #OSAL_GETTIME_LOCAL_CLOCK macro. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +#include +#include + +#include "osapi-clock.h" +#include "os-shared-clock.h" + +/**************************************************************************************** + FUNCTIONS + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_GetMonotonicTime_Impl(OS_time_t *time_struct) +{ + return OS_ERR_NOT_IMPLEMENTED; +} diff --git a/src/os/portable/os-impl-posix-gettime.c b/src/os/portable/os-impl-posix-gettime.c index 2f3e9052e..cec84921b 100644 --- a/src/os/portable/os-impl-posix-gettime.c +++ b/src/os/portable/os-impl-posix-gettime.c @@ -31,7 +31,7 @@ * most cases this should be CLOCK_REALTIME to allow the clock to be set, and * so the application will also see any manual/administrative clock changes. * - * The clock ID is selected by defining the #OSAL_GETTIME_SOURCE_CLOCK macro. + * The clock ID is selected by defining the #OSAL_GETTIME_LOCAL_CLOCK macro. */ /**************************************************************************************** @@ -71,7 +71,7 @@ int32 OS_GetLocalTime_Impl(OS_time_t *time_struct) int32 ReturnCode; struct timespec TimeSp; - Status = clock_gettime(OSAL_GETTIME_SOURCE_CLOCK, &TimeSp); + Status = clock_gettime(OSAL_GETTIME_LOCAL_CLOCK, &TimeSp); if (Status == 0) { @@ -102,7 +102,7 @@ int32 OS_SetLocalTime_Impl(const OS_time_t *time_struct) TimeSp.tv_sec = OS_TimeGetTotalSeconds(*time_struct); TimeSp.tv_nsec = OS_TimeGetNanosecondsPart(*time_struct); - Status = clock_settime(OSAL_GETTIME_SOURCE_CLOCK, &TimeSp); + Status = clock_settime(OSAL_GETTIME_LOCAL_CLOCK, &TimeSp); if (Status == 0) { diff --git a/src/os/posix/CMakeLists.txt b/src/os/posix/CMakeLists.txt index 359e8ec48..7babe2a29 100644 --- a/src/os/posix/CMakeLists.txt +++ b/src/os/posix/CMakeLists.txt @@ -28,6 +28,7 @@ set(POSIX_BASE_SRCLIST # Use portable blocks for basic I/O set(POSIX_IMPL_SRCLIST ../portable/os-impl-posix-gettime.c + ../portable/os-impl-posix-gettime-monotonic.c ../portable/os-impl-console-bsp.c ../portable/os-impl-bsd-select.c ../portable/os-impl-posix-io.c diff --git a/src/os/posix/inc/os-impl-gettime.h b/src/os/posix/inc/os-impl-gettime.h index 3d346ebec..ed4959940 100644 --- a/src/os/posix/inc/os-impl-gettime.h +++ b/src/os/posix/inc/os-impl-gettime.h @@ -35,6 +35,14 @@ * This is the POSIX clock ID that will be used to implement * OS_GetLocalTime() and OS_SetLocalTime(). */ -#define OSAL_GETTIME_SOURCE_CLOCK CLOCK_REALTIME +#define OSAL_GETTIME_LOCAL_CLOCK CLOCK_REALTIME + +/** + * \brief Identifies the clock ID for OSAL clock operations on POSIX + * + * This is the POSIX clock ID that will be used to implement + * OS_GetMonotonicTime(). + */ +#define OSAL_GETTIME_MONOTONIC_CLOCK CLOCK_MONOTONIC #endif /* OS_IMPL_GETTIME_H */ diff --git a/src/os/rtems/CMakeLists.txt b/src/os/rtems/CMakeLists.txt index 2358ae844..9f506a8b7 100644 --- a/src/os/rtems/CMakeLists.txt +++ b/src/os/rtems/CMakeLists.txt @@ -28,6 +28,7 @@ set(RTEMS_BASE_SRCLIST # Use portable blocks for basic I/O set(RTEMS_IMPL_SRCLIST ../portable/os-impl-posix-gettime.c + ../portable/os-impl-posix-gettime-monotonic.c ../portable/os-impl-console-bsp.c ../portable/os-impl-posix-io.c ../portable/os-impl-posix-files.c diff --git a/src/os/rtems/inc/os-impl-gettime.h b/src/os/rtems/inc/os-impl-gettime.h index 2604eb865..45e3b546a 100644 --- a/src/os/rtems/inc/os-impl-gettime.h +++ b/src/os/rtems/inc/os-impl-gettime.h @@ -35,6 +35,6 @@ * This is the POSIX clock ID that will be used to implement * OS_GetLocalTime() and OS_SetLocalTime(). */ -#define OSAL_GETTIME_SOURCE_CLOCK CLOCK_REALTIME +#define OSAL_GETTIME_LOCAL_CLOCK CLOCK_REALTIME #endif /* OS_IMPL_GETTIME_H */ diff --git a/src/os/shared/inc/os-shared-clock.h b/src/os/shared/inc/os-shared-clock.h index d578c7474..93db24778 100644 --- a/src/os/shared/inc/os-shared-clock.h +++ b/src/os/shared/inc/os-shared-clock.h @@ -34,6 +34,14 @@ * These simply get/set the kernel RTC (if it has one) */ +/*---------------------------------------------------------------- + + Purpose: Get the monotinc time from the Operating System + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_GetMonotonicTime_Impl(OS_time_t *time_struct); + /*---------------------------------------------------------------- Purpose: Get the time from the RTC diff --git a/src/os/shared/src/osapi-clock.c b/src/os/shared/src/osapi-clock.c index 2cd0b0448..f82c28efd 100644 --- a/src/os/shared/src/osapi-clock.c +++ b/src/os/shared/src/osapi-clock.c @@ -38,6 +38,20 @@ */ #include "os-shared-clock.h" +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_GetMonotonicTime(OS_time_t *time_struct) +{ + /* Check parameters */ + OS_CHECK_POINTER(time_struct); + + return OS_GetMonotonicTime_Impl(time_struct); +} + /*---------------------------------------------------------------- * * Purpose: Implemented per public OSAL API diff --git a/src/os/vxworks/CMakeLists.txt b/src/os/vxworks/CMakeLists.txt index 5bcc7f4d3..2c56ffaa3 100644 --- a/src/os/vxworks/CMakeLists.txt +++ b/src/os/vxworks/CMakeLists.txt @@ -28,6 +28,7 @@ set(VXWORKS_BASE_SRCLIST # Use portable blocks for basic I/O set(VXWORKS_IMPL_SRCLIST ../portable/os-impl-posix-gettime.c + ../portable/os-impl-posix-gettime-no-monotonic.c ../portable/os-impl-console-bsp.c ../portable/os-impl-bsd-select.c ../portable/os-impl-posix-io.c diff --git a/src/os/vxworks/inc/os-impl-gettime.h b/src/os/vxworks/inc/os-impl-gettime.h index 7f245a79e..3e2a5b53a 100644 --- a/src/os/vxworks/inc/os-impl-gettime.h +++ b/src/os/vxworks/inc/os-impl-gettime.h @@ -35,6 +35,6 @@ * This is the POSIX clock ID that will be used to implement * OS_GetLocalTime() and OS_SetLocalTime(). */ -#define OSAL_GETTIME_SOURCE_CLOCK CLOCK_REALTIME +#define OSAL_GETTIME_LOCAL_CLOCK CLOCK_REALTIME #endif /* OS_IMPL_GETTIME_H */ diff --git a/src/unit-test-coverage/shared/src/coveragetest-clock.c b/src/unit-test-coverage/shared/src/coveragetest-clock.c index dae84ee71..fa40dcacf 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-clock.c +++ b/src/unit-test-coverage/shared/src/coveragetest-clock.c @@ -25,6 +25,19 @@ #include "os-shared-coveragetest.h" #include "os-shared-clock.h" +void Test_OS_GetMonotonicTime(void) +{ + /* + * Test Case For: + * int32 OS_GetMonotonicTime(OS_time_t *time_struct) + */ + OS_time_t time_struct; + + UtAssert_INT32_EQ(OS_GetMonotonicTime(&time_struct), OS_SUCCESS); + UtAssert_NONZERO(OS_TimeGetTotalMilliseconds(time_struct)); + UtAssert_INT32_EQ(OS_GetMonotonicTime(NULL), OS_INVALID_POINTER); +} + void Test_OS_GetLocalTime(void) { /* @@ -220,6 +233,7 @@ void Osapi_Test_Teardown(void) {} void UtTest_Setup(void) { ADD_TEST(OS_GetLocalTime); + ADD_TEST(OS_GetMonotonicTime); ADD_TEST(OS_SetLocalTime); ADD_TEST(OS_TimeAccessConversions); ADD_TEST(OS_TimeFromRelativeMilliseconds); diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c index e8f2160a2..bb10c7864 100644 --- a/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-clock-impl-stubs.c @@ -43,6 +43,22 @@ int32 OS_GetLocalTime_Impl(OS_time_t *time_struct) return UT_GenStub_GetReturnValue(OS_GetLocalTime_Impl, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_GetMonotonicTime_Impl() + * ---------------------------------------------------- + */ +int32 OS_GetMonotonicTime_Impl(OS_time_t *time_struct) +{ + UT_GenStub_SetupReturnBuffer(OS_GetMonotonicTime_Impl, int32); + + UT_GenStub_AddParam(OS_GetMonotonicTime_Impl, OS_time_t *, time_struct); + + UT_GenStub_Execute(OS_GetMonotonicTime_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_GetMonotonicTime_Impl, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SetLocalTime_Impl() diff --git a/src/ut-stubs/osapi-clock-stubs.c b/src/ut-stubs/osapi-clock-stubs.c index 27914ea91..1dbdfa7d1 100644 --- a/src/ut-stubs/osapi-clock-stubs.c +++ b/src/ut-stubs/osapi-clock-stubs.c @@ -44,6 +44,22 @@ int32 OS_GetLocalTime(OS_time_t *time_struct) return UT_GenStub_GetReturnValue(OS_GetLocalTime, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_GetMonotonicTime() + * ---------------------------------------------------- + */ +int32 OS_GetMonotonicTime(OS_time_t *time_struct) +{ + UT_GenStub_SetupReturnBuffer(OS_GetMonotonicTime, int32); + + UT_GenStub_AddParam(OS_GetMonotonicTime, OS_time_t *, time_struct); + + UT_GenStub_Execute(OS_GetMonotonicTime, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_GetMonotonicTime, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_SetLocalTime() From 066becf5eb08bec843c70755d35cd1fba53789b6 Mon Sep 17 00:00:00 2001 From: "Molock, Dwaine S 550328410" Date: Fri, 28 Feb 2025 10:55:21 -0500 Subject: [PATCH 26/51] Issue cFS/PSP#11, Fixed Unit Tests to add support for QNX Operating System --- src/os/inc/osapi-macros.h | 1 - src/unit-test-coverage/ut-stubs/src/posix-mqueue-stubs.c | 1 - src/unit-test-coverage/ut-stubs/src/posix-pthread-stubs.c | 1 - src/unit-test-coverage/ut-stubs/src/posix-semaphore-stubs.c | 1 - src/unit-test-coverage/ut-stubs/src/posix-signal-stubs.c | 1 - src/unit-test-coverage/ut-stubs/src/posix-stat-stubs.c | 1 - src/unit-test-coverage/ut-stubs/src/posix-time-stubs.c | 1 - src/unit-test-coverage/ut-stubs/src/sys-select-stubs.c | 1 - 8 files changed, 8 deletions(-) diff --git a/src/os/inc/osapi-macros.h b/src/os/inc/osapi-macros.h index ab1354a8a..e61d0b124 100644 --- a/src/os/inc/osapi-macros.h +++ b/src/os/inc/osapi-macros.h @@ -26,7 +26,6 @@ #define OSAPI_MACROS_H #include -#include #include #include "osconfig.h" diff --git a/src/unit-test-coverage/ut-stubs/src/posix-mqueue-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-mqueue-stubs.c index e85f9bc7e..dbe8d14ed 100644 --- a/src/unit-test-coverage/ut-stubs/src/posix-mqueue-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/posix-mqueue-stubs.c @@ -18,7 +18,6 @@ /* OSAL coverage stub replacement for mqueue.h */ #include -#include #include "utstubs.h" #include "OCS_mqueue.h" diff --git a/src/unit-test-coverage/ut-stubs/src/posix-pthread-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-pthread-stubs.c index 136b5dcd9..7b9793dd4 100644 --- a/src/unit-test-coverage/ut-stubs/src/posix-pthread-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/posix-pthread-stubs.c @@ -18,7 +18,6 @@ /* OSAL coverage stub replacement for pthread.h */ #include -#include #include "utstubs.h" #include "OCS_pthread.h" diff --git a/src/unit-test-coverage/ut-stubs/src/posix-semaphore-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-semaphore-stubs.c index 6adf9b9f9..087a87182 100644 --- a/src/unit-test-coverage/ut-stubs/src/posix-semaphore-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/posix-semaphore-stubs.c @@ -18,7 +18,6 @@ /* OSAL coverage stub replacement for semaphore.h */ #include -#include #include "utstubs.h" #include "OCS_semaphore.h" diff --git a/src/unit-test-coverage/ut-stubs/src/posix-signal-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-signal-stubs.c index 6f8ee74e5..3294f1154 100644 --- a/src/unit-test-coverage/ut-stubs/src/posix-signal-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/posix-signal-stubs.c @@ -18,7 +18,6 @@ /* OSAL coverage stub replacement for signal.h */ #include -#include #include "utstubs.h" #include "OCS_signal.h" diff --git a/src/unit-test-coverage/ut-stubs/src/posix-stat-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-stat-stubs.c index aadc1e957..da433302a 100644 --- a/src/unit-test-coverage/ut-stubs/src/posix-stat-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/posix-stat-stubs.c @@ -18,7 +18,6 @@ /* OSAL coverage stub replacement for functions in sys/stat.h */ #include -#include #include "utstubs.h" #include "OCS_stat.h" diff --git a/src/unit-test-coverage/ut-stubs/src/posix-time-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-time-stubs.c index c76e4b6b7..4070ba598 100644 --- a/src/unit-test-coverage/ut-stubs/src/posix-time-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/posix-time-stubs.c @@ -18,7 +18,6 @@ /* OSAL coverage stub replacement for time.h */ #include -#include #include "utstubs.h" #include "OCS_time.h" diff --git a/src/unit-test-coverage/ut-stubs/src/sys-select-stubs.c b/src/unit-test-coverage/ut-stubs/src/sys-select-stubs.c index ffa873b43..6af1ac943 100644 --- a/src/unit-test-coverage/ut-stubs/src/sys-select-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/sys-select-stubs.c @@ -25,7 +25,6 @@ /* OSAL coverage stub replacement for functions in sys/stat.h */ #include -#include #include "utstubs.h" #include "OCS_sys_select.h" From ac8c9a34f5aa04fb5ae33135a1bf1195fcce91ad Mon Sep 17 00:00:00 2001 From: root Date: Fri, 7 Mar 2025 21:37:23 +0000 Subject: [PATCH 27/51] Fix cFS/workflows#14, Added JSON output to MCDC comment for osal --- .github/workflows/mcdc-internal.yml | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index 2d23f7a16..d01798d0d 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -123,7 +123,7 @@ jobs: with: name: MCDC results path: | - **/*.gcov + **/*.gcov.json.gz mcdc_results.txt pr_number modules.txt @@ -168,15 +168,22 @@ jobs: const path = require('path'); // Adjust the path based on where you see mcdc_results.txt after running the 'ls' command const mcdcResultsFilePath = path.join(process.env.GITHUB_WORKSPACE, 'mcdc_comment.txt'); + const uncoveredFilePath = path.join(process.env.GITHUB_WORKSPACE, 'uncovered.json'); // Debugging: Check if the file exists at the adjusted path if (!fs.existsSync(mcdcResultsFilePath)) { console.log('mcdc_comment.txt file not found at path: ' + mcdcResultsFilePath); return; } + + if (!fs.existsSync(uncoveredFilePath)) { + console.log('uncovered.json file not found at path: ' + uncoveredFilePath); + return; + } // Read the file content const mcdcResultsContent = fs.readFileSync(mcdcResultsFilePath, 'utf-8').trim(); + const uncoveredContent = fs.readFileSync(uncoveredFilePath, 'utf-8').trim(); // If the file is empty, don't comment if (mcdcResultsContent === '') { @@ -184,11 +191,15 @@ jobs: return; } - const mcdcResults = `MCDC Results: - \`\`\` - ${mcdcResultsContent} - \`\`\` - `; + const mcdcResults = `MC/DC Results: +
${mcdcResultsContent}
+            
+
+ Click to view uncovered branches (uncovered.json) +
+
${uncoveredContent}
+            
+
`; // Ensure the correct path to the pr_number file after unzipping const prNumberPath = path.join(process.env.GITHUB_WORKSPACE, 'pr_number'); From 86eeb3d0e3dbca822847e6ffb2b1516b493db989 Mon Sep 17 00:00:00 2001 From: Adams Date: Mon, 10 Mar 2025 12:13:13 -0500 Subject: [PATCH 28/51] Fix cFS/cFS#41, Add CodeSonar Integration --- .github/workflows/codesonar-internal.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/codesonar-internal.yml diff --git a/.github/workflows/codesonar-internal.yml b/.github/workflows/codesonar-internal.yml new file mode 100644 index 000000000..139038fa6 --- /dev/null +++ b/.github/workflows/codesonar-internal.yml @@ -0,0 +1,15 @@ +name: Internal CodeSonar + +on: + schedule: + - cron: "0 0 * * 1" # Runs every Monday at 12:00 AM UTC + workflow_dispatch: + +jobs: + codesonar: + name: Run Codesonar + uses: cFS/workflows/.github/workflows/codesonar-reusable-internal.yml@dev + with: + component-path: cFS # Causes reusable workflow to not checkout bundle + setup: cp Makefile.sample Makefile + secrets: inherit \ No newline at end of file From 75a757abf3d8f8068434ebe00baeedec0cb7e332 Mon Sep 17 00:00:00 2001 From: Adams Date: Tue, 11 Mar 2025 13:29:32 -0500 Subject: [PATCH 29/51] Fix cFS/workflows#10, Update MCDC Trigger --- .github/workflows/mcdc-internal.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index 2d23f7a16..dc01a030a 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -2,7 +2,7 @@ name: Internal MCDC Analysis on: push: - pull_request: + pull_request_target: # Force bash to apply pipefail option so pipeline failures aren't masked defaults: @@ -102,7 +102,7 @@ jobs: run: bash workflows/.github/scripts/mcdc-analyze.sh - name: Save PR number - if: github.event_name == 'pull_request' && always() + if: github.event_name == 'pull_request_target' && always() env: PR_NUMBER: ${{ github.event.number }} run: echo $PR_NUMBER > pr_number @@ -130,7 +130,7 @@ jobs: comment-mcdc: needs: mcdc - if: github.event_name == 'pull_request' && always() + if: github.event_name == 'pull_request_target' && always() name: Comment MCDC Comparision on PR runs-on: Linux From 4efc874e3521dd7a01a3453d7a7bcff81d9bdf0b Mon Sep 17 00:00:00 2001 From: Shiraz Bhalwani Date: Mon, 24 Mar 2025 14:23:23 -0400 Subject: [PATCH 30/51] Fix #11, modifications to get 'No Network Option' to compile --- src/os/portable/os-impl-no-select.c | 4 ++-- src/os/rtems/CMakeLists.txt | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/os/portable/os-impl-no-select.c b/src/os/portable/os-impl-no-select.c index 9cd416bef..d4c648734 100644 --- a/src/os/portable/os-impl-no-select.c +++ b/src/os/portable/os-impl-no-select.c @@ -57,7 +57,7 @@ * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, int32 msecs) +int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, OS_time_t abs_timeout) { return OS_ERR_NOT_IMPLEMENTED; } @@ -68,7 +68,7 @@ int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags, * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) +int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, OS_time_t abs_timeout) { return OS_ERR_NOT_IMPLEMENTED; } diff --git a/src/os/rtems/CMakeLists.txt b/src/os/rtems/CMakeLists.txt index 2358ae844..f06210c17 100644 --- a/src/os/rtems/CMakeLists.txt +++ b/src/os/rtems/CMakeLists.txt @@ -73,7 +73,8 @@ if (OSAL_CONFIG_INCLUDE_NETWORK) endif() else() list(APPEND RTEMS_IMPL_SRCLIST - ../portable/os-impl-no-network.c + ../portable/os-impl-no-network-gethostid.c + ../portable/os-impl-no-network-gethostname.c ../portable/os-impl-no-sockets.c ../portable/os-impl-no-select.c ) From 80798ed7c50d4a60f1066ccd366941e6b4136003 Mon Sep 17 00:00:00 2001 From: Anh Van Date: Wed, 26 Feb 2025 16:33:55 -0500 Subject: [PATCH 31/51] Fix #92, Update MIRs Fix #92, Update functional test/unit test MIR. Remove Length Error from OS_SymbolTableDump --- src/os/inc/osapi-module.h | 1 - src/os/vxworks/src/os-impl-symtab.c | 1 - src/tests/symbol-api-test/symbol-api-test.c | 72 +++++--------- .../vxworks/src/coveragetest-symtab.c | 10 +- .../oscore-test/ut_oscore_misc_test.c | 95 +++++++++++++------ .../osloader-test/ut_osloader_symtable_test.c | 28 +++--- 6 files changed, 112 insertions(+), 95 deletions(-) diff --git a/src/os/inc/osapi-module.h b/src/os/inc/osapi-module.h index 34b4c527b..7118b8b89 100644 --- a/src/os/inc/osapi-module.h +++ b/src/os/inc/osapi-module.h @@ -178,7 +178,6 @@ int32 OS_ModuleSymbolLookup(osal_id_t module_id, cpuaddr *symbol_address, const * @retval #OS_ERR_NOT_IMPLEMENTED @copybrief OS_ERR_NOT_IMPLEMENTED * @retval #OS_INVALID_POINTER if the filename argument is NULL * @retval #OS_FS_ERR_PATH_INVALID if the filename argument is not valid - * @retval #OS_ERR_NAME_TOO_LONG if any of the symbol names are too long @covtest * @retval #OS_ERR_OUTPUT_TOO_LARGE if the size_limit was reached before completing all symbols @covtest * @retval #OS_ERROR if an other/unspecified error occurs @covtest */ diff --git a/src/os/vxworks/src/os-impl-symtab.c b/src/os/vxworks/src/os-impl-symtab.c index a3699f6ca..cd9446036 100644 --- a/src/os/vxworks/src/os-impl-symtab.c +++ b/src/os/vxworks/src/os-impl-symtab.c @@ -174,7 +174,6 @@ BOOL OS_SymTableIterator_Impl(char *name, SYM_VALUE val, SYM_TYPE type, _Vx_usr_ { symRecord.SymbolName[sizeof(symRecord.SymbolName) - 2] = '*'; OS_DEBUG("%s(): symbol name too long\n", __func__); - state->StatusCode = OS_ERR_NAME_TOO_LONG; } /* diff --git a/src/tests/symbol-api-test/symbol-api-test.c b/src/tests/symbol-api-test/symbol-api-test.c index 78de352a2..2c29b8cce 100644 --- a/src/tests/symbol-api-test/symbol-api-test.c +++ b/src/tests/symbol-api-test/symbol-api-test.c @@ -32,78 +32,56 @@ void TestSymbolApi(void) { int32 status; cpuaddr SymAddress = 0; + uint32 size; + char fileName[128]; /* Make the file system */ - status = OS_mkfs(0, "/ramdev0", "RAM", 512, 2048); + status = OS_mkfs(0, "/ramdev1", "RAM", 512, 10240); UtAssert_True(status == OS_SUCCESS, "status after mkfs = %d", (int)status); - status = OS_mount("/ramdev0", "/ram"); + status = OS_mount("/ramdev1", "/ram"); UtAssert_True(status == OS_SUCCESS, "status after mount = %d", (int)status); /* - ** dump the symbol table with a 32768 byte limit + ** dump the symbol table with a small limit to cause it to fail */ - UtPrintf("Dumping symbol table with a limit of 32768 bytes\n"); - status = OS_SymbolTableDump("/ram/SymbolTable32k.dat", 32768); - if (status == OS_ERR_NOT_IMPLEMENTED) - { - UtAssert_NA("OS_SymbolTableDump API not implemented"); - } - else if (status == OS_ERR_OUTPUT_TOO_LARGE) - { - UtAssert_MIR("32k too small for OS_SymbolTableDump"); - } - else if (status == OS_ERR_NAME_TOO_LONG) - { - UtAssert_MIR("OS_SymbolTableDump name to long, consider increasing OSAL_CONFIG_MAX_SYM_LEN"); - } - else - { - UtAssert_True(status == OS_SUCCESS, "status after 32k OS_SymbolTableDump = %d", (int)status); - } + size = 10; + UtPrintf("Dumping symbol table with a limit of %d bytes\n", size); + snprintf(fileName, sizeof(fileName), "/ram/SymbolTable%d.dat", size); - /* - ** dump the symbol table with a 128k byte limit - */ - UtPrintf("Dumping symbol table with a limit of 131072 bytes\n"); - status = OS_SymbolTableDump("/ram/SymbolTable128k.dat", 131072); + status = OS_SymbolTableDump(fileName, size); if (status == OS_ERR_NOT_IMPLEMENTED) { UtAssert_NA("OS_SymbolTableDump API not implemented"); } - else if (status == OS_ERR_OUTPUT_TOO_LARGE) - { - UtAssert_MIR("128k too small for OS_SymbolTableDump"); - } - else if (status == OS_ERR_NAME_TOO_LONG) - { - UtAssert_MIR("OS_SymbolTableDump name to long, consider increasing OSAL_CONFIG_MAX_SYM_LEN"); - } else { - UtAssert_True(status == OS_SUCCESS, "status after 128k OS_SymbolTableDump = %d", (int)status); + UtAssert_INT32_EQ(status, OS_ERR_OUTPUT_TOO_LARGE); } /* - ** dump the symbol table with a 512k byte limit + ** dump the symbol table with a high limit to pass */ - UtPrintf("Dumping symbol table with a limit of 524288 bytes\n"); - status = OS_SymbolTableDump("/ram/SymbolTable512k.dat", 524288); + size = 1024 * 1024 * 5; + UtPrintf("Dumping symbol table with a limit of %d bytes\n", size); + snprintf(fileName, sizeof(fileName), "/ram/SymbolTable5MiB.dat"); + + status = OS_SymbolTableDump(fileName, size); if (status == OS_ERR_NOT_IMPLEMENTED) { UtAssert_NA("OS_SymbolTableDump API not implemented"); } - else if (status == OS_ERR_OUTPUT_TOO_LARGE) - { - UtAssert_MIR("512k too small for OS_SymbolTableDump"); - } - else if (status == OS_ERR_NAME_TOO_LONG) - { - UtAssert_MIR("OS_SymbolTableDump name to long, consider increasing OSAL_CONFIG_MAX_SYM_LEN"); - } else { - UtAssert_True(status == OS_SUCCESS, "status after 512k OS_SymbolTableDump = %d", (int)status); + UtAssert_INT32_EQ(status, OS_SUCCESS); + if (status == OS_ERR_OUTPUT_TOO_LARGE) + { + UtPrintf("Symbol Table bigger than %d bytes. Consider increasing dump size\n", size); + } + else if (status == OS_ERR_NAME_TOO_LONG) + { + UtPrintf("OS_SymbolTableDump name to long, consider increasing OSAL_CONFIG_MAX_SYM_LEN\n"); + } } /* diff --git a/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c b/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c index 4da5f8c43..366eb7c14 100644 --- a/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c +++ b/src/unit-test-coverage/vxworks/src/coveragetest-symtab.c @@ -71,16 +71,16 @@ void Test_OS_SymTableIterator_Impl(void) OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 1000), true); OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_SUCCESS); - /* Check case where next entry will exceed size limit */ - OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 101), false); - OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_ERR_OUTPUT_TOO_LARGE); - /* Check case where entry has a name that is too long */ UT_SetDefaultReturnValue(UT_KEY(OCS_memchr), OS_ERROR); OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 1000), true); - OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_ERR_NAME_TOO_LONG); + OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_SUCCESS); UT_ClearDefaultReturnValue(UT_KEY(OCS_memchr)); + /* Check case where next entry will exceed size limit */ + OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 101), false); + OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_GetIteratorStatus(), OS_ERR_OUTPUT_TOO_LARGE); + /* Check case where writing to file fails */ UT_SetDefaultReturnValue(UT_KEY(OCS_write), -1); OSAPI_TEST_FUNCTION_RC(UT_SymTabTest_CallIteratorFunc("ut", &Data, 100, 1000), false); diff --git a/src/unit-tests/oscore-test/ut_oscore_misc_test.c b/src/unit-tests/oscore-test/ut_oscore_misc_test.c index 0dd7e787b..72f2d9ce8 100644 --- a/src/unit-tests/oscore-test/ut_oscore_misc_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_misc_test.c @@ -161,7 +161,7 @@ void UT_os_registereventhandler_test(void) void UT_os_printf_test(void) { OS_printf_enable(); - UT_MIR_VOID(OS_printf("OS_printf() - #1 Nominal [This is the expected stdout output after API call]\n")); + UT_MIR_VOID(OS_printf("OS_printf() - #1 Nominal [Seeing this text in stdout constitutes a pass for this MIR]\n")); } /*--------------------------------------------------------------------------------* @@ -181,7 +181,7 @@ void UT_os_printfenable_test(void) OS_printf_disable(); OS_printf_enable(); - UT_MIR_VOID(OS_printf("OS_printf_enable() - #1 Nominal [This is the expected stdout output after API call]\n")); + UT_MIR_VOID(OS_printf("OS_printf_enable() - #1 Nominal [Seeing this text in stdout constitutes a pass for this MIR]\n")); } /*--------------------------------------------------------------------------------* @@ -199,15 +199,15 @@ void UT_os_printfenable_test(void) void UT_os_printfdisable_test(void) { OS_printf_enable(); - UT_MIR_VOID(OS_printf("OS_printf_disable() - #1 Nominal [This is the expected stdout output before API call]\n")); + UT_MIR_VOID(OS_printf("OS_printf_disable() - #1 Nominal [Seeing this text in stdout constitutes a pass for this MIR]\n")); OS_printf_disable(); UT_MIR_VOID( - OS_printf("OS_printf_disable() - #1 Nominal [This is NOT the expected stdout output after API call]\n")); + OS_printf("OS_printf_disable() - #1 Nominal [Seeing this text in stdout constitutes a failure for this MIR]\n")); /* Reset test environment */ OS_printf_enable(); - UT_MIR_VOID(OS_printf("OS_printf_disable() - #1 Nominal [This is the expected stdout output after test reset]\n")); + UT_MIR_VOID(OS_printf("OS_printf_disable() - #1 Nominal [Seeing this text in stdout constitutes a pass for this MIR]\n")); } /*--------------------------------------------------------------------------------* @@ -243,8 +243,10 @@ void UT_os_printfdisable_test(void) **--------------------------------------------------------------------------------*/ void UT_os_getlocaltime_test(void) { - OS_time_t time_struct; - int32 i = 0; + OS_time_t time_struct[10]; + int32 i = 0; + int64 microsecs[10]; + int32 total_sec_inc = 0; memset(&time_struct, 0, sizeof(time_struct)); @@ -262,18 +264,33 @@ void UT_os_getlocaltime_test(void) /*-----------------------------------------------------*/ /* #3 Nominal */ - for (i = 0; i < 5; i++) { - UT_NOMINAL(OS_GetLocalTime(&time_struct)); + UT_NOMINAL(OS_GetLocalTime(&time_struct[i])); + UtPrintf("[Expecting output after API call to increase over time: %ld.%ld]\n", - (long)OS_TimeGetTotalSeconds(time_struct), (long)OS_TimeGetMicrosecondsPart(time_struct)); + (long)OS_TimeGetTotalSeconds(time_struct[i]), (long)OS_TimeGetMicrosecondsPart(time_struct[i])); + microsecs[i] = OS_TimeGetMicrosecondsPart(time_struct[i]); + + if ( i != 0 ) + { + total_sec_inc = OS_TimeGetTotalSeconds(time_struct[i]) - OS_TimeGetTotalSeconds(time_struct[i-1]); + } + + if (i != 0 && total_sec_inc <= 0) + { + if(total_sec_inc < 0) + { + UtAssert_Failed("UT_os_setlocaltime_test failure: Time not increasing"); + } + else if (microsecs[i] <= microsecs[i-1]) + { + UtAssert_Failed("UT_os_setlocaltime_test failure: Time not increasing"); + } + } OS_TaskDelay(20); } - - /* #3 Nominal - Manual inspection required */ - UT_MIR_STATUS(OS_GetLocalTime(&time_struct)); } /*--------------------------------------------------------------------------------* @@ -309,8 +326,11 @@ void UT_os_getlocaltime_test(void) **--------------------------------------------------------------------------------*/ void UT_os_setlocaltime_test(void) { - OS_time_t time_struct; - int32 i = 0; + OS_time_t time_struct[10]; + int32 i = 0; + int64 microsecs[10]; + int32 total_sec_inc; + int32 status; memset(&time_struct, 0, sizeof(time_struct)); @@ -332,34 +352,55 @@ void UT_os_setlocaltime_test(void) for (i = 0; i < 5; i++) { - UT_NOMINAL(OS_GetLocalTime(&time_struct)); + UT_NOMINAL(OS_GetLocalTime(&time_struct[i])); UtPrintf("[Expecting output before API call to increase over time: %ld.%ld]\n", - (long)OS_TimeGetTotalSeconds(time_struct), (long)OS_TimeGetMicrosecondsPart(time_struct)); + (long)OS_TimeGetTotalSeconds(time_struct[i]), (long)OS_TimeGetMicrosecondsPart(time_struct[i])); OS_TaskDelay(20); } - time_struct = OS_TimeAssembleFromNanoseconds(20000, 123000); + time_struct[0] = OS_TimeAssembleFromNanoseconds(20000, 123000); /* * This case is MIR because on some systems this requires permission, * failure is expected if user does not have the required permission */ - if (UT_MIR_STATUS(OS_SetLocalTime(&time_struct))) + status = OS_SetLocalTime(&time_struct[0]); + if(status != OS_SUCCESS) + { + /* Generate MIR for tester to review */ + UT_MIR_STATUS(OS_SetLocalTime(&time_struct[0])); + UtPrintf("Failed OS_SetLocalTime(), Check to see if your system has the required premission.\n"); + } + else { UtPrintf("OS_SetLocalTime() - #3 Nominal [New time set at %ld.%ld]\n", - (long)OS_TimeGetTotalSeconds(time_struct), (long)OS_TimeGetMicrosecondsPart(time_struct)); + (long)OS_TimeGetTotalSeconds(time_struct[0]), (long)OS_TimeGetMicrosecondsPart(time_struct[0])); for (i = 0; i < 5; i++) { - UT_NOMINAL(OS_GetLocalTime(&time_struct)); - UtPrintf("[Expecting output before API call to increase over time: %ld.%ld]\n", - (long)OS_TimeGetTotalSeconds(time_struct), (long)OS_TimeGetMicrosecondsPart(time_struct)); - - OS_TaskDelay(20); + UT_NOMINAL(OS_GetLocalTime(&time_struct[i])); + + UtPrintf("[Expecting output after API call to increase over time: %ld.%ld]\n", + (long)OS_TimeGetTotalSeconds(time_struct[i]), (long)OS_TimeGetMicrosecondsPart(time_struct[i])); + + microsecs[i] = OS_TimeGetMicrosecondsPart(time_struct[i]); + + total_sec_inc = OS_TimeGetTotalSeconds(time_struct[i]) - OS_TimeGetTotalSeconds(time_struct[i-1]); + + if (i != 0 && total_sec_inc <= 0) + { + if(total_sec_inc < 0) + { + UtAssert_Failed("UT_os_setlocaltime_test failure: Time not increasing"); + } + else if (microsecs[i] <= microsecs[i-1]) + { + UtAssert_Failed("UT_os_setlocaltime_test failure: Time not increasing"); + } + } + OS_TaskDelay(20); } - - UT_MIR_STATUS(OS_GetLocalTime(&time_struct)); } } diff --git a/src/unit-tests/osloader-test/ut_osloader_symtable_test.c b/src/unit-tests/osloader-test/ut_osloader_symtable_test.c index 91d2f2a55..e48820175 100644 --- a/src/unit-tests/osloader-test/ut_osloader_symtable_test.c +++ b/src/unit-tests/osloader-test/ut_osloader_symtable_test.c @@ -39,7 +39,7 @@ * This must be large enough to actually accommodate all of the symbols * in the target system. */ -#define UT_SYMTABLE_SIZE_LIMIT 1048576 +#define UT_SYMTABLE_SIZE_LIMIT (1024 * 1024 * 5) /*--------------------------------------------------------------------------------* ** Data types @@ -213,23 +213,23 @@ void UT_os_symbol_table_dump_test(void) { UtAssert_NA("OS_SymbolTableDump API not implemented"); } - else if (status == OS_ERR_OUTPUT_TOO_LARGE) - { - UtAssert_MIR("UT_SYMTABLE_SIZE_LIMIT too small for OS_SymbolTableDump"); - } - else if (status == OS_ERR_NAME_TOO_LONG) - { - UtAssert_MIR("OSAL_CONFIG_MAX_SYM_LEN too small for OS_SymbolTableDump"); - } else { - UtAssert_True(status == OS_SUCCESS, "status after 128k OS_SymbolTableDump = %d", (int)status); + UtAssert_INT32_EQ(status, OS_SUCCESS); + if (status == OS_SUCCESS) + { + UT_RETVAL(OS_SymbolTableDump(UT_OS_GENERIC_MODULE_DIR "SymbolZero.dat", 0), OS_ERR_OUTPUT_TOO_LARGE); + } + else if (status == OS_ERR_OUTPUT_TOO_LARGE) + { + UtPrintf("Failed OS_SymbolTableDump, UT_SYMTABLE_SIZE_LIMIT too small for OS_SymbolTableDump\n"); + } + else if (status == OS_ERR_NAME_TOO_LONG) + { + UtPrintf("OS_SymbolTableDump name to long, consider increasing OSAL_CONFIG_MAX_SYM_LEN\n"); + } } - if (status == OS_SUCCESS) - { - UT_RETVAL(OS_SymbolTableDump(UT_OS_GENERIC_MODULE_DIR "SymbolZero.dat", 0), OS_ERR_OUTPUT_TOO_LARGE); - } } /*================================================================================* From 9bb603a3b3bae634a296b74bfddff68df0d0b38e Mon Sep 17 00:00:00 2001 From: Shiraz Bhalwani Date: Mon, 14 Apr 2025 13:27:35 -0400 Subject: [PATCH 32/51] Fix #13, Changed to fix linking issue for network_pc686_rtems module Commented out lines were causing 'rtems_bsdnet_config' structure to be defined by librtemscpu.a instead of libnetwork_pc686_rtems.a --- src/bsp/generic-rtems/CMakeLists.txt | 11 ++++++----- src/bsp/pc-rtems/CMakeLists.txt | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/bsp/generic-rtems/CMakeLists.txt b/src/bsp/generic-rtems/CMakeLists.txt index 2eea908ab..7eef98cef 100644 --- a/src/bsp/generic-rtems/CMakeLists.txt +++ b/src/bsp/generic-rtems/CMakeLists.txt @@ -23,12 +23,13 @@ else () ) endif () +# Commented out since it is causing problems linking when using network module 'network_pc686_rtems' # Link rtemscpu to osal public api if not dynamic loading -if (NOT RTEMS_DYNAMIC_LOAD) - target_link_libraries(osal_public_api INTERFACE - rtemscpu - ) -endif () +#if (NOT RTEMS_DYNAMIC_LOAD) +# target_link_libraries(osal_public_api INTERFACE +# rtemscpu +# ) +#endif () if (RTEMS_NO_SHELL) list(APPEND OS_BSP_SRCLIST diff --git a/src/bsp/pc-rtems/CMakeLists.txt b/src/bsp/pc-rtems/CMakeLists.txt index 83c74461e..7281c48aa 100644 --- a/src/bsp/pc-rtems/CMakeLists.txt +++ b/src/bsp/pc-rtems/CMakeLists.txt @@ -16,9 +16,10 @@ target_compile_definitions(osal_public_api INTERFACE _BSD_SOURCE ) +# Commented out since it is causing problems linking when using network module 'network_pc686_rtems' # Link the RTEMS BSP with the "rtemscpu" system library -target_link_libraries(osal_public_api INTERFACE - rtemscpu -) +#target_link_libraries(osal_public_api INTERFACE +# rtemscpu +#) set_property(TARGET osal_pc-rtems_impl PROPERTY OSAL_EXPECTED_OSTYPE "rtems") From a95f4731942dc3f91c3acf47368318212e37b6f1 Mon Sep 17 00:00:00 2001 From: Shiraz Bhalwani Date: Tue, 15 Apr 2025 14:33:02 -0400 Subject: [PATCH 33/51] Fix 13, Deleted the lines causing link issue since not needed --- src/bsp/generic-rtems/CMakeLists.txt | 8 -------- src/bsp/pc-rtems/CMakeLists.txt | 6 ------ 2 files changed, 14 deletions(-) diff --git a/src/bsp/generic-rtems/CMakeLists.txt b/src/bsp/generic-rtems/CMakeLists.txt index 7eef98cef..09adca437 100644 --- a/src/bsp/generic-rtems/CMakeLists.txt +++ b/src/bsp/generic-rtems/CMakeLists.txt @@ -23,14 +23,6 @@ else () ) endif () -# Commented out since it is causing problems linking when using network module 'network_pc686_rtems' -# Link rtemscpu to osal public api if not dynamic loading -#if (NOT RTEMS_DYNAMIC_LOAD) -# target_link_libraries(osal_public_api INTERFACE -# rtemscpu -# ) -#endif () - if (RTEMS_NO_SHELL) list(APPEND OS_BSP_SRCLIST src/bsp_no_shell.c diff --git a/src/bsp/pc-rtems/CMakeLists.txt b/src/bsp/pc-rtems/CMakeLists.txt index 7281c48aa..d5efd66f9 100644 --- a/src/bsp/pc-rtems/CMakeLists.txt +++ b/src/bsp/pc-rtems/CMakeLists.txt @@ -16,10 +16,4 @@ target_compile_definitions(osal_public_api INTERFACE _BSD_SOURCE ) -# Commented out since it is causing problems linking when using network module 'network_pc686_rtems' -# Link the RTEMS BSP with the "rtemscpu" system library -#target_link_libraries(osal_public_api INTERFACE -# rtemscpu -#) - set_property(TARGET osal_pc-rtems_impl PROPERTY OSAL_EXPECTED_OSTYPE "rtems") From 0f3cad6c02a5bc0f6ac389bed5c428c7d9230d64 Mon Sep 17 00:00:00 2001 From: Adams Date: Wed, 23 Apr 2025 10:09:37 -0500 Subject: [PATCH 34/51] Fix cFS/cFS#12, Add PR to Project --- .github/workflows/add-to-project-internal.yml | 14 ++++++++++++++ .github/workflows/add-to-project.yml | 19 ------------------- 2 files changed, 14 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/add-to-project-internal.yml delete mode 100644 .github/workflows/add-to-project.yml diff --git a/.github/workflows/add-to-project-internal.yml b/.github/workflows/add-to-project-internal.yml new file mode 100644 index 000000000..7a25a341d --- /dev/null +++ b/.github/workflows/add-to-project-internal.yml @@ -0,0 +1,14 @@ +name: Internal Add Issue or PR to Project + +on: + issues: + types: [opened] + pull_request_target: + types: [opened] + + +jobs: + add-to-project: + name: Add issue or pull request to project + uses: cFS/workflows/.github/workflows/add-to-project-reusable-internal.yml@dev + secrets: inherit diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml deleted file mode 100644 index b002fcfd9..000000000 --- a/.github/workflows/add-to-project.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Add issues to project - -on: - issues: - types: - - opened - -jobs: - add-to-project: - name: Add issue to project - runs-on: Linux - steps: - # This action doesn't exist in enterprise, manually added to cFS org for now - - uses: cFS/add-to-project@v1.0.2 - with: - # You can target a project in a different organization - # to the issue - project-url: https://github.com/orgs/cFS/projects/1 - github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} \ No newline at end of file From d9fbeb0f26fd99fa3839ae38cabef99918895aa6 Mon Sep 17 00:00:00 2001 From: Shiraz Bhalwani Date: Wed, 21 May 2025 16:21:11 -0400 Subject: [PATCH 35/51] Fix #13, Modify generic-rtems OSAL to be able to use it with RKI --- src/bsp/generic-rtems/CMakeLists.txt | 27 ++++++++++++++----- src/bsp/generic-rtems/src/bsp_no_setupfs.c | 31 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 src/bsp/generic-rtems/src/bsp_no_setupfs.c diff --git a/src/bsp/generic-rtems/CMakeLists.txt b/src/bsp/generic-rtems/CMakeLists.txt index 09adca437..44019fd2c 100644 --- a/src/bsp/generic-rtems/CMakeLists.txt +++ b/src/bsp/generic-rtems/CMakeLists.txt @@ -7,20 +7,33 @@ # Basic set of files set(OS_BSP_SRCLIST src/bsp_console.c - src/bsp_init.c src/bsp_start.c ) -# Source select file system setup implementation -if (RTEMS_INCLUDE_TARFS) +# Do not include these files when building cFS image using RTEMS Kernel Image (RKI) +if (NOT RTEMS_USING_RKI) list(APPEND OS_BSP_SRCLIST - src/bsp_tarfs_setupfs.c + src/bsp_init.c ) -else () - # NOTE: rtems config needs to define supporting configuration (FILESYSTEM and DRIVERs) +endif () + +# No File System setup when building cFS image using RKI +if (RTEMS_USING_RKI) list(APPEND OS_BSP_SRCLIST - src/bsp_mount_setupfs.c + src/bsp_no_setupfs.c ) +else () + # Source select file system setup implementation + if (RTEMS_INCLUDE_TARFS) + list(APPEND OS_BSP_SRCLIST + src/bsp_tarfs_setupfs.c + ) + else () + # NOTE: rtems config needs to define supporting configuration (FILESYSTEM and DRIVERs) + list(APPEND OS_BSP_SRCLIST + src/bsp_mount_setupfs.c + ) + endif () endif () if (RTEMS_NO_SHELL) diff --git a/src/bsp/generic-rtems/src/bsp_no_setupfs.c b/src/bsp/generic-rtems/src/bsp_no_setupfs.c new file mode 100644 index 000000000..eeb0765c7 --- /dev/null +++ b/src/bsp/generic-rtems/src/bsp_no_setupfs.c @@ -0,0 +1,31 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as core Flight System: Bootes + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/* + * \file + * + * OSAL BSP: File System not set up + */ +#include +#include "bsp_setupfs.h" + +void OS_BSP_SetupFS(void) +{ + /* Null File System setup function. Used when the file system has already + been setup in RTEMS kernel. For instance, when building cFS with RKI */ +} \ No newline at end of file From c2bfba42df3c35a937859d411faaf230a5a24fea Mon Sep 17 00:00:00 2001 From: Shiraz Bhalwani Date: Thu, 22 May 2025 16:11:51 -0400 Subject: [PATCH 36/51] Fix #13, Update cmake file as per review comments --- src/bsp/generic-rtems/CMakeLists.txt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/bsp/generic-rtems/CMakeLists.txt b/src/bsp/generic-rtems/CMakeLists.txt index 44019fd2c..6c75c72b2 100644 --- a/src/bsp/generic-rtems/CMakeLists.txt +++ b/src/bsp/generic-rtems/CMakeLists.txt @@ -8,21 +8,19 @@ set(OS_BSP_SRCLIST src/bsp_console.c src/bsp_start.c -) +) -# Do not include these files when building cFS image using RTEMS Kernel Image (RKI) -if (NOT RTEMS_USING_RKI) - list(APPEND OS_BSP_SRCLIST - src/bsp_init.c - ) -endif () - -# No File System setup when building cFS image using RKI -if (RTEMS_USING_RKI) +if (RTEMS_EXTERNAL_KERNEL) + # No File System setup implemented when building cFS image using external RTEMS Kernel (e.g. RKI) list(APPEND OS_BSP_SRCLIST src/bsp_no_setupfs.c ) else () + # Include these files when NOT building cFS image using external RTEMS Kernel (e.g. RKI) + list(APPEND OS_BSP_SRCLIST + src/bsp_init.c + ) + # Source select file system setup implementation if (RTEMS_INCLUDE_TARFS) list(APPEND OS_BSP_SRCLIST From 9d96971e96027318ddcf1cb5b3ca212d0cfe5313 Mon Sep 17 00:00:00 2001 From: Adams Date: Tue, 27 May 2025 15:13:05 -0500 Subject: [PATCH 37/51] Fix cFS/cFS#170, Use Self-Hosted Runners --- .../build-osal-documentation-internal.yml | 18 ++++--------- .github/workflows/mcdc-internal.yml | 25 ++++++------------- .../workflows/standalone-build-internal.yml | 23 +++-------------- 3 files changed, 16 insertions(+), 50 deletions(-) diff --git a/.github/workflows/build-osal-documentation-internal.yml b/.github/workflows/build-osal-documentation-internal.yml index 20613073f..485e773ae 100644 --- a/.github/workflows/build-osal-documentation-internal.yml +++ b/.github/workflows/build-osal-documentation-internal.yml @@ -8,7 +8,7 @@ jobs: #Check for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action. check-for-duplicates: - runs-on: Linux + runs-on: cfs-self-hosted # Map a step output to a job output outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} @@ -24,18 +24,10 @@ jobs: #Continue if check-for-duplicates found no duplicates. Always runs for pull-requests. needs: check-for-duplicates if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }} - runs-on: Linux + runs-on: cfs-self-hosted timeout-minutes: 15 steps: - - name: Clean workflow - run: | - rm -rf ./* || true - rm -rf ./.??* || true - - - name: Install Dependencies - run: sudo apt-get install doxygen graphviz make cmake -y - - name: Checkout submodule uses: actions/checkout@v4 @@ -54,9 +46,9 @@ jobs: with: name: OSAL Guide Artifacts path: | - make_osal-apiguide_stdout.txt - make_osal-apiguide_stderr.txt - osal-apiguide-warnings.log + ${{ env.WORK_PATH }}/make_osal-apiguide_stdout.txt + ${{ env.WORK_PATH }}/make_osal-apiguide_stderr.txt + ${{ env.WORK_PATH }}/osal-apiguide-warnings.log - name: Error Check run: | diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index 5ea49b482..f60f2b4fe 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -20,7 +20,7 @@ jobs: # Checks for duplicate actions. Skips push actions if there is a matching or # duplicate pull-request action. checks-for-duplicates: - runs-on: Linux + runs-on: cfs-mcdc # Map a step output to a job output outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} @@ -36,15 +36,9 @@ jobs: needs: checks-for-duplicates if: ${{ needs.checks-for-duplicates.outputs.should_skip != 'true' || contains(github.ref, 'dev') }} name: Build and Run MCDC - runs-on: Linux - container: ghcr.io/core-flight-system/mcdc:latest + runs-on: cfs-mcdc steps: - - name: Clean workflow - run: | - rm -rf ./* || true - rm -rf ./.??* || true - - name: Checkout MCDC Script uses: actions/checkout@v4 with: @@ -61,10 +55,6 @@ jobs: sed -i 's/target_compile_options.*)/target_compile_options(ut_coverage_compile INTERFACE -pg -O0 -fprofile-arcs -ftest-coverage -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/CMakeLists.txt sed -i 's/set(UT_COVERAGE_COMPILE_FLAGS.*)/set(UT_COVERAGE_COMPILE_FLAGS -pg --coverage -O0 -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/build_options.cmake sed -i 's/set(UT_COVERAGE_LINK_FLAGS.*)/set(UT_COVERAGE_LINK_FLAGS -pg --coverage -O0 -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/build_options.cmake - - - name: Clean cmake - run: | - rm -rf /__w/osal/osal/build/* - name: Set up build run: cmake @@ -77,8 +67,8 @@ jobs: -DOSAL_SYSTEM_BSPTYPE=generic-linux -DCMAKE_PREFIX_PATH=/usr/lib/cmake -DCMAKE_INSTALL_PREFIX=/usr - -S /__w/osal/osal/source - -B /__w/osal/osal/build + -S source + -B build - name: Build OSAL working-directory: build @@ -132,7 +122,7 @@ jobs: needs: mcdc if: github.event_name == 'pull_request_target' && always() name: Comment MCDC Comparision on PR - runs-on: Linux + runs-on: cfs-mcdc steps: - name: Checkout MCDC Script @@ -149,7 +139,7 @@ jobs: search_artifacts: true branch: dev name: MCDC results - path: ./main-branch-results + path: main-branch-results - uses: actions/download-artifact@v3 with: @@ -247,4 +237,5 @@ jobs: name: MCDC main branch comparison path: | mcdc_comment.txt - mcdc_compare.txt \ No newline at end of file + mcdc_compare.txt + \ No newline at end of file diff --git a/.github/workflows/standalone-build-internal.yml b/.github/workflows/standalone-build-internal.yml index 305235299..55730769b 100644 --- a/.github/workflows/standalone-build-internal.yml +++ b/.github/workflows/standalone-build-internal.yml @@ -14,43 +14,26 @@ env: allowed_ncov_functions: 0 jobs: - clean-workflows: - name: Clean Workflows - runs-on: Linux - - steps: - - name: Clean workflow - run: | - rm -rf ./* || true - rm -rf ./.??* || true - build-and-test: name: Build and Execute Tests - needs: clean-workflows - + runs-on: cfs-self-hosted strategy: fail-fast: false matrix: build-type: [Debug, Release] - runs-on: Linux - steps: - name: Checkout OSAL uses: actions/checkout@v4 with: path: source - - name: Install make - run: | - sudo apt-get update && sudo apt-get install -y make cmake g++ - - name: Set CXX environment variable run: echo "CXX=/usr/bin/g++" >> $GITHUB_ENV - - name: Install Coverage Analysis Tools + - name: Set run_lcov=TRUE if: ${{ matrix.build-type == 'Debug' }} - run: sudo apt-get install -y lcov xsltproc && echo "run_lcov=TRUE" >> $GITHUB_ENV + run: echo "run_lcov=TRUE" >> $GITHUB_ENV - name: Set up debug environment if: ${{ matrix.build-type == 'Debug' }} From 5789f1f712754bf8e24b2dd11882d871604d103b Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Mon, 9 Jun 2025 17:09:39 -0400 Subject: [PATCH 38/51] Fix cFS/cFS#116, deprecations in latest Cmake versions --- CMakeLists.txt | 4 ++-- docs/src/CMakeLists.txt | 1 - src/unit-test-coverage/CMakeLists.txt | 2 +- src/unit-tests/osloader-test/CMakeLists.txt | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f65266481..bd95a62ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,7 @@ # OSAL resources. # ###################################################################### -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.10) # Set the policy dictating use of target_link_libraries across directories # Either OLD or NEW should work here but setting it to something avoids a @@ -419,7 +419,7 @@ if (ENABLE_UNIT_TESTS) target_link_libraries(${TGTNAME} PUBLIC ut_assert osal) add_test(${TGTNAME} ${TGTNAME}) foreach(TGT ${INSTALL_TARGET_LIST}) - install(TARGETS ${TGTNAME} DESTINATION ${TGT}/${UT_INSTALL_SUBDIR}) + install(TARGETS ${TGTNAME} DESTINATION ${TGT}) endforeach() endfunction(add_osal_ut_exe) diff --git a/docs/src/CMakeLists.txt b/docs/src/CMakeLists.txt index c257dc0b0..916be46df 100644 --- a/docs/src/CMakeLists.txt +++ b/docs/src/CMakeLists.txt @@ -28,7 +28,6 @@ # in a standalone build environment. # -cmake_minimum_required(VERSION 3.5) project(OSAL_DOCS NONE) # List of dox files to include - diff --git a/src/unit-test-coverage/CMakeLists.txt b/src/unit-test-coverage/CMakeLists.txt index 34be9e245..0550a0ac7 100644 --- a/src/unit-test-coverage/CMakeLists.txt +++ b/src/unit-test-coverage/CMakeLists.txt @@ -86,7 +86,7 @@ function (add_coverage_testrunner TESTNAME FSW_SRCFILE TESTCASE_SRCFILE) add_test(${TESTNAME} ${TESTNAME}-testrunner) foreach(TGT ${INSTALL_TARGET_LIST}) - install(TARGETS ${TESTNAME}-testrunner DESTINATION ${TGT}/${UT_INSTALL_SUBDIR}) + install(TARGETS ${TESTNAME}-testrunner DESTINATION ${TGT}) endforeach() endfunction() diff --git a/src/unit-tests/osloader-test/CMakeLists.txt b/src/unit-tests/osloader-test/CMakeLists.txt index dbaece6ac..9cb1dfc45 100644 --- a/src/unit-tests/osloader-test/CMakeLists.txt +++ b/src/unit-tests/osloader-test/CMakeLists.txt @@ -21,6 +21,6 @@ while(MOD GREATER 0) LIBRARY_OUTPUT_DIRECTORY utmod) add_dependencies(osal_loader_UT MODULE${MOD}) foreach(TGT ${INSTALL_TARGET_LIST}) - install(TARGETS MODULE${MOD} DESTINATION ${TGT}/${UT_INSTALL_SUBDIR}/utmod) + install(TARGETS MODULE${MOD} DESTINATION ${TGT}/utmod) endforeach() endwhile(MOD GREATER 0) From ca4e9d984b7cb26e158ec9f7338e47d20f55867d Mon Sep 17 00:00:00 2001 From: Adams Date: Wed, 11 Jun 2025 08:54:13 -0500 Subject: [PATCH 39/51] Fix cFS/cFS#170, Use Workflow Containers --- .github/workflows/build-osal-documentation-internal.yml | 2 ++ .github/workflows/mcdc-internal.yml | 8 +++++--- .github/workflows/standalone-build-internal.yml | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-osal-documentation-internal.yml b/.github/workflows/build-osal-documentation-internal.yml index 485e773ae..51300ee3c 100644 --- a/.github/workflows/build-osal-documentation-internal.yml +++ b/.github/workflows/build-osal-documentation-internal.yml @@ -25,6 +25,8 @@ jobs: needs: check-for-duplicates if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }} runs-on: cfs-self-hosted + container: + image: aetd-dockerlab.gsfc.nasa.gov/gsfc-cfs/github-actions-ci-cd/cfsbuildenv-doxygen timeout-minutes: 15 steps: diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index f60f2b4fe..efc05e0aa 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -20,7 +20,7 @@ jobs: # Checks for duplicate actions. Skips push actions if there is a matching or # duplicate pull-request action. checks-for-duplicates: - runs-on: cfs-mcdc + runs-on: cfs-self-hosted # Map a step output to a job output outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} @@ -36,7 +36,9 @@ jobs: needs: checks-for-duplicates if: ${{ needs.checks-for-duplicates.outputs.should_skip != 'true' || contains(github.ref, 'dev') }} name: Build and Run MCDC - runs-on: cfs-mcdc + runs-on: cfs-self-hosted + container: + image: aetd-dockerlab.gsfc.nasa.gov/gsfc-cfs/github-actions-ci-cd/cfsbuildenv-mcdc steps: - name: Checkout MCDC Script @@ -122,7 +124,7 @@ jobs: needs: mcdc if: github.event_name == 'pull_request_target' && always() name: Comment MCDC Comparision on PR - runs-on: cfs-mcdc + runs-on: cfs-self-hosted steps: - name: Checkout MCDC Script diff --git a/.github/workflows/standalone-build-internal.yml b/.github/workflows/standalone-build-internal.yml index 55730769b..92a00b356 100644 --- a/.github/workflows/standalone-build-internal.yml +++ b/.github/workflows/standalone-build-internal.yml @@ -17,6 +17,8 @@ jobs: build-and-test: name: Build and Execute Tests runs-on: cfs-self-hosted + container: + image: aetd-dockerlab.gsfc.nasa.gov/gsfc-cfs/github-actions-ci-cd/cfsbuildenv-ubuntu22 strategy: fail-fast: false matrix: From 770c2f62bcdb113ae85279c7eb8ff411f901070c Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 11 Jun 2025 10:26:42 -0400 Subject: [PATCH 40/51] Fix #59, add define for monotonic clock on RTEMS --- src/os/rtems/inc/os-impl-gettime.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/os/rtems/inc/os-impl-gettime.h b/src/os/rtems/inc/os-impl-gettime.h index 45e3b546a..14d96416f 100644 --- a/src/os/rtems/inc/os-impl-gettime.h +++ b/src/os/rtems/inc/os-impl-gettime.h @@ -37,4 +37,12 @@ */ #define OSAL_GETTIME_LOCAL_CLOCK CLOCK_REALTIME +/** + * \brief Identifies the clock ID for OSAL clock operations on POSIX + * + * This is the POSIX clock ID that will be used to implement + * OS_GetMonotonicTime(). + */ +#define OSAL_GETTIME_MONOTONIC_CLOCK CLOCK_MONOTONIC + #endif /* OS_IMPL_GETTIME_H */ From bb44c89df2cb77d9e4f00d2d5cf345760005df30 Mon Sep 17 00:00:00 2001 From: Adams Date: Mon, 23 Jun 2025 15:19:04 -0500 Subject: [PATCH 41/51] Part cFS/workflows#39, Exclude Draft PRs for Add to Project Workflow --- .github/workflows/add-to-project-internal.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/add-to-project-internal.yml b/.github/workflows/add-to-project-internal.yml index 7a25a341d..cb6a31ef2 100644 --- a/.github/workflows/add-to-project-internal.yml +++ b/.github/workflows/add-to-project-internal.yml @@ -4,8 +4,7 @@ on: issues: types: [opened] pull_request_target: - types: [opened] - + types: [opened, ready_for_review, converted_to_draft] jobs: add-to-project: From a15d4d72de89cea270422b15f71723af0f9481dd Mon Sep 17 00:00:00 2001 From: Adams Date: Thu, 3 Jul 2025 13:23:27 -0500 Subject: [PATCH 42/51] Fix #71, Update Workflow Coverage Path --- .github/actions/check-coverage/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/actions/check-coverage/action.yml b/.github/actions/check-coverage/action.yml index 6089b2112..2f86ac507 100644 --- a/.github/actions/check-coverage/action.yml +++ b/.github/actions/check-coverage/action.yml @@ -27,7 +27,6 @@ runs: shell: bash run: lcov --capture --rc lcov_branch_coverage=1 - --include '${{ github.workspace }}/*' --directory '${{ inputs.binary-dir }}' --output-file '${{ inputs.binary-dir }}/coverage.info' | tee '${{ inputs.binary-dir }}/lcov_out.txt' From 6c1ece6ce899af7df630c66ce6fe37b08c92727c Mon Sep 17 00:00:00 2001 From: Aras Shirwan Date: Tue, 24 Jun 2025 14:39:18 +0000 Subject: [PATCH 43/51] Fix #56, Add RwLock API & its POSIX implementation Create a shared RwLock API, along with a POSIX implementation and the associated test cases and stubs. Add configuration option to disable RwLocks. Since some persistent data structures within cFS are read-heavy, it would be wise to take advantage of a readers-writer lock over a mutex for synchronization for performance reasons. --- CMakeLists.txt | 2 +- default_config.cmake | 32 ++ osconfig.h.in | 7 + src/os/inc/osapi-idmap.h | 1 + src/os/inc/osapi-rwlock.h | 208 ++++++++++ src/os/inc/osapi.h | 1 + src/os/portable/os-impl-no-rwlock.c | 68 +++ src/os/posix/CMakeLists.txt | 10 + src/os/posix/inc/os-impl-rwlock.h | 41 ++ src/os/posix/inc/os-posix.h | 1 + src/os/posix/src/os-impl-rwlock.c | 225 ++++++++++ src/os/qnx/CMakeLists.txt | 10 + src/os/rtems/CMakeLists.txt | 1 + src/os/shared/inc/os-shared-idmap.h | 8 +- src/os/shared/inc/os-shared-rwlock.h | 109 +++++ src/os/shared/src/osapi-idmap.c | 11 +- src/os/shared/src/osapi-rwlock.c | 325 +++++++++++++++ src/os/vxworks-rtp/CMakeLists.txt | 10 + src/os/vxworks/CMakeLists.txt | 1 + src/tests/rwlock-test/rwlock-test.c | 391 ++++++++++++++++++ .../portable/src/coveragetest-no-rwlock.c | 127 ++++++ src/unit-test-coverage/shared/CMakeLists.txt | 1 + .../shared/src/coveragetest-idmap.c | 2 +- .../shared/src/coveragetest-rwlock.c | 259 ++++++++++++ .../shared/src/os-shared-coverage-support.c | 3 + .../ut-stubs/CMakeLists.txt | 4 + .../src/os-shared-rwlock-impl-stubs.c | 140 +++++++ .../src/os-shared-rwlock-init-stubs.c | 40 ++ .../src/osapi-shared-idmap-table-stubs.c | 2 + .../src/osapi-shared-rwlock-table-stubs.c | 32 ++ src/ut-stubs/CMakeLists.txt | 3 + src/ut-stubs/osapi-rwlock-handlers.c | 111 +++++ src/ut-stubs/osapi-rwlock-stubs.c | 163 ++++++++ 33 files changed, 2341 insertions(+), 8 deletions(-) create mode 100644 src/os/inc/osapi-rwlock.h create mode 100644 src/os/portable/os-impl-no-rwlock.c create mode 100644 src/os/posix/inc/os-impl-rwlock.h create mode 100644 src/os/posix/src/os-impl-rwlock.c create mode 100644 src/os/shared/inc/os-shared-rwlock.h create mode 100644 src/os/shared/src/osapi-rwlock.c create mode 100644 src/tests/rwlock-test/rwlock-test.c create mode 100644 src/unit-test-coverage/portable/src/coveragetest-no-rwlock.c create mode 100644 src/unit-test-coverage/shared/src/coveragetest-rwlock.c create mode 100644 src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-impl-stubs.c create mode 100644 src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-init-stubs.c create mode 100644 src/unit-test-coverage/ut-stubs/src/osapi-shared-rwlock-table-stubs.c create mode 100644 src/ut-stubs/osapi-rwlock-handlers.c create mode 100644 src/ut-stubs/osapi-rwlock-stubs.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bd95a62ca..50eb9b05c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,7 @@ set(OSAL_SRCLIST src/os/shared/src/osapi-network.c src/os/shared/src/osapi-printf.c src/os/shared/src/osapi-queue.c + src/os/shared/src/osapi-rwlock.c src/os/shared/src/osapi-select.c src/os/shared/src/osapi-shell.c src/os/shared/src/osapi-sockets.c @@ -370,7 +371,6 @@ if (OSAL_CONFIG_DEBUG_PRINTF) ) endif (OSAL_CONFIG_DEBUG_PRINTF) - # Define the external "osal" static library target # This is a combination of the generic parts with the low level # system-specific parts diff --git a/default_config.cmake b/default_config.cmake index 592e5636a..3c0bb2dfa 100644 --- a/default_config.cmake +++ b/default_config.cmake @@ -206,6 +206,33 @@ set(OSAL_CONFIG_CONSOLE_ASYNC TRUE CACHE BOOL "Controls spawning of a separate utility task for OS_printf" ) +# +# OS_CONFIG_RWLOCK +# ---------------------------------- +# +# Controls whether the readers-writer lock object is included in the compilation +# process of the OSAL. +# +# If set FALSE, the relevant source and header files will be excluded in the compilation +# of OSAL, such that the object is still registered with the Object ID system +# but its associated functions won't be defined or declared. +# +# If set TRUE, the relevant source and header files will be included in the compilation +# of OSAL, and all it's associated functions will be callable. +# +# When this is TRUE (default), it gives the ability to create a readers-writer lock as +# an alternative to synchronization with mutexes for data structures that are read-heavy. +# It allows for either an infinite number of readers to be accessing a data structure or +# a single writer. +# +# This option is available since some platforms may not support readers-writer locks, so +# any use of a readers-writer lock should also create an implementation using solely +# mutexes. +# +set(OSAL_CONFIG_RWLOCK TRUE + CACHE BOOL "Controls the inclusion of readers-writer lock objects in the code" +) + ############################################# # Resource Limits for the OS API ############################################# @@ -238,6 +265,11 @@ set(OSAL_CONFIG_MAX_MUTEXES 20 CACHE STRING "Maximum Number of Mutexes to support" ) +# The maximum number of rwlocks to support +set(OSAL_CONFIG_MAX_RWLOCKS 20 + CACHE STRING "Maximum Number of RwLocks to support" +) + # The maximum number of condition variables to support set(OSAL_CONFIG_MAX_CONDVARS 4 CACHE STRING "Maximum Number of Condition Variables to support" diff --git a/osconfig.h.in b/osconfig.h.in index ac8cbb954..9551c0391 100644 --- a/osconfig.h.in +++ b/osconfig.h.in @@ -71,6 +71,13 @@ */ #define OS_MAX_MUTEXES @OSAL_CONFIG_MAX_MUTEXES@ + /** + * \brief The maximum number of rwlocks to support + * + * Based on the OSAL_CONFIG_MAX_RWLOCKS configuration option + */ +#define OS_MAX_RWLOCKS @OSAL_CONFIG_MAX_RWLOCKS@ + /** * \brief The maximum number of condition variables to support * diff --git a/src/os/inc/osapi-idmap.h b/src/os/inc/osapi-idmap.h index 3f1fb8e14..09867d9fd 100644 --- a/src/os/inc/osapi-idmap.h +++ b/src/os/inc/osapi-idmap.h @@ -49,6 +49,7 @@ #define OS_OBJECT_TYPE_OS_FILESYS 0x0B /**< @brief Object file system type */ #define OS_OBJECT_TYPE_OS_CONSOLE 0x0C /**< @brief Object console type */ #define OS_OBJECT_TYPE_OS_CONDVAR 0x0D /**< @brief Object condition variable type */ +#define OS_OBJECT_TYPE_OS_RWLOCK 0x0E /**< @brief Object readers-writer lock type */ #define OS_OBJECT_TYPE_USER 0x10 /**< @brief Object user type */ /**@}*/ diff --git a/src/os/inc/osapi-rwlock.h b/src/os/inc/osapi-rwlock.h new file mode 100644 index 000000000..f27e7d19e --- /dev/null +++ b/src/os/inc/osapi-rwlock.h @@ -0,0 +1,208 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * + * Declarations and prototypes for rwlocks + */ + +#ifndef OSAPI_RWLOCK_H +#define OSAPI_RWLOCK_H + +#include "osconfig.h" +#include "common_types.h" + +/** @brief OSAL rwlock properties */ +typedef struct +{ + char name[OS_MAX_API_NAME]; + osal_id_t creator; +} OS_rwlock_prop_t; + +/** @defgroup OSAPIRwLock OSAL RwLock APIs + * @{ + */ + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Creates an readers-writer lock (rwlock) + * + * RwLocks are always created in the unlocked (full) state. + * + * @param[out] rw_id will be set to the non-zero ID of the newly-created resource @nonnull + * @param[in] rw_name the name of the new resource to create @nonnull + * @param[in] options reserved for future use. Should be passed as 0. + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_INVALID_POINTER if sem_id or sem_name are NULL + * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME + * @retval #OS_ERR_NO_FREE_IDS if there are no more free rwlock Ids + * @retval #OS_ERR_NAME_TAKEN if there is already a rwlock with the same name + * @retval #OS_ERROR if the OS call failed @covtest + */ +int32 OS_RwLockCreate(osal_id_t *rw_id, const char *rw_name, uint32 options); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Releases the reader lock on the rwlock object referenced by rw_id. + * + * If this function is called by a thread which holds a read lock on this rwlock object, + * and there are other threads currently holding read locks, the rwlock will remain in + * the read locked state. If the function is called by the last thread which held a + * read lock, the rwlock becomes unlocked. + * + * If this function is called by a thread which holds a write lock on this rwlock object, + * the behavior is undefined. + * + * If there are threads blocked on the rwlock object referenced by + * rw_id when this function is called, resulting in the rwlock becoming + * available, the scheduling policy shall determine which thread shall + * acquire the rwlock. + * + * @param[in] rw_id The object ID to operate on + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid rwlock + * @retval #OS_ERROR if an unspecified error occurs @covtest + */ +int32 OS_RwLockReadGive(osal_id_t rw_id); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Releases the rwlock object referenced by rw_id. + * + * If this function is called by a thread which holds a write lock on this rwlock object, + * the rwlock becomes unlocked. + * + * If this function is called by a thread which holds a read lock on this rwlock object, + * the behavior is undefined. + * + * If there are threads blocked on the rwlock object referenced by + * rwlock when this function is called, resulting in the rwlock becoming + * available, the scheduling policy shall determine which thread shall + * acquire the rwlock. + * + * @param[in] rw_id The object ID to operate on + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid rwlock + * @retval #OS_ERROR if an unspecified error occurs @covtest + */ +int32 OS_RwLockWriteGive(osal_id_t rw_id); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Acquire the rwlock object as a read lock as referenced by rw_id. + * + * If the rwlock is currently write locked, as in a thread holds a write lock on this + * rwlock object, the current thread will block until the rwlock becomes available to + * readers. + * + * If the rwlock is currently read locked and a thread intending to obtain a write lock + * is waiting, whether or not the current thread is allowed to obtain a read lock depends + * on the underlying OS rwlock implementation. + * + * If the rwlock is currently read locked and there are no threads waiting to obtain a write + * lock, the current thread is allowed to obtain a read lock. + * + * If the rwlock is unlocked, the current thread will obtain a read lock + * on this rwlock object. + * + * @param[in] rw_id The object ID to operate on + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID the id passed in is not a valid rwlock + * @retval #OS_ERROR if an unspecified error occurs @covtest + */ +int32 OS_RwLockReadTake(osal_id_t rw_id); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Acquire the rwlock object as a write lock as referenced by rw_id. + * + * If the rwlock is currently write or read locked, the current thread will block until + * the rwlock becomes available. If the rwlock is open, the current thread will acquire + * a write lock on this rwlock object. + * + * @param[in] rw_id The object ID to operate on + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID the id passed in is not a valid rwlock + * @retval #OS_ERROR if an unspecified error occurs @covtest + */ +int32 OS_RwLockWriteTake(osal_id_t rw_id); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Deletes the specified RwLock. + * + * Delete the rwlock. This also frees the respective rw_id such that it can be + * used again when another is created. + * + * @param[in] rw_id The object ID to delete + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid rwlock + * @retval #OS_ERROR if an unspecified error occurs @covtest + */ +int32 OS_RwLockDelete(osal_id_t rw_id); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Find an existing rwlock ID by name + * + * This function tries to find a rwlock Id given the name of a rwlock. + * The id is returned through rw_id + * + * @param[out] rw_id will be set to the ID of the existing resource + * @param[in] rw_name the name of the existing resource to find @nonnull + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_INVALID_POINTER is rw_id or rw_name are NULL pointers + * @retval #OS_ERR_NAME_TOO_LONG name length including null terminator greater than #OS_MAX_API_NAME + * @retval #OS_ERR_NAME_NOT_FOUND if the name was not found in the table + */ +int32 OS_RwLockGetIdByName(osal_id_t *rw_id, const char *rw_name); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Fill a property object buffer with details regarding the resource + * + * This function will pass back a pointer to structure that contains + * all of the relevant info( name and creator) about the specified rwlock. + * + * @param[in] rw_id The object ID to operate on + * @param[out] rw_prop The property object buffer to fill @nonnull + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS + * @retval #OS_ERR_INVALID_ID if the id passed in is not a valid rwlock + * @retval #OS_INVALID_POINTER if the rw_prop pointer is null + */ +int32 OS_RwLockGetInfo(osal_id_t rw_id, OS_rwlock_prop_t *rw_prop); +/**@}*/ + +#endif /* OSAPI_RWLOCK_H */ diff --git a/src/os/inc/osapi.h b/src/os/inc/osapi.h index d86cb3254..bac41add6 100644 --- a/src/os/inc/osapi.h +++ b/src/os/inc/osapi.h @@ -79,6 +79,7 @@ extern "C" #include "osapi-network.h" #include "osapi-printf.h" #include "osapi-queue.h" +#include "osapi-rwlock.h" #include "osapi-select.h" #include "osapi-shell.h" #include "osapi-sockets.h" diff --git a/src/os/portable/os-impl-no-rwlock.c b/src/os/portable/os-impl-no-rwlock.c new file mode 100644 index 000000000..d6f04201b --- /dev/null +++ b/src/os/portable/os-impl-no-rwlock.c @@ -0,0 +1,68 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup posix + * \author joseph.p.hickey@nasa.gov + * + * Purpose: All functions return OS_ERR_NOT_IMPLEMENTED. + * This is used when rwlock functionality is disabled by config. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +#include +#include "os-shared-rwlock.h" + +int32 OS_RwLockCreate_Impl(const OS_object_token_t *token, uint32 options) +{ + return OS_ERR_NOT_IMPLEMENTED; +} + +int32 OS_RwLockDelete_Impl(const OS_object_token_t *token) +{ + return OS_ERR_NOT_IMPLEMENTED; +} + +int32 OS_RwLockReadGive_Impl(const OS_object_token_t *token) +{ + return OS_ERR_NOT_IMPLEMENTED; +} + +int32 OS_RwLockWriteGive_Impl(const OS_object_token_t *token) +{ + return OS_ERR_NOT_IMPLEMENTED; +} + +int32 OS_RwLockReadTake_Impl(const OS_object_token_t *token) +{ + return OS_ERR_NOT_IMPLEMENTED; +} + +int32 OS_RwLockWriteTake_Impl(const OS_object_token_t *token) +{ + return OS_ERR_NOT_IMPLEMENTED; +} + +int32 OS_RwLockGetInfo_Impl(const OS_object_token_t *token, OS_rwlock_prop_t *rw_prop) +{ + return OS_ERR_NOT_IMPLEMENTED; +} diff --git a/src/os/posix/CMakeLists.txt b/src/os/posix/CMakeLists.txt index 7babe2a29..cdeb36fb9 100644 --- a/src/os/posix/CMakeLists.txt +++ b/src/os/posix/CMakeLists.txt @@ -76,6 +76,16 @@ else() ) endif () +if (OSAL_CONFIG_RWLOCK) + list(APPEND POSIX_IMPL_SRCLIST + src/os-impl-rwlock.c + ) +else () + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-rwlock.c + ) +endif () + # Defines an OBJECT target named "osal_posix_impl" with selected source files add_library(osal_posix_impl OBJECT ${POSIX_BASE_SRCLIST} diff --git a/src/os/posix/inc/os-impl-rwlock.h b/src/os/posix/inc/os-impl-rwlock.h new file mode 100644 index 000000000..98517464c --- /dev/null +++ b/src/os/posix/inc/os-impl-rwlock.h @@ -0,0 +1,41 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * + * \ingroup posix + * + */ + +#ifndef OS_IMPL_RWLOCK_H +#define OS_IMPL_RWLOCK_H + +#include "osconfig.h" +#include + +/* RwLocks */ +typedef struct +{ + pthread_rwlock_t id; +} OS_impl_rwlock_internal_record_t; + +/* Tables where the OS object information is stored */ +extern OS_impl_rwlock_internal_record_t OS_impl_rwlock_table[OS_MAX_RWLOCKS]; + +#endif /* OS_IMPL_RWLOCK_H */ diff --git a/src/os/posix/inc/os-posix.h b/src/os/posix/inc/os-posix.h index 1d8024da6..eec05882f 100644 --- a/src/os/posix/inc/os-posix.h +++ b/src/os/posix/inc/os-posix.h @@ -95,6 +95,7 @@ int32 OS_Posix_QueueAPI_Impl_Init(void); int32 OS_Posix_BinSemAPI_Impl_Init(void); int32 OS_Posix_CountSemAPI_Impl_Init(void); int32 OS_Posix_MutexAPI_Impl_Init(void); +int32 OS_Posix_RwLockAPI_Impl_Init(void); int32 OS_Posix_CondVarAPI_Impl_Init(void); int32 OS_Posix_ModuleAPI_Impl_Init(void); int32 OS_Posix_TimeBaseAPI_Impl_Init(void); diff --git a/src/os/posix/src/os-impl-rwlock.c b/src/os/posix/src/os-impl-rwlock.c new file mode 100644 index 000000000..963145ae0 --- /dev/null +++ b/src/os/posix/src/os-impl-rwlock.c @@ -0,0 +1,225 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup posix + * \author joseph.p.hickey@nasa.gov + * + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +#include "os-posix.h" +#include "os-shared-rwlock.h" +#include "os-shared-idmap.h" +#include "os-impl-rwlock.h" + +/* Tables where the OS object information is stored */ +OS_impl_rwlock_internal_record_t OS_impl_rwlock_table[OS_MAX_RWLOCKS]; + +/**************************************************************************************** + RWLOCK API + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Local helper routine, not part of OSAL API. + * + *-----------------------------------------------------------------*/ +int32 OS_Posix_RwLockAPI_Impl_Init(void) +{ + memset(OS_impl_rwlock_table, 0, sizeof(OS_impl_rwlock_table)); + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockCreate_Impl(const OS_object_token_t *token, uint32 options) +{ + int return_code; + pthread_rwlockattr_t rwlock_attr; + OS_impl_rwlock_internal_record_t *impl; + + impl = OS_OBJECT_TABLE_GET(OS_impl_rwlock_table, *token); + + /* + ** initialize the attribute with default values + */ + return_code = pthread_rwlockattr_init(&rwlock_attr); + if (return_code != 0) + { + OS_DEBUG("Error: RwLock could not be created. pthread_rwlockattr_init failed ID = %lu: %s\n", + OS_ObjectIdToInteger(OS_ObjectIdFromToken(token)), strerror(return_code)); + return OS_ERROR; + } + + /* + ** create the rwlock + ** upon successful initialization, the state of the rwlock becomes initialized and unlocked + */ + return_code = pthread_rwlock_init(&impl->id, &rwlock_attr); + if (return_code != 0) + { + OS_DEBUG("Error: RwLock could not be created. ID = %lu: %s\n", + OS_ObjectIdToInteger(OS_ObjectIdFromToken(token)), strerror(return_code)); + return OS_SEM_FAILURE; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockDelete_Impl(const OS_object_token_t *token) +{ + int status; + OS_impl_rwlock_internal_record_t *impl; + + impl = OS_OBJECT_TABLE_GET(OS_impl_rwlock_table, *token); + + status = pthread_rwlock_destroy(&(impl->id)); /* 0 = success */ + + if (status != 0) + { + return OS_ERROR; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockReadGive_Impl(const OS_object_token_t *token) +{ + int status; + OS_impl_rwlock_internal_record_t *impl; + + impl = OS_OBJECT_TABLE_GET(OS_impl_rwlock_table, *token); + + /* + ** Unlock the mutex + */ + status = pthread_rwlock_unlock(&(impl->id)); + if (status != 0) + { + return OS_ERROR; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockWriteGive_Impl(const OS_object_token_t *token) +{ + int status; + OS_impl_rwlock_internal_record_t *impl; + + impl = OS_OBJECT_TABLE_GET(OS_impl_rwlock_table, *token); + + /* + ** Unlock the mutex + */ + status = pthread_rwlock_unlock(&(impl->id)); + if (status != 0) + { + return OS_ERROR; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockReadTake_Impl(const OS_object_token_t *token) +{ + int status; + OS_impl_rwlock_internal_record_t *impl; + + impl = OS_OBJECT_TABLE_GET(OS_impl_rwlock_table, *token); + + /* + ** Lock the mutex + */ + status = pthread_rwlock_rdlock(&(impl->id)); + if (status != 0) + { + return OS_ERROR; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockWriteTake_Impl(const OS_object_token_t *token) +{ + int status; + OS_impl_rwlock_internal_record_t *impl; + + impl = OS_OBJECT_TABLE_GET(OS_impl_rwlock_table, *token); + + /* + ** Lock the mutex + */ + status = pthread_rwlock_wrlock(&(impl->id)); + if (status != 0) + { + return OS_ERROR; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockGetInfo_Impl(const OS_object_token_t *token, OS_rwlock_prop_t *rw_prop) +{ + return OS_SUCCESS; +} diff --git a/src/os/qnx/CMakeLists.txt b/src/os/qnx/CMakeLists.txt index 6e938db94..8bb383ee6 100644 --- a/src/os/qnx/CMakeLists.txt +++ b/src/os/qnx/CMakeLists.txt @@ -44,6 +44,16 @@ else () ) endif () +if (OSAL_CONFIG_RWLOCK) + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-rwlock.c + ) +else () + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-rwlock.c + ) +endif () + # If some form of module loading is configured, # then build the module loader if (OSAL_CONFIG_INCLUDE_DYNAMIC_LOADER) diff --git a/src/os/rtems/CMakeLists.txt b/src/os/rtems/CMakeLists.txt index ba660b836..7aab8e18f 100644 --- a/src/os/rtems/CMakeLists.txt +++ b/src/os/rtems/CMakeLists.txt @@ -34,6 +34,7 @@ set(RTEMS_IMPL_SRCLIST ../portable/os-impl-posix-files.c ../portable/os-impl-posix-dirs.c ../portable/os-impl-no-condvar.c + ../portable/os-impl-no-rwlock.c ) # Currently the "shell output to file" for RTEMS is not implemented diff --git a/src/os/shared/inc/os-shared-idmap.h b/src/os/shared/inc/os-shared-idmap.h index c1dacc285..326efb141 100644 --- a/src/os/shared/inc/os-shared-idmap.h +++ b/src/os/shared/inc/os-shared-idmap.h @@ -49,7 +49,8 @@ typedef enum OS_BINSEM_BASE = OS_QUEUE_BASE + OS_MAX_QUEUES, OS_COUNTSEM_BASE = OS_BINSEM_BASE + OS_MAX_BIN_SEMAPHORES, OS_MUTEX_BASE = OS_COUNTSEM_BASE + OS_MAX_COUNT_SEMAPHORES, - OS_STREAM_BASE = OS_MUTEX_BASE + OS_MAX_MUTEXES, + OS_RWLOCK_BASE = OS_MUTEX_BASE + OS_MAX_MUTEXES, + OS_STREAM_BASE = OS_RWLOCK_BASE + OS_MAX_RWLOCKS, OS_DIR_BASE = OS_STREAM_BASE + OS_MAX_NUM_OPEN_FILES, OS_TIMEBASE_BASE = OS_DIR_BASE + OS_MAX_NUM_OPEN_DIRS, OS_TIMECB_BASE = OS_TIMEBASE_BASE + OS_MAX_TIMEBASES, @@ -131,9 +132,9 @@ typedef int32 (*OS_ObjectIdIteratorProcessFunc_t)(osal_id_t, void *); */ typedef struct { - OS_common_record_t * base; + OS_common_record_t *base; OS_ObjectMatchFunc_t match; - void * arg; + void *arg; osal_index_t limit; OS_object_token_t token; } OS_object_iter_t; @@ -147,6 +148,7 @@ extern OS_common_record_t *const OS_global_queue_table; extern OS_common_record_t *const OS_global_bin_sem_table; extern OS_common_record_t *const OS_global_count_sem_table; extern OS_common_record_t *const OS_global_mutex_table; +extern OS_common_record_t *const OS_global_rwlock_table; extern OS_common_record_t *const OS_global_stream_table; extern OS_common_record_t *const OS_global_dir_table; extern OS_common_record_t *const OS_global_timebase_table; diff --git a/src/os/shared/inc/os-shared-rwlock.h b/src/os/shared/inc/os-shared-rwlock.h new file mode 100644 index 000000000..93eacded6 --- /dev/null +++ b/src/os/shared/inc/os-shared-rwlock.h @@ -0,0 +1,109 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * + * \ingroup shared + * + */ + +#ifndef OS_SHARED_RWLOCK_H +#define OS_SHARED_RWLOCK_H + +#include "osapi-rwlock.h" +#include "os-shared-globaldefs.h" + +typedef struct +{ + char obj_name[OS_MAX_API_NAME]; + osal_id_t last_writer; +} OS_rwlock_internal_record_t; + +/* + * These record types have extra information with each entry. These tables are used + * to share extra data between the common layer and the OS-specific implementation. + */ +extern OS_rwlock_internal_record_t OS_rwlock_table[OS_MAX_RWLOCKS]; + +/*--------------------------------------------------------------------------------------- + Name: OS_RwLockAPI_Init + + Purpose: Initialize the OS-independent layer for rwlock objects + + returns: OS_SUCCESS on success, or relevant error code +---------------------------------------------------------------------------------------*/ +int32 OS_RwLockAPI_Init(void); + +/*---------------------------------------------------------------- + + Purpose: Prepare/allocate OS resources for a rwlock object + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_RwLockCreate_Impl(const OS_object_token_t *token, uint32 options); + +/*---------------------------------------------------------------- + + Purpose: Releases the read lock, which must be owned by the caller + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_RwLockReadGive_Impl(const OS_object_token_t *token); + +/*---------------------------------------------------------------- + + Purpose: Releases the write lock, which must be owned by the caller + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_RwLockWriteGive_Impl(const OS_object_token_t *token); + +/*---------------------------------------------------------------- + + Purpose: Obtain a read lock, blocking the caller as necessary + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_RwLockReadTake_Impl(const OS_object_token_t *token); + +/*---------------------------------------------------------------- + + Purpose: Obtain a write lock, blocking the caller as necessary + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_RwLockWriteTake_Impl(const OS_object_token_t *token); + +/*---------------------------------------------------------------- + + Purpose: Free the OS resources associated with a rwlock object + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_RwLockDelete_Impl(const OS_object_token_t *token); + +/*---------------------------------------------------------------- + + Purpose: Obtain OS-specific information about the rwlock object + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_RwLockGetInfo_Impl(const OS_object_token_t *token, OS_rwlock_prop_t *rw_prop); + +#endif /* OS_SHARED_RWLOCK_H */ diff --git a/src/os/shared/src/osapi-idmap.c b/src/os/shared/src/osapi-idmap.c index 13a3d336a..7ea2770f4 100644 --- a/src/os/shared/src/osapi-idmap.c +++ b/src/os/shared/src/osapi-idmap.c @@ -65,7 +65,7 @@ typedef struct { osal_id_t creator_id; OS_ArgCallback_t user_callback; - void * user_arg; + void *user_arg; } OS_creator_filter_t; /* @@ -94,6 +94,7 @@ OS_common_record_t *const OS_global_queue_table = &OS_common_table[OS_QUEUE_ OS_common_record_t *const OS_global_bin_sem_table = &OS_common_table[OS_BINSEM_BASE]; OS_common_record_t *const OS_global_count_sem_table = &OS_common_table[OS_COUNTSEM_BASE]; OS_common_record_t *const OS_global_mutex_table = &OS_common_table[OS_MUTEX_BASE]; +OS_common_record_t *const OS_global_rwlock_table = &OS_common_table[OS_RWLOCK_BASE]; OS_common_record_t *const OS_global_stream_table = &OS_common_table[OS_STREAM_BASE]; OS_common_record_t *const OS_global_dir_table = &OS_common_table[OS_DIR_BASE]; OS_common_record_t *const OS_global_timebase_table = &OS_common_table[OS_TIMEBASE_BASE]; @@ -141,6 +142,8 @@ uint32 OS_GetMaxForObjectType(osal_objtype_t idtype) return OS_MAX_COUNT_SEMAPHORES; case OS_OBJECT_TYPE_OS_MUTEX: return OS_MAX_MUTEXES; + case OS_OBJECT_TYPE_OS_RWLOCK: + return OS_MAX_RWLOCKS; case OS_OBJECT_TYPE_OS_STREAM: return OS_MAX_NUM_OPEN_FILES; case OS_OBJECT_TYPE_OS_DIR: @@ -181,6 +184,8 @@ uint32 OS_GetBaseForObjectType(osal_objtype_t idtype) return OS_COUNTSEM_BASE; case OS_OBJECT_TYPE_OS_MUTEX: return OS_MUTEX_BASE; + case OS_OBJECT_TYPE_OS_RWLOCK: + return OS_RWLOCK_BASE; case OS_OBJECT_TYPE_OS_STREAM: return OS_STREAM_BASE; case OS_OBJECT_TYPE_OS_DIR: @@ -595,8 +600,8 @@ int32 OS_ObjectIdFindNextFree(OS_object_token_t *token) OS_common_record_t *obj = NULL; OS_objtype_state_t *objtype_state; - base_id = OS_GetBaseForObjectType(token->obj_type); - max_id = OS_GetMaxForObjectType(token->obj_type); + base_id = OS_GetBaseForObjectType(token->obj_type); + max_id = OS_GetMaxForObjectType(token->obj_type); if (max_id == 0) { diff --git a/src/os/shared/src/osapi-rwlock.c b/src/os/shared/src/osapi-rwlock.c new file mode 100644 index 000000000..cbf6578fe --- /dev/null +++ b/src/os/shared/src/osapi-rwlock.c @@ -0,0 +1,325 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup shared + * \author joseph.p.hickey@nasa.gov + * + * This file contains some of the OS APIs abstraction layer code + * that is shared/common across all OS-specific implementations. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ +#include +#include +#include +#include + +/* + * User defined include files + */ +#include "os-shared-idmap.h" +#include "os-shared-rwlock.h" + +/* + * Other OSAL public APIs used by this module + */ +#include "osapi-task.h" + +/* + * Sanity checks on the user-supplied configuration + * The relevant OS_MAX limit should be defined and greater than zero + */ +#if !defined(OS_MAX_RWLOCKS) || (OS_MAX_RWLOCKS <= 0) +#error "osconfig.h must define OS_MAX_RWLOCKS to a valid value" +#endif + +/* + * Global data for the API + */ +enum +{ + LOCAL_NUM_OBJECTS = OS_MAX_RWLOCKS, + LOCAL_OBJID_TYPE = OS_OBJECT_TYPE_OS_RWLOCK +}; + +OS_rwlock_internal_record_t OS_rwlock_table[LOCAL_NUM_OBJECTS]; + +/**************************************************************************************** + RWLOCK API + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Local helper routine, not part of OSAL API. + * Init function for OS-independent layer + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockAPI_Init(void) +{ + memset(OS_rwlock_table, 0, sizeof(OS_rwlock_table)); + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockCreate(osal_id_t *rw_id, const char *rw_name, uint32 options) +{ + int32 return_code; + OS_object_token_t token; + OS_rwlock_internal_record_t *rwlock; + + /* Check parameters */ + OS_CHECK_POINTER(rw_id); + OS_CHECK_APINAME(rw_name); + + /* Note - the common ObjectIdAllocate routine will lock the object type and leave it locked. */ + return_code = OS_ObjectIdAllocateNew(LOCAL_OBJID_TYPE, rw_name, &token); + if (return_code == OS_SUCCESS) + { + rwlock = OS_OBJECT_TABLE_GET(OS_rwlock_table, token); + + /* Reset the table entry and save the name */ + OS_OBJECT_INIT(token, rwlock, obj_name, rw_name); + + /* Now call the OS-specific implementation. This reads info from the table. */ + return_code = OS_RwLockCreate_Impl(&token, options); + + /* Check result, finalize record, and unlock global table. */ + return_code = OS_ObjectIdFinalizeNew(return_code, &token, rw_id); + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockDelete(osal_id_t rw_id) +{ + OS_object_token_t token; + int32 return_code; + + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_EXCLUSIVE, LOCAL_OBJID_TYPE, rw_id, &token); + if (return_code == OS_SUCCESS) + { + return_code = OS_RwLockDelete_Impl(&token); + + /* Complete the operation via the common routine */ + return_code = OS_ObjectIdFinalizeDelete(return_code, &token); + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockReadGive(osal_id_t rw_id) +{ + OS_rwlock_internal_record_t *rwlock; + OS_object_token_t token; + int32 return_code; + osal_id_t self_task; + + /* Check Parameters */ + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_NONE, LOCAL_OBJID_TYPE, rw_id, &token); + if (return_code == OS_SUCCESS) + { + rwlock = OS_OBJECT_TABLE_GET(OS_rwlock_table, token); + + self_task = OS_TaskGetId(); + + /* Ensure no write locks were held while this read lock was held */ + if (!OS_ObjectIdEqual(rwlock->last_writer, OS_OBJECT_ID_UNDEFINED)) + { + OS_DEBUG("WARNING: Task %lu giving read lock on rwlock %lu while write lock held by task %lu\n", + OS_ObjectIdToInteger(self_task), OS_ObjectIdToInteger(rw_id), + OS_ObjectIdToInteger(rwlock->last_writer)); + } + + return_code = OS_RwLockReadGive_Impl(&token); + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockWriteGive(osal_id_t rw_id) +{ + OS_rwlock_internal_record_t *rwlock; + OS_object_token_t token; + int32 return_code; + osal_id_t self_task; + + /* Check Parameters */ + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_NONE, LOCAL_OBJID_TYPE, rw_id, &token); + if (return_code == OS_SUCCESS) + { + rwlock = OS_OBJECT_TABLE_GET(OS_rwlock_table, token); + + self_task = OS_TaskGetId(); + + /* Ensure multiple write locks weren't held */ + if (!OS_ObjectIdEqual(rwlock->last_writer, self_task)) + { + OS_DEBUG("WARNING: Task %lu giving write lock on rwlock %lu while write lock held by task %lu\n", + OS_ObjectIdToInteger(self_task), OS_ObjectIdToInteger(rw_id), + OS_ObjectIdToInteger(rwlock->last_writer)); + } + + rwlock->last_writer = OS_OBJECT_ID_UNDEFINED; + + return_code = OS_RwLockWriteGive_Impl(&token); + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockReadTake(osal_id_t rw_id) +{ + OS_rwlock_internal_record_t *rwlock; + OS_object_token_t token; + int32 return_code; + osal_id_t self_task; + + /* Check Parameters */ + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_NONE, LOCAL_OBJID_TYPE, rw_id, &token); + if (return_code == OS_SUCCESS) + { + rwlock = OS_OBJECT_TABLE_GET(OS_rwlock_table, token); + + self_task = OS_TaskGetId(); + + return_code = OS_RwLockReadTake_Impl(&token); + + /* Ensure no write locks are being held */ + if (return_code == OS_SUCCESS && !OS_ObjectIdEqual(rwlock->last_writer, OS_OBJECT_ID_UNDEFINED)) + { + OS_DEBUG("WARNING: Task %lu taking read lock on rwlock %lu while write lock held by task %lu\n", + OS_ObjectIdToInteger(self_task), OS_ObjectIdToInteger(rw_id), + OS_ObjectIdToInteger(rwlock->last_writer)); + } + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockWriteTake(osal_id_t rw_id) +{ + OS_rwlock_internal_record_t *rwlock; + OS_object_token_t token; + int32 return_code; + + /* Check Parameters */ + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_NONE, LOCAL_OBJID_TYPE, rw_id, &token); + if (return_code == OS_SUCCESS) + { + rwlock = OS_OBJECT_TABLE_GET(OS_rwlock_table, token); + + return_code = OS_RwLockWriteTake_Impl(&token); + if (return_code == OS_SUCCESS) + { + rwlock->last_writer = OS_TaskGetId(); + } + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockGetIdByName(osal_id_t *rw_id, const char *rw_name) +{ + int32 return_code; + + /* Check parameters */ + OS_CHECK_POINTER(rw_id); + OS_CHECK_POINTER(rw_name); + + return_code = OS_ObjectIdFindByName(LOCAL_OBJID_TYPE, rw_name, rw_id); + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_RwLockGetInfo(osal_id_t rw_id, OS_rwlock_prop_t *rw_prop) +{ + OS_common_record_t *record; + int32 return_code; + OS_object_token_t token; + + /* Check parameters */ + OS_CHECK_POINTER(rw_prop); + + memset(rw_prop, 0, sizeof(OS_rwlock_prop_t)); + + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_GLOBAL, LOCAL_OBJID_TYPE, rw_id, &token); + if (return_code == OS_SUCCESS) + { + record = OS_OBJECT_TABLE_GET(OS_global_rwlock_table, token); + + strncpy(rw_prop->name, record->name_entry, sizeof(rw_prop->name) - 1); + rw_prop->creator = record->creator; + + return_code = OS_RwLockGetInfo_Impl(&token, rw_prop); + + OS_ObjectIdRelease(&token); + } + + return return_code; +} diff --git a/src/os/vxworks-rtp/CMakeLists.txt b/src/os/vxworks-rtp/CMakeLists.txt index 78411186d..29f28c7c1 100644 --- a/src/os/vxworks-rtp/CMakeLists.txt +++ b/src/os/vxworks-rtp/CMakeLists.txt @@ -45,6 +45,16 @@ else () ) endif () +if (OSAL_CONFIG_RWLOCK) + list(APPEND POSIX_IMPL_SRCLIST + ../posix/src/os-impl-rwlock.c + ) +else () + list(APPEND POSIX_IMPL_SRCLIST + ../portable/os-impl-no-rwlock.c + ) +endif () + # If some form of module loading is configured, # then build the module loader if (OSAL_CONFIG_INCLUDE_DYNAMIC_LOADER) diff --git a/src/os/vxworks/CMakeLists.txt b/src/os/vxworks/CMakeLists.txt index 2c56ffaa3..4d78d401a 100644 --- a/src/os/vxworks/CMakeLists.txt +++ b/src/os/vxworks/CMakeLists.txt @@ -35,6 +35,7 @@ set(VXWORKS_IMPL_SRCLIST ../portable/os-impl-posix-files.c ../portable/os-impl-posix-dirs.c ../portable/os-impl-no-condvar.c + ../portable/os-impl-no-rwlock.c ) if (OSAL_CONFIG_INCLUDE_SHELL) diff --git a/src/tests/rwlock-test/rwlock-test.c b/src/tests/rwlock-test/rwlock-test.c new file mode 100644 index 000000000..68383a44e --- /dev/null +++ b/src/tests/rwlock-test/rwlock-test.c @@ -0,0 +1,391 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/* +** RwLock read timeout test +*/ +#include + +#include "common_types.h" +#include "osapi.h" +#include "utassert.h" +#include "uttest.h" +#include "utbsp.h" + +#define STACK_SIZE 4096 + +/* Define setup and check functions for UT assert */ +void RwLockSetup(void); +void RwLockCheck(void); + +uint32 orchestrator_stack[STACK_SIZE]; +osal_id_t orchestrator_id; +uint32 orchestrator_failures; + +uint32 reader_1_stack[STACK_SIZE]; +osal_id_t reader_1_id; +uint32 reader_1_failures; + +uint32 reader_2_stack[STACK_SIZE]; +osal_id_t reader_2_id; +uint32 reader_2_failures; + +osal_id_t rw_id; + +bool reader_1_ready; +bool reader_2_ready; + +bool should_run; +bool start_count; + +uint32 counter; + +void orchestrator(void) +{ + int i; + uint32 status; + + OS_printf("Starting ORCHESTRATOR...\n"); + + while (should_run) + { + /* First, acquire the write lock and reset flags */ + start_count = false; + reader_1_ready = false; + reader_2_ready = false; + + /* Wait for other tasks to try to acquire the read lock */ + status = OS_TaskDelay(500); + if (reader_1_ready == true || reader_2_ready == true) + { + ++orchestrator_failures; + OS_printf("ORCHESTRATOR:Error while holding write lock, readers read during rwlock write phase\n"); + } else { + OS_printf("Single-writer only check passed!\n"); + } + + /* Release the write lock to allow readers to take the read lock */ + status = OS_RwLockWriteGive(rw_id); + if (status != OS_SUCCESS) + { + ++orchestrator_failures; + OS_printf("ORCHESTRATOR:Error calling OS_RwLockWriteGive\n"); + } + + /* Wait for readers to set their ready flags, once they've acquire the read lock */ + status = OS_TaskDelay(500); + if (reader_1_ready != true || reader_2_ready != true) + { + ++orchestrator_failures; + OS_printf("ORCHESTRATOR:Error, readers unable to simultaneously read\n"); + } else { + OS_printf("Multiple-reader check passed!\n"); + } + + /* Reset reader flags and signal that they should release their read locks and start counting */ + reader_1_ready = false; + reader_2_ready = false; + start_count = true; + + /* Increment the counter by 100 */ + for (i = 0; i < 100; ++i) + { + status = OS_RwLockWriteTake(rw_id); + if (status != OS_SUCCESS) + { + OS_printf("ORCHESTRATOR:Error unable to take write lock\n"); + ++orchestrator_failures; + } + + ++counter; + status = OS_RwLockWriteGive(rw_id); + if (status != OS_SUCCESS) + { + OS_printf("ORCHESTRATOR:Error unable to give write lock\n"); + ++orchestrator_failures; + } + } + + /* Wait for the readers to finish counting 100 as well */ + while (reader_1_ready != true || reader_2_ready != true) + { + OS_TaskDelay(5); + if (should_run == false) + { + return; + } + } + + /* If the counter wasn't incremented correctly due to a data race, report the failure */ + if (counter % 300 != 0) + { + OS_printf("ORCHESTRATOR:Error counter did not match expected value: %d\n", counter); + ++orchestrator_failures; + } else { + OS_printf("One parallel unit of work completed!\n"); + } + + if (counter >= 1500) { + return; + } + + /* Time limited execution */ + status = OS_RwLockWriteTake(rw_id); + if (status != OS_SUCCESS) + { + ++orchestrator_failures; + OS_printf("ORCHESTRATOR:Error calling OS_RwLockWriteTake\n"); + } + } +} + +void reader_1(void) +{ + int i; + uint32 status; + + OS_printf("Starting READER 1..."); + + while (should_run) + { + /* Taking the read lock will take a while as the orchestrator will hold onto the write lock */ + status = OS_RwLockReadTake(rw_id); + if (status != OS_SUCCESS) + { + ++reader_1_failures; + OS_printf("READER 1:Error calling OS_RwLockReadTake"); + } + + /* Once the read lock is acquired, set the read flag to show the reader read it */ + reader_1_ready = true; + + /* Wait for the command to start counting */ + while (start_count != true) + { + OS_TaskDelay(5); + if (should_run == false) + { + return; + } + } + + /* Once the command has been received return the read lock */ + status = OS_RwLockReadGive(rw_id); + if (status != OS_SUCCESS) + { + ++reader_1_failures; + OS_printf("READER 1:Error calling OS_RwLockReadGive"); + } + + /* Increment the counter by 100 */ + for (i = 0; i < 100; ++i) + { + status = OS_RwLockWriteTake(rw_id); + if (status != OS_SUCCESS) + { + OS_printf("READER 1:Error unable to take write lock\n"); + ++reader_1_failures; + } + + ++counter; + status = OS_RwLockWriteGive(rw_id); + if (status != OS_SUCCESS) + { + OS_printf("READER 1:Error unable to give write lock\n"); + ++reader_1_failures; + } + } + + /* Signal that the reader is ready to repeat the test */ + reader_1_ready = true; + while (reader_1_ready == true) + { + OS_TaskDelay(5); + if (should_run == false) + { + return; + } + } + } +} + +void reader_2(void) +{ + int i; + uint32 status; + + OS_printf("Starting READER 2..."); + + while (should_run) + { + /* Taking the read lock will take a while as the orchestrator will hold onto the write lock */ + status = OS_RwLockReadTake(rw_id); + if (status != OS_SUCCESS) + { + ++reader_2_failures; + OS_printf("READER 2:Error calling OS_RwLockReadTake"); + } + + /* Once the read lock is acquired, set the read flag to show the reader read it */ + reader_2_ready = true; + + /* Wait for the command to start counting */ + while (start_count != true) + { + OS_TaskDelay(5); + if (should_run == false) + { + return; + } + } + + /* Once the command has been received return the read lock */ + status = OS_RwLockReadGive(rw_id); + if (status != OS_SUCCESS) + { + ++reader_2_failures; + OS_printf("READER 2:Error calling OS_RwLockReadGive"); + } + + /* Increment the counter by 100 */ + for (i = 0; i < 100; ++i) + { + status = OS_RwLockWriteTake(rw_id); + if (status != OS_SUCCESS) + { + OS_printf("READER 2:Error unable to take write lock\n"); + ++reader_2_failures; + } + + ++counter; + status = OS_RwLockWriteGive(rw_id); + if (status != OS_SUCCESS) + { + OS_printf("READER 2:Error unable to give write lock\n"); + ++reader_2_failures; + } + } + + /* Signal that the reader is ready to repeat the test */ + reader_2_ready = true; + while (reader_2_ready == true) + { + OS_TaskDelay(5); + if (should_run == false) + { + return; + } + } + } +} + +bool RwLockTest_CheckImpl(void) +{ + int32 status; + osal_id_t rwid; + + status = OS_RwLockCreate(&rwid, "ut", 0); + if (status == OS_SUCCESS) + { + OS_RwLockDelete(rwid); + } + + return (status != OS_ERR_NOT_IMPLEMENTED); +} + +void UtTest_Setup(void) +{ + if (OS_API_Init() != OS_SUCCESS) + { + UtAssert_Abort("OS_API_Init() failed"); + } + + /* the test should call OS_API_Teardown() before exiting */ + UtTest_AddTeardown(OS_API_Teardown, "Cleanup"); + + /* + * Register the test setup and check routines in UT assert + */ + if (RwLockTest_CheckImpl()) + { + UtTest_Add(RwLockCheck, RwLockSetup, NULL, "RwLockTest"); + } + else + { + UtAssert_MIR("Readers-writer locks not implemented; skipping tests"); + } +} + +void RwLockSetup(void) +{ + uint32 status; + + orchestrator_failures = 0; + reader_1_failures = 0; + reader_2_failures = 0; + counter = 0; + reader_1_ready = false; + reader_2_ready = false; + start_count = false; + should_run = true; + + /* Create the RwLock */ + status = OS_RwLockCreate(&rw_id, "rwlock", 0); + UtAssert_True(status == OS_SUCCESS, "RwLock ID=%lx, status=%d\n", OS_ObjectIdToInteger(rw_id), (int)status); + + /* Test for RwLock read nesting */ + status = OS_RwLockReadTake(rw_id); + UtAssert_True(status == OS_SUCCESS, "OS_RwLockReadTake 1, status=%d\n", (int)status); + + status = OS_RwLockReadTake(rw_id); + UtAssert_True(status == OS_SUCCESS, "OS_RwLockReadTake 2, status=%d\n", (int)status); + + status = OS_RwLockReadGive(rw_id); + UtAssert_True(status == OS_SUCCESS, "OS_RwLockReadGive 2, status=%d\n", (int)status); + + status = OS_RwLockReadGive(rw_id); + UtAssert_True(status == OS_SUCCESS, "OS_RwLockReadGive 1, status=%d\n", (int)status); + + /* Ensure the orchestrator has the write lock before the test begins. */ + status = OS_RwLockWriteTake(rw_id); + UtAssert_True(status == OS_SUCCESS, "OS_RwLockWriteTake, status=%d\n", (int)status); + + /* Create the tasks */ + status = OS_TaskCreate(&reader_1_id, "Reader 1", reader_1, OSAL_STACKPTR_C(reader_1_stack), sizeof(reader_1_stack), + OSAL_PRIORITY_C(100), 0); + UtAssert_True(status == OS_SUCCESS, "Reader ID=%lx, status=%d", OS_ObjectIdToInteger(reader_1_id), (int)status); + + status = OS_TaskCreate(&reader_2_id, "Reader 2", reader_2, OSAL_STACKPTR_C(reader_2_stack), sizeof(reader_2_stack), + OSAL_PRIORITY_C(100), 0); + UtAssert_True(status == OS_SUCCESS, "Reader ID=%lx, status=%d", OS_ObjectIdToInteger(reader_2_id), (int)status); + + orchestrator(); + + /* Delete the tasks */ + should_run = false; + OS_TaskDelete(reader_1_id); + OS_TaskDelete(reader_2_id); +} + +void RwLockCheck(void) +{ + /* None of the tasks should have any failures in their own counters */ + UtAssert_True(orchestrator_failures == 0, "Orchestrator failures = %u", (unsigned int)orchestrator_failures); + UtAssert_True(reader_1_failures == 0, "Reader 1 failures = %u", (unsigned int)reader_1_failures); + UtAssert_True(reader_2_failures == 0, "Reader 2 failures = %u", (unsigned int)reader_2_failures); +} diff --git a/src/unit-test-coverage/portable/src/coveragetest-no-rwlock.c b/src/unit-test-coverage/portable/src/coveragetest-no-rwlock.c new file mode 100644 index 000000000..f765feae7 --- /dev/null +++ b/src/unit-test-coverage/portable/src/coveragetest-no-rwlock.c @@ -0,0 +1,127 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup portable + * \author joseph.p.hickey@nasa.gov + * + */ + +#include "os-portable-coveragetest.h" +#include "os-shared-rwlock.h" + +void Test_OS_RwLockCreate_Impl(void) +{ + /* Test Case For: + * int32 OS_RwLockCreate_Impl(const OS_object_token_t *token, uint32 options) + */ + + OSAPI_TEST_FUNCTION_RC(OS_RwLockCreate_Impl, (UT_INDEX_0, 0), OS_ERR_NOT_IMPLEMENTED); +} + +void Test_OS_RwLockDelete_Impl(void) +{ + /* Test Case For: + * int32 OS_RwLockDelete_Impl(const OS_object_token_t *token, uint32 options) + */ + + OSAPI_TEST_FUNCTION_RC(OS_RwLockDelete_Impl, (UT_INDEX_0), OS_ERR_NOT_IMPLEMENTED); +} + +void Test_OS_RwLockReadGive_Impl(void) +{ + /* Test Case For: + * int32 OS_RwLockReadGive_Impl(const OS_object_token_t *token) + */ + + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadGive_Impl, (UT_INDEX_0), OS_ERR_NOT_IMPLEMENTED); +} + +void Test_OS_RwLockWriteGive_Impl(void) +{ + /* Test Case For: + * int32 OS_RwLockWriteGive_Impl(const OS_object_token_t *token) + */ + + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteGive_Impl, (UT_INDEX_0), OS_ERR_NOT_IMPLEMENTED); +} + +void Test_OS_RwLockReadTake_Impl(void) +{ + /* Test Case For: + * int32 OS_RwLockReadTake_Impl(const OS_object_token_t *token) + */ + + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadTake_Impl, (UT_INDEX_0), OS_ERR_NOT_IMPLEMENTED); +} + +void Test_OS_RwLockWriteTake_Impl(void) +{ + /* Test Case For: + * int32 OS_RwLockWriteTake_Impl(const OS_object_token_t *token) + */ + + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteTake_Impl, (UT_INDEX_0), OS_ERR_NOT_IMPLEMENTED); +} + +void Test_OS_RwLockGetInfo_Impl(void) +{ + /* Test Case For: + * int32 OS_RwLockGetInfo_Impl(const OS_object_token_t *token, OS_rwlock_prop_t *rw_prop) + */ + OS_rwlock_prop_t rw_prop; + + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetInfo_Impl, (UT_INDEX_0, &rw_prop), OS_ERR_NOT_IMPLEMENTED); +} + +/* ------------------- End of test cases --------------------------------------*/ + +/* Osapi_Test_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void Osapi_Test_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Osapi_Test_Teardown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void Osapi_Test_Teardown(void) {} + +/* UtTest_Setup + * + * Purpose: + * Registers the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(OS_RwLockCreate_Impl); + ADD_TEST(OS_RwLockDelete_Impl); + ADD_TEST(OS_RwLockReadGive_Impl); + ADD_TEST(OS_RwLockWriteGive_Impl); + ADD_TEST(OS_RwLockReadTake_Impl); + ADD_TEST(OS_RwLockWriteTake_Impl); + ADD_TEST(OS_RwLockGetInfo_Impl); +} diff --git a/src/unit-test-coverage/shared/CMakeLists.txt b/src/unit-test-coverage/shared/CMakeLists.txt index 2b3b98eb4..c8a5ef2ca 100644 --- a/src/unit-test-coverage/shared/CMakeLists.txt +++ b/src/unit-test-coverage/shared/CMakeLists.txt @@ -19,6 +19,7 @@ set(MODULE_LIST network printf queue + rwlock select sockets task diff --git a/src/unit-test-coverage/shared/src/coveragetest-idmap.c b/src/unit-test-coverage/shared/src/coveragetest-idmap.c index 1b8f8ea8a..a40dc67fe 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-idmap.c +++ b/src/unit-test-coverage/shared/src/coveragetest-idmap.c @@ -1041,7 +1041,7 @@ void Test_OS_ForEachObject(void) UtAssert_True(Count.TaskCount == 1, "OS_ForEachObject() TaskCount (%lu) == 1", (unsigned long)Count.TaskCount); UtAssert_True(Count.QueueCount == 1, "OS_ForEachObject() QueueCount (%lu) == 1", (unsigned long)Count.QueueCount); UtAssert_True(Count.MutexCount == 1, "OS_ForEachObject() MutexCount (%lu) == 1", (unsigned long)Count.MutexCount); - UtAssert_True(Count.OtherCount == 10, "OS_ForEachObject() OtherCount (%lu) == 9", (unsigned long)Count.OtherCount); + UtAssert_True(Count.OtherCount == 11, "OS_ForEachObject() OtherCount (%lu) == 11", (unsigned long)Count.OtherCount); OS_ForEachObjectOfType(OS_OBJECT_TYPE_OS_QUEUE, self_id.id, ObjTypeCounter, &Count); UtAssert_True(Count.TaskCount == 1, "OS_ForEachObjectOfType(), creator %08lx TaskCount (%lu) == 1", diff --git a/src/unit-test-coverage/shared/src/coveragetest-rwlock.c b/src/unit-test-coverage/shared/src/coveragetest-rwlock.c new file mode 100644 index 000000000..bc5850da4 --- /dev/null +++ b/src/unit-test-coverage/shared/src/coveragetest-rwlock.c @@ -0,0 +1,259 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup shared + * \author joseph.p.hickey@nasa.gov + * + */ +#include "os-shared-coveragetest.h" +#include "os-shared-rwlock.h" + +#include "OCS_string.h" + +/* +********************************************************************************** +** PUBLIC API FUNCTIONS +********************************************************************************** +*/ + +void Test_OS_RwLockAPI_Init(void) +{ + /* + * Test Case For: + * int32 OS_RwLockAPI_Init(void) + */ + OSAPI_TEST_FUNCTION_RC(OS_RwLockAPI_Init(), OS_SUCCESS); +} + +void Test_OS_RwLockCreate(void) +{ + /* + * Test Case For: + * int32 OS_RwLockCreate (uint32 *rw_id, const char *rw_name, uint32 options) + */ + osal_id_t objid = OS_OBJECT_ID_UNDEFINED; + + OSAPI_TEST_FUNCTION_RC(OS_RwLockCreate(&objid, "UT", 0), OS_SUCCESS); + OSAPI_TEST_OBJID(objid, !=, OS_OBJECT_ID_UNDEFINED); + + OSAPI_TEST_FUNCTION_RC(OS_RwLockCreate(NULL, "UT", 0), OS_INVALID_POINTER); + OSAPI_TEST_FUNCTION_RC(OS_RwLockCreate(&objid, NULL, 0), OS_INVALID_POINTER); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdAllocateNew), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_RwLockCreate(&objid, "UT", 0), OS_ERROR); + + UT_SetDefaultReturnValue(UT_KEY(OCS_memchr), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_RwLockCreate(&objid, "UT", 0), OS_ERR_NAME_TOO_LONG); +} + +void Test_OS_RwLockDelete(void) +{ + /* + * Test Case For: + * int32 OS_RwLockDelete (uint32 rw_id) + */ + + OSAPI_TEST_FUNCTION_RC(OS_RwLockDelete(UT_OBJID_1), OS_SUCCESS); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_RwLockDelete(UT_OBJID_1), OS_ERROR); +} + +void Test_OS_RwLockReadGive(void) +{ + /* + * Test Case For: + * int32 OS_RwLockReadGive ( uint32 rw_id ) + */ + OS_rwlock_internal_record_t *rwlock; + + /* Call when held by a writer. This still works (or at least it calls the OS impl) + * but should generate a debug message */ + rwlock = &OS_rwlock_table[1]; + rwlock->last_writer = OS_TaskGetId(); + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadGive(UT_OBJID_1), OS_SUCCESS); + + /* Since rwlocks have no mechanism to check if a thread holds a read lock, this will always work */ + rwlock->last_writer = OS_OBJECT_ID_UNDEFINED; + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadGive(UT_OBJID_1), OS_SUCCESS); + + /* writer should still be undefined */ + UtAssert_True(!OS_ObjectIdDefined(rwlock->last_writer), "RwLock writer unset"); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadGive(UT_OBJID_1), OS_ERROR); +} + +void Test_OS_RwLockWriteGive(void) +{ + /* + * Test Case For: + * int32 OS_RwLockWriteGive ( uint32 rw_id ) + */ + OS_rwlock_internal_record_t *rwlock; + + /* Set up for "last writer" matching the calling task (nominal) */ + rwlock = &OS_rwlock_table[1]; + rwlock->last_writer = OS_TaskGetId(); + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteGive(UT_OBJID_1), OS_SUCCESS); + + /* writer should be unset */ + UtAssert_True(!OS_ObjectIdDefined(rwlock->last_writer), "RwLock writer unset"); + + /* Call again when not held by a writer. This still works (or at least it calls the OS impl) + * but should generate a debug message */ + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteGive(UT_OBJID_1), OS_SUCCESS); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteGive(UT_OBJID_1), OS_ERROR); +} + +void Test_OS_RwLockReadTake(void) +{ + /* + * Test Case For: + * int32 OS_RwLockReadTake ( uint32 rw_id ) + */ + OS_rwlock_internal_record_t *rwlock; + + /* Set up for "last writer" being undefined (nominal) */ + rwlock = &OS_rwlock_table[1]; + rwlock->last_writer = OS_OBJECT_ID_UNDEFINED; + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadTake(UT_OBJID_1), OS_SUCCESS); + + /* writer shouldn't be set */ + UtAssert_True(!OS_ObjectIdDefined(rwlock->last_writer), "RwLock writer unset"); + + UT_SetDefaultReturnValue(UT_KEY(OS_RwLockReadTake_Impl), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadTake(UT_OBJID_1), OS_ERROR); + + /* Try and get the debug message to print */ + rwlock->last_writer = OS_OBJECT_ID_RESERVED; + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadTake(UT_OBJID_1), OS_ERROR); + + UT_SetDefaultReturnValue(UT_KEY(OS_RwLockReadTake_Impl), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadTake(UT_OBJID_1), OS_SUCCESS); + rwlock->last_writer = OS_OBJECT_ID_UNDEFINED; + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_RwLockReadTake(UT_OBJID_1), OS_ERR_INVALID_ID); +} + +void Test_OS_RwLockWriteTake(void) +{ + /* + * Test Case For: + * int32 OS_RwLockWriteTake ( uint32 rw_id ) + */ + OS_rwlock_internal_record_t *rwlock; + + /* Set up for "last writer" being undefined (nominal) */ + rwlock = &OS_rwlock_table[1]; + rwlock->last_writer = OS_OBJECT_ID_UNDEFINED; + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteTake(UT_OBJID_1), OS_SUCCESS); + + /* writer should be set */ + UtAssert_True(OS_ObjectIdDefined(rwlock->last_writer), "RwLock writer set"); + + /* Call again when holding write lock. This still works (or at least it calls the OS impl) */ + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteTake(UT_OBJID_1), OS_SUCCESS); + + UT_SetDefaultReturnValue(UT_KEY(OS_RwLockWriteTake_Impl), OS_ERROR); + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteTake(UT_OBJID_1), OS_ERROR); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_RwLockWriteTake(UT_OBJID_1), OS_ERR_INVALID_ID); +} + +void Test_OS_RwLockGetIdByName(void) +{ + /* + * Test Case For: + * int32 OS_RwLockGetIdByName (uint32 *rw_id, const char *rw_name) + */ + osal_id_t objid = OS_OBJECT_ID_UNDEFINED; + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdFindByName), OS_SUCCESS); + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetIdByName(&objid, "UT"), OS_SUCCESS); + OSAPI_TEST_OBJID(objid, !=, OS_OBJECT_ID_UNDEFINED); + UT_ClearDefaultReturnValue(UT_KEY(OS_ObjectIdFindByName)); + + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetIdByName(&objid, "NF"), OS_ERR_NAME_NOT_FOUND); + + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetIdByName(NULL, "UT"), OS_INVALID_POINTER); + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetIdByName(&objid, NULL), OS_INVALID_POINTER); +} + +void Test_OS_RwLockGetInfo(void) +{ + /* + * Test Case For: + * int32 OS_RwLockGetInfo (uint32 rw_id, OS_rwlock_prop_t *rw_prop) + */ + OS_rwlock_prop_t prop; + + memset(&prop, 0, sizeof(prop)); + + OS_UT_SetupBasicInfoTest(OS_OBJECT_TYPE_OS_RWLOCK, UT_INDEX_1, "ABC", UT_OBJID_OTHER); + + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetInfo(UT_OBJID_1, &prop), OS_SUCCESS); + + OSAPI_TEST_OBJID(prop.creator, ==, UT_OBJID_OTHER); + UtAssert_True(strcmp(prop.name, "ABC") == 0, "prop.name (%s) == ABC", prop.name); + + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetInfo(UT_OBJID_1, NULL), OS_INVALID_POINTER); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_RwLockGetInfo(UT_OBJID_1, &prop), OS_ERR_INVALID_ID); +} + +/* Osapi_Test_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void Osapi_Test_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Osapi_Test_Teardown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void Osapi_Test_Teardown(void) {} + +/* + * Register the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(OS_RwLockAPI_Init); + ADD_TEST(OS_RwLockCreate); + ADD_TEST(OS_RwLockDelete); + ADD_TEST(OS_RwLockReadGive); + ADD_TEST(OS_RwLockWriteGive); + ADD_TEST(OS_RwLockReadTake); + ADD_TEST(OS_RwLockWriteTake); + ADD_TEST(OS_RwLockGetIdByName); + ADD_TEST(OS_RwLockGetInfo); +} diff --git a/src/unit-test-coverage/shared/src/os-shared-coverage-support.c b/src/unit-test-coverage/shared/src/os-shared-coverage-support.c index bbfe7878b..9ac25e8e7 100644 --- a/src/unit-test-coverage/shared/src/os-shared-coverage-support.c +++ b/src/unit-test-coverage/shared/src/os-shared-coverage-support.c @@ -101,6 +101,9 @@ void OS_UT_SetupBasicInfoTest(osal_objtype_t obj_type, osal_index_t test_idx, co case OS_OBJECT_TYPE_OS_CONDVAR: rptr = OS_global_condvar_table; break; + case OS_OBJECT_TYPE_OS_RWLOCK: + rptr = OS_global_rwlock_table; + break; default: rptr = NULL; break; diff --git a/src/unit-test-coverage/ut-stubs/CMakeLists.txt b/src/unit-test-coverage/ut-stubs/CMakeLists.txt index d96eef819..41c67910b 100644 --- a/src/unit-test-coverage/ut-stubs/CMakeLists.txt +++ b/src/unit-test-coverage/ut-stubs/CMakeLists.txt @@ -126,6 +126,7 @@ set(OSAL_SHARED_IMPL_HEADERS ${OSAL_SOURCE_DIR}/src/os/shared/inc/os-shared-network.h ${OSAL_SOURCE_DIR}/src/os/shared/inc/os-shared-printf.h ${OSAL_SOURCE_DIR}/src/os/shared/inc/os-shared-queue.h + ${OSAL_SOURCE_DIR}/src/os/shared/inc/os-shared-rwlock.h ${OSAL_SOURCE_DIR}/src/os/shared/inc/os-shared-select.h ${OSAL_SOURCE_DIR}/src/os/shared/inc/os-shared-shell.h ${OSAL_SOURCE_DIR}/src/os/shared/inc/os-shared-sockets.h @@ -183,6 +184,7 @@ add_library(ut_osapi_impl_stubs STATIC EXCLUDE_FROM_ALL src/os-shared-network-impl-stubs.c src/os-shared-printf-impl-stubs.c src/os-shared-queue-impl-stubs.c + src/os-shared-rwlock-impl-stubs.c src/os-shared-select-impl-stubs.c src/os-shared-shell-impl-stubs.c src/os-shared-sockets-impl-handlers.c @@ -211,6 +213,7 @@ add_library(ut_osapi_init_stubs STATIC EXCLUDE_FROM_ALL src/os-shared-mutex-init-stubs.c src/os-shared-network-init-stubs.c src/os-shared-queue-init-stubs.c + src/os-shared-queue-init-stubs.c src/os-shared-sockets-init-stubs.c src/os-shared-task-init-stubs.c src/os-shared-timebase-init-stubs.c @@ -259,6 +262,7 @@ add_library(ut_osapi_table_stubs STATIC EXCLUDE_FROM_ALL src/osapi-shared-module-table-stubs.c src/osapi-shared-mutex-table-stubs.c src/osapi-shared-queue-table-stubs.c + src/osapi-shared-rwlock-table-stubs.c src/osapi-shared-stream-table-stubs.c src/osapi-shared-task-table-stubs.c src/osapi-shared-timebase-table-stubs.c diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-impl-stubs.c new file mode 100644 index 000000000..856731810 --- /dev/null +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-impl-stubs.c @@ -0,0 +1,140 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * @file + * + * Auto-Generated stub implementations for functions defined in os-shared-rwlock header + */ + +#include "os-shared-rwlock.h" +#include "utgenstub.h" + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockCreate_Impl() + * ---------------------------------------------------- + */ +int32 OS_RwLockCreate_Impl(const OS_object_token_t *token, uint32 options) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockCreate_Impl, int32); + + UT_GenStub_AddParam(OS_RwLockCreate_Impl, const OS_object_token_t *, token); + UT_GenStub_AddParam(OS_RwLockCreate_Impl, uint32, options); + + UT_GenStub_Execute(OS_RwLockCreate_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockCreate_Impl, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockDelete_Impl() + * ---------------------------------------------------- + */ +int32 OS_RwLockDelete_Impl(const OS_object_token_t *token) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockDelete_Impl, int32); + + UT_GenStub_AddParam(OS_RwLockDelete_Impl, const OS_object_token_t *, token); + + UT_GenStub_Execute(OS_RwLockDelete_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockDelete_Impl, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockGetInfo_Impl() + * ---------------------------------------------------- + */ +int32 OS_RwLockGetInfo_Impl(const OS_object_token_t *token, OS_rwlock_prop_t *rw_prop) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockGetInfo_Impl, int32); + + UT_GenStub_AddParam(OS_RwLockGetInfo_Impl, const OS_object_token_t *, token); + UT_GenStub_AddParam(OS_RwLockGetInfo_Impl, OS_rwlock_prop_t *, rw_prop); + + UT_GenStub_Execute(OS_RwLockGetInfo_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockGetInfo_Impl, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockReadGive_Impl() + * ---------------------------------------------------- + */ +int32 OS_RwLockReadGive_Impl(const OS_object_token_t *token) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockReadGive_Impl, int32); + + UT_GenStub_AddParam(OS_RwLockReadGive_Impl, const OS_object_token_t *, token); + + UT_GenStub_Execute(OS_RwLockReadGive_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockReadGive_Impl, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockReadTake_Impl() + * ---------------------------------------------------- + */ +int32 OS_RwLockReadTake_Impl(const OS_object_token_t *token) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockReadTake_Impl, int32); + + UT_GenStub_AddParam(OS_RwLockReadTake_Impl, const OS_object_token_t *, token); + + UT_GenStub_Execute(OS_RwLockReadTake_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockReadTake_Impl, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockWriteGive_Impl() + * ---------------------------------------------------- + */ +int32 OS_RwLockWriteGive_Impl(const OS_object_token_t *token) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockWriteGive_Impl, int32); + + UT_GenStub_AddParam(OS_RwLockWriteGive_Impl, const OS_object_token_t *, token); + + UT_GenStub_Execute(OS_RwLockWriteGive_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockWriteGive_Impl, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockWriteTake_Impl() + * ---------------------------------------------------- + */ +int32 OS_RwLockWriteTake_Impl(const OS_object_token_t *token) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockWriteTake_Impl, int32); + + UT_GenStub_AddParam(OS_RwLockWriteTake_Impl, const OS_object_token_t *, token); + + UT_GenStub_Execute(OS_RwLockWriteTake_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockWriteTake_Impl, int32); +} diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-init-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-init-stubs.c new file mode 100644 index 000000000..fcbe827c6 --- /dev/null +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-rwlock-init-stubs.c @@ -0,0 +1,40 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * @file + * + * Auto-Generated stub implementations for functions defined in os-shared-rwlock header + */ + +#include "os-shared-rwlock.h" +#include "utgenstub.h" + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockAPI_Init() + * ---------------------------------------------------- + */ +int32 OS_RwLockAPI_Init(void) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockAPI_Init, int32); + + UT_GenStub_Execute(OS_RwLockAPI_Init, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockAPI_Init, int32); +} diff --git a/src/unit-test-coverage/ut-stubs/src/osapi-shared-idmap-table-stubs.c b/src/unit-test-coverage/ut-stubs/src/osapi-shared-idmap-table-stubs.c index 42b2f26aa..04c778597 100644 --- a/src/unit-test-coverage/ut-stubs/src/osapi-shared-idmap-table-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/osapi-shared-idmap-table-stubs.c @@ -41,6 +41,7 @@ OS_common_record_t OS_stub_timecb_table[OS_MAX_TIMERS]; OS_common_record_t OS_stub_stream_table[OS_MAX_NUM_OPEN_FILES]; OS_common_record_t OS_stub_dir_table[OS_MAX_NUM_OPEN_DIRS]; OS_common_record_t OS_stub_condvar_table[OS_MAX_CONDVARS]; +OS_common_record_t OS_stub_rwlock_table[OS_MAX_RWLOCKS]; OS_common_record_t *const OS_global_task_table = OS_stub_task_table; OS_common_record_t *const OS_global_queue_table = OS_stub_queue_table; @@ -55,3 +56,4 @@ OS_common_record_t *const OS_global_module_table = OS_stub_module_table; OS_common_record_t *const OS_global_filesys_table = OS_stub_filesys_table; OS_common_record_t *const OS_global_console_table = OS_stub_console_table; OS_common_record_t *const OS_global_condvar_table = OS_stub_condvar_table; +OS_common_record_t *const OS_global_rwlock_table = OS_stub_rwlock_table; diff --git a/src/unit-test-coverage/ut-stubs/src/osapi-shared-rwlock-table-stubs.c b/src/unit-test-coverage/ut-stubs/src/osapi-shared-rwlock-table-stubs.c new file mode 100644 index 000000000..6e4f5946e --- /dev/null +++ b/src/unit-test-coverage/ut-stubs/src/osapi-shared-rwlock-table-stubs.c @@ -0,0 +1,32 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup ut-stubs + * \author joseph.p.hickey@nasa.gov + * + */ + +#include +#include +#include "utstubs.h" + +#include "os-shared-rwlock.h" + +OS_rwlock_internal_record_t OS_rwlock_table[OS_MAX_RWLOCKS]; diff --git a/src/ut-stubs/CMakeLists.txt b/src/ut-stubs/CMakeLists.txt index 1b3908d35..961550427 100644 --- a/src/ut-stubs/CMakeLists.txt +++ b/src/ut-stubs/CMakeLists.txt @@ -29,6 +29,7 @@ set(OSAL_PUBLIC_API_HEADERS ${OSAL_SOURCE_DIR}/src/os/inc/osapi-network.h ${OSAL_SOURCE_DIR}/src/os/inc/osapi-printf.h ${OSAL_SOURCE_DIR}/src/os/inc/osapi-queue.h + ${OSAL_SOURCE_DIR}/src/os/inc/osapi-rwlock.h ${OSAL_SOURCE_DIR}/src/os/inc/osapi-select.h ${OSAL_SOURCE_DIR}/src/os/inc/osapi-shell.h ${OSAL_SOURCE_DIR}/src/os/inc/osapi-sockets.h @@ -86,6 +87,8 @@ add_library(ut_osapi_stubs STATIC osapi-printf-handlers.c osapi-queue-stubs.c osapi-queue-handlers.c + osapi-rwlock-stubs.c + osapi-rwlock-handlers.c osapi-select-stubs.c osapi-shell-stubs.c osapi-sockets-stubs.c diff --git a/src/ut-stubs/osapi-rwlock-handlers.c b/src/ut-stubs/osapi-rwlock-handlers.c new file mode 100644 index 000000000..af7babe59 --- /dev/null +++ b/src/ut-stubs/osapi-rwlock-handlers.c @@ -0,0 +1,111 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * + * Stub implementations for the functions defined in the OSAL API + * + * The stub implementation can be used for unit testing applications built + * on top of OSAL. The stubs do not do any real function, but allow + * the return code to be crafted such that error paths in the application + * can be executed. + */ + +#include "osapi-rwlock.h" /* OSAL public API for this subsystem */ +#include "utstub-helpers.h" + +/* + * ----------------------------------------------------------------- + * Default handler implementation for 'OS_RwLockCreate' stub + * ----------------------------------------------------------------- + */ +void UT_DefaultHandler_OS_RwLockCreate(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + osal_id_t *rw_id = UT_Hook_GetArgValueByName(Context, "rw_id", osal_id_t *); + int32 status; + + UT_Stub_GetInt32StatusCode(Context, &status); + + if (status == OS_SUCCESS) + { + *rw_id = UT_AllocStubObjId(OS_OBJECT_TYPE_OS_RWLOCK); + } + else + { + *rw_id = UT_STUB_FAKE_OBJECT_ID; + } +} + +/* + * ----------------------------------------------------------------- + * Default handler implementation for 'OS_RwLockDelete' stub + * ----------------------------------------------------------------- + */ +void UT_DefaultHandler_OS_RwLockDelete(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + osal_id_t rw_id = UT_Hook_GetArgValueByName(Context, "rw_id", osal_id_t); + int32 status; + + UT_Stub_GetInt32StatusCode(Context, &status); + + if (status == OS_SUCCESS) + { + UT_DeleteStubObjId(OS_OBJECT_TYPE_OS_MUTEX, rw_id); + } +} + +/* + * ----------------------------------------------------------------- + * Default handler implementation for 'OS_RwLockGetIdByName' stub + * ----------------------------------------------------------------- + */ +void UT_DefaultHandler_OS_RwLockGetIdByName(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + osal_id_t *rw_id = UT_Hook_GetArgValueByName(Context, "rw_id", osal_id_t *); + int32 status; + + UT_Stub_GetInt32StatusCode(Context, &status); + + if (status == OS_SUCCESS && + UT_Stub_CopyToLocal(UT_KEY(OS_RwLockGetIdByName), rw_id, sizeof(*rw_id)) < sizeof(*rw_id)) + { + UT_ObjIdCompose(1, OS_OBJECT_TYPE_OS_RWLOCK, rw_id); + } +} + +/* + * ----------------------------------------------------------------- + * Default handler implementation for 'OS_RwLockGetInfo' stub + * ----------------------------------------------------------------- + */ +void UT_DefaultHandler_OS_RwLockGetInfo(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + OS_rwlock_prop_t *rw_prop = UT_Hook_GetArgValueByName(Context, "rw_prop", OS_rwlock_prop_t *); + int32 status; + + UT_Stub_GetInt32StatusCode(Context, &status); + + if (status == OS_SUCCESS && + UT_Stub_CopyToLocal(UT_KEY(OS_RwLockGetInfo), rw_prop, sizeof(*rw_prop)) < sizeof(*rw_prop)) + { + strncpy(rw_prop->name, "Name", sizeof(rw_prop->name) - 1); + rw_prop->name[sizeof(rw_prop->name) - 1] = '\0'; + UT_ObjIdCompose(1, OS_OBJECT_TYPE_OS_TASK, &rw_prop->creator); + } +} diff --git a/src/ut-stubs/osapi-rwlock-stubs.c b/src/ut-stubs/osapi-rwlock-stubs.c new file mode 100644 index 000000000..67e4cc839 --- /dev/null +++ b/src/ut-stubs/osapi-rwlock-stubs.c @@ -0,0 +1,163 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * @file + * + * Auto-Generated stub implementations for functions defined in osapi-rwlock header + */ + +#include "osapi-rwlock.h" +#include "utgenstub.h" + +void UT_DefaultHandler_OS_RwLockCreate(void *, UT_EntryKey_t, const UT_StubContext_t *); +void UT_DefaultHandler_OS_RwLockDelete(void *, UT_EntryKey_t, const UT_StubContext_t *); +void UT_DefaultHandler_OS_RwLockGetIdByName(void *, UT_EntryKey_t, const UT_StubContext_t *); +void UT_DefaultHandler_OS_RwLockGetInfo(void *, UT_EntryKey_t, const UT_StubContext_t *); + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockCreate() + * ---------------------------------------------------- + */ +int32 OS_RwLockCreate(osal_id_t *rw_id, const char *rw_name, uint32 options) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockCreate, int32); + + UT_GenStub_AddParam(OS_RwLockCreate, osal_id_t *, rw_id); + UT_GenStub_AddParam(OS_RwLockCreate, const char *, rw_name); + UT_GenStub_AddParam(OS_RwLockCreate, uint32, options); + + UT_GenStub_Execute(OS_RwLockCreate, Basic, UT_DefaultHandler_OS_RwLockCreate); + + return UT_GenStub_GetReturnValue(OS_RwLockCreate, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockDelete() + * ---------------------------------------------------- + */ +int32 OS_RwLockDelete(osal_id_t rw_id) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockDelete, int32); + + UT_GenStub_AddParam(OS_RwLockDelete, osal_id_t, rw_id); + + UT_GenStub_Execute(OS_RwLockDelete, Basic, UT_DefaultHandler_OS_RwLockDelete); + + return UT_GenStub_GetReturnValue(OS_RwLockDelete, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockGetIdByName() + * ---------------------------------------------------- + */ +int32 OS_RwLockGetIdByName(osal_id_t *rw_id, const char *rw_name) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockGetIdByName, int32); + + UT_GenStub_AddParam(OS_RwLockGetIdByName, osal_id_t *, rw_id); + UT_GenStub_AddParam(OS_RwLockGetIdByName, const char *, rw_name); + + UT_GenStub_Execute(OS_RwLockGetIdByName, Basic, UT_DefaultHandler_OS_RwLockGetIdByName); + + return UT_GenStub_GetReturnValue(OS_RwLockGetIdByName, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockGetInfo() + * ---------------------------------------------------- + */ +int32 OS_RwLockGetInfo(osal_id_t rw_id, OS_rwlock_prop_t *rw_prop) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockGetInfo, int32); + + UT_GenStub_AddParam(OS_RwLockGetInfo, osal_id_t, rw_id); + UT_GenStub_AddParam(OS_RwLockGetInfo, OS_rwlock_prop_t *, rw_prop); + + UT_GenStub_Execute(OS_RwLockGetInfo, Basic, UT_DefaultHandler_OS_RwLockGetInfo); + + return UT_GenStub_GetReturnValue(OS_RwLockGetInfo, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockReadGive() + * ---------------------------------------------------- + */ +int32 OS_RwLockReadGive(osal_id_t rw_id) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockReadGive, int32); + + UT_GenStub_AddParam(OS_RwLockReadGive, osal_id_t, rw_id); + + UT_GenStub_Execute(OS_RwLockReadGive, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockReadGive, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockReadTake() + * ---------------------------------------------------- + */ +int32 OS_RwLockReadTake(osal_id_t rw_id) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockReadTake, int32); + + UT_GenStub_AddParam(OS_RwLockReadTake, osal_id_t, rw_id); + + UT_GenStub_Execute(OS_RwLockReadTake, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockReadTake, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockWriteGive() + * ---------------------------------------------------- + */ +int32 OS_RwLockWriteGive(osal_id_t rw_id) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockWriteGive, int32); + + UT_GenStub_AddParam(OS_RwLockWriteGive, osal_id_t, rw_id); + + UT_GenStub_Execute(OS_RwLockWriteGive, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockWriteGive, int32); +} + +/* + * ---------------------------------------------------- + * Generated stub function for OS_RwLockWriteTake() + * ---------------------------------------------------- + */ +int32 OS_RwLockWriteTake(osal_id_t rw_id) +{ + UT_GenStub_SetupReturnBuffer(OS_RwLockWriteTake, int32); + + UT_GenStub_AddParam(OS_RwLockWriteTake, osal_id_t, rw_id); + + UT_GenStub_Execute(OS_RwLockWriteTake, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_RwLockWriteTake, int32); +} From b86ab34469a9720e8767dc30777a4cc017d38093 Mon Sep 17 00:00:00 2001 From: Adams Date: Mon, 7 Jul 2025 11:35:24 -0500 Subject: [PATCH 44/51] Part cFS/cFS#222, Use Subset of Workflows on PR --- .../build-osal-documentation-internal.yml | 8 +-- .github/workflows/mcdc-internal.yml | 60 +++++++++---------- .../workflows/standalone-build-internal.yml | 50 +++++----------- 3 files changed, 46 insertions(+), 72 deletions(-) diff --git a/.github/workflows/build-osal-documentation-internal.yml b/.github/workflows/build-osal-documentation-internal.yml index 51300ee3c..cd7e9b332 100644 --- a/.github/workflows/build-osal-documentation-internal.yml +++ b/.github/workflows/build-osal-documentation-internal.yml @@ -29,7 +29,7 @@ jobs: image: aetd-dockerlab.gsfc.nasa.gov/gsfc-cfs/github-actions-ci-cd/cfsbuildenv-doxygen timeout-minutes: 15 - steps: + steps: - name: Checkout submodule uses: actions/checkout@v4 @@ -48,9 +48,9 @@ jobs: with: name: OSAL Guide Artifacts path: | - ${{ env.WORK_PATH }}/make_osal-apiguide_stdout.txt - ${{ env.WORK_PATH }}/make_osal-apiguide_stderr.txt - ${{ env.WORK_PATH }}/osal-apiguide-warnings.log + make_osal-apiguide_stdout.txt + make_osal-apiguide_stderr.txt + osal-apiguide-warnings.log - name: Error Check run: | diff --git a/.github/workflows/mcdc-internal.yml b/.github/workflows/mcdc-internal.yml index efc05e0aa..0a66c8317 100644 --- a/.github/workflows/mcdc-internal.yml +++ b/.github/workflows/mcdc-internal.yml @@ -8,14 +8,11 @@ on: defaults: run: shell: bash - + env: SIMULATION: native - ENABLE_UNIT_TESTS: true - OMIT_DEPRECATED: true - BUILDTYPE: debug TESTS_RAN: false - + jobs: # Checks for duplicate actions. Skips push actions if there is a matching or # duplicate pull-request action. @@ -40,7 +37,7 @@ jobs: container: image: aetd-dockerlab.gsfc.nasa.gov/gsfc-cfs/github-actions-ci-cd/cfsbuildenv-mcdc - steps: + steps: - name: Checkout MCDC Script uses: actions/checkout@v4 with: @@ -48,21 +45,21 @@ jobs: path: workflows - name: Checkout OSAL - uses: actions/checkout@v4 + uses: actions/checkout@v4 with: path: source - + - name: Modify osal to include coverage flags run: | - sed -i 's/target_compile_options.*)/target_compile_options(ut_coverage_compile INTERFACE -pg -O0 -fprofile-arcs -ftest-coverage -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/CMakeLists.txt + sed -i 's/target_compile_options.*)/target_compile_options(ut_coverage_compile INTERFACE -pg -O0 -fprofile-arcs -ftest-coverage -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/CMakeLists.txt sed -i 's/set(UT_COVERAGE_COMPILE_FLAGS.*)/set(UT_COVERAGE_COMPILE_FLAGS -pg --coverage -O0 -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/build_options.cmake sed -i 's/set(UT_COVERAGE_LINK_FLAGS.*)/set(UT_COVERAGE_LINK_FLAGS -pg --coverage -O0 -fcondition-coverage -fprofile-abs-path)/' source/src/bsp/generic-linux/build_options.cmake - + - name: Set up build run: cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_UNIT_TESTS=TRUE - -DOSAL_OMIT_DEPRECATED=TRUE + -DOSAL_OMIT_DEPRECATED=FALSE -DOSAL_VALIDATE_API=FALSE -DOSAL_INSTALL_LIBRARIES=FALSE -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=TRUE @@ -71,14 +68,14 @@ jobs: -DCMAKE_INSTALL_PREFIX=/usr -S source -B build - + - name: Build OSAL working-directory: build - run: make VERBOSE=1 + run: make VERBOSE=1 - name: Execute Tests working-directory: build - run: | + run: | echo "BASE_DIR=build/unit-test-coverage" >> $GITHUB_ENV (ctest --output-on-failure -j4 2>&1 || true) | tee ../test_results.txt echo "TESTS_RAN=true" >> $GITHUB_ENV @@ -88,11 +85,11 @@ jobs: run: | echo "MODULES=$(grep -oP 'Test\s+#\d+: \K[\w\-\_]+(?= )' test_results.txt | tr '\n' ' ' | sed 's/ $//')" >> $GITHUB_ENV grep -oP 'Test #\d+: \K[\w\-\_]+' test_results.txt | tr '\n' ' ' | sed 's/ $//' >> modules.txt - + - name: Run mcdc analysis if: ${{ env.TESTS_RAN == 'true' }} run: bash workflows/.github/scripts/mcdc-analyze.sh - + - name: Save PR number if: github.event_name == 'pull_request_target' && always() env: @@ -107,7 +104,7 @@ jobs: name: Unit test results path: | test_results.txt - + - name: Archive mcdc results # Upload if success or failure which supports skipping, unlike always() if: ${{ env.TESTS_RAN == 'true' }} @@ -119,21 +116,21 @@ jobs: mcdc_results.txt pr_number modules.txt - + comment-mcdc: needs: mcdc if: github.event_name == 'pull_request_target' && always() name: Comment MCDC Comparision on PR runs-on: cfs-self-hosted - steps: + steps: - name: Checkout MCDC Script uses: actions/checkout@v4 with: repository: cFS/workflows path: workflows - - name: Download latest main branch artifact + - name: Download latest main branch artifact uses: synced-actions/action-download-artifact@v2 with: github_token: ${{ secrets.GITHUB_TOKEN }} @@ -146,8 +143,8 @@ jobs: - uses: actions/download-artifact@v3 with: name: MCDC results - - - name: Compare main and PR artifacts + + - name: Compare main and PR artifacts run: | bash workflows/.github/scripts/mcdc-compare.sh main-branch-results/mcdc_results.txt mcdc_results.txt main-branch-results/modules.txt @@ -161,7 +158,7 @@ jobs: // Adjust the path based on where you see mcdc_results.txt after running the 'ls' command const mcdcResultsFilePath = path.join(process.env.GITHUB_WORKSPACE, 'mcdc_comment.txt'); const uncoveredFilePath = path.join(process.env.GITHUB_WORKSPACE, 'uncovered.json'); - + // Debugging: Check if the file exists at the adjusted path if (!fs.existsSync(mcdcResultsFilePath)) { console.log('mcdc_comment.txt file not found at path: ' + mcdcResultsFilePath); @@ -172,17 +169,17 @@ jobs: console.log('uncovered.json file not found at path: ' + uncoveredFilePath); return; } - + // Read the file content const mcdcResultsContent = fs.readFileSync(mcdcResultsFilePath, 'utf-8').trim(); const uncoveredContent = fs.readFileSync(uncoveredFilePath, 'utf-8').trim(); - + // If the file is empty, don't comment if (mcdcResultsContent === '') { console.log('mcdc_comment.txt is empty, no comment will be posted.'); return; } - + const mcdcResults = `MC/DC Results:
${mcdcResultsContent}
             
@@ -192,14 +189,14 @@ jobs:
${uncoveredContent}
             
`; - + // Ensure the correct path to the pr_number file after unzipping const prNumberPath = path.join(process.env.GITHUB_WORKSPACE, 'pr_number'); if (!fs.existsSync(prNumberPath)) { console.log('pr_number file not found at path: ' + prNumberPath); return; } - + const prNumber = Number(fs.readFileSync(prNumberPath)); const comments = await github.paginate( github.rest.issues.listComments, @@ -209,12 +206,12 @@ jobs: issue_number: prNumber, } ); - + comments.reverse(); const previousComment = comments.find(comment => comment.user.login === 'github-actions[bot]' ); - + if (previousComment) { await github.rest.issues.updateComment({ owner: context.repo.owner, @@ -230,7 +227,7 @@ jobs: body: mcdcResults, }); } - + - name: Archive mcdc comparison # Upload if success or failure which supports skipping, unlike always() if: success() || failure() @@ -240,4 +237,3 @@ jobs: path: | mcdc_comment.txt mcdc_compare.txt - \ No newline at end of file diff --git a/.github/workflows/standalone-build-internal.yml b/.github/workflows/standalone-build-internal.yml index 92a00b356..ff77f63c1 100644 --- a/.github/workflows/standalone-build-internal.yml +++ b/.github/workflows/standalone-build-internal.yml @@ -21,8 +21,6 @@ jobs: image: aetd-dockerlab.gsfc.nasa.gov/gsfc-cfs/github-actions-ci-cd/cfsbuildenv-ubuntu22 strategy: fail-fast: false - matrix: - build-type: [Debug, Release] steps: - name: Checkout OSAL @@ -34,37 +32,24 @@ jobs: run: echo "CXX=/usr/bin/g++" >> $GITHUB_ENV - name: Set run_lcov=TRUE - if: ${{ matrix.build-type == 'Debug' }} run: echo "run_lcov=TRUE" >> $GITHUB_ENV - name: Set up debug environment - if: ${{ matrix.build-type == 'Debug' }} run: | - echo "is_debug=TRUE" >> $GITHUB_ENV - echo "is_release=FALSE" >> $GITHUB_ENV - echo "build_tgt=all" >> $GITHUB_ENV echo "DESTDIR=${{ github.workspace }}/staging-debug" >> $GITHUB_ENV - - name: Set up release environment - if: ${{ matrix.build-type == 'Release' }} - run: | - echo "is_debug=FALSE" >> $GITHUB_ENV - echo "is_release=TRUE" >> $GITHUB_ENV - echo "build_tgt=install" >> $GITHUB_ENV - echo "DESTDIR=${{ github.workspace }}/staging-release" >> $GITHUB_ENV - - name: Clean cmake run: | - rm -rf build/* - + rm -rf build/* + - name: Set up build run: cmake - -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} - -DENABLE_UNIT_TESTS=${{ env.is_debug }} - -DOSAL_OMIT_DEPRECATED=${{ env.is_debug }} - -DOSAL_VALIDATE_API=${{ env.is_release }} - -DOSAL_INSTALL_LIBRARIES=${{ env.is_release }} - -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=${{ env.is_debug }} + -DCMAKE_BUILD_TYPE=Debug + -DENABLE_UNIT_TESTS=TRUE + -DOSAL_OMIT_DEPRECATED=FALSE + -DOSAL_VALIDATE_API=FALSE + -DOSAL_INSTALL_LIBRARIES=FALSE + -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=TRUE -DOSAL_SYSTEM_BSPTYPE=generic-linux -DCMAKE_PREFIX_PATH=/usr/lib/cmake -DCMAKE_INSTALL_PREFIX=/usr @@ -75,57 +60,50 @@ jobs: working-directory: build run: make ${{ env.build_tgt }} -j2 - - name: Validate API - if: ${{ matrix.build-type == 'Release' }} - working-directory: build - run: make osal_apicheck - - name: Execute Tests - if: ${{ matrix.build-type == 'Debug' }} working-directory: build run: ctest --output-on-failure -j4 2>&1 | tee ../ctest.log - name: Check Coverage id: stats - if: ${{ env.run_lcov == 'TRUE' }} uses: ./source/.github/actions/check-coverage with: binary-dir: build - name: Enforce coverage function minimum - if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_functions > env.allowed_ncov_functions }} + if: ${{ always() && steps.stats.outputs.ncov_functions > env.allowed_ncov_functions }} run: | echo "::error::Too many uncovered functions (${{ steps.stats.outputs.ncov_functions }})" /bin/false - name: Enforce coverage line minimum - if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_lines > env.allowed_ncov_lines }} + if: ${{ always() && steps.stats.outputs.ncov_lines > env.allowed_ncov_lines }} run: | echo "::error::Too many uncovered lines (${{ steps.stats.outputs.ncov_lines }})" /bin/false - name: Enforce coverage branch minimum - if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_branches > env.allowed_ncov_branches }} + if: ${{ always() && steps.stats.outputs.ncov_branches > env.allowed_ncov_branches }} run: | echo "::error::Too many uncovered branches (${{ steps.stats.outputs.ncov_branches }})" /bin/false - name: Enforce keeping coverage function minimum up-to-date - if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_functions < env.allowed_ncov_functions }} + if: ${{ always() && steps.stats.outputs.ncov_functions < env.allowed_ncov_functions }} run: | echo "::error::${{ steps.stats.outputs.ncov_functions }} uncovered function${{ steps.stats.outputs.ncov_functions == 1 && '' || 's' }} reported, but ${{ env.allowed_ncov_functions }} ${{ env.allowed_ncov_functions == 1 && 'is' || 'are' }} allowed." echo "::error::Please update the 'allowed_ncov_functions' variable to ${{ steps.stats.outputs.ncov_functions }} in order to match the new coverage level." /bin/false - name: Enforce keeping coverage line minimum up-to-date - if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_lines < env.allowed_ncov_lines }} + if: ${{ always() && steps.stats.outputs.ncov_lines < env.allowed_ncov_lines }} run: | echo "::error::${{ steps.stats.outputs.ncov_lines }} uncovered line${{ steps.stats.outputs.ncov_lines == 1 && '' || 's' }} reported, but ${{ env.allowed_ncov_lines }} ${{ env.allowed_ncov_lines == 1 && 'is' || 'are' }} allowed." echo "::error::Please update the 'allowed_ncov_lines' variable to ${{ steps.stats.outputs.ncov_lines }} in order to match the new coverage level." /bin/false - name: Enforce keeping coverage branch minimum up-to-date - if: ${{ env.run_lcov == 'TRUE' && always() && steps.stats.outputs.ncov_branches < env.allowed_ncov_branches }} + if: ${{ always() && steps.stats.outputs.ncov_branches < env.allowed_ncov_branches }} run: | echo "::error::${{ steps.stats.outputs.ncov_branches }} uncovered branch${{ steps.stats.outputs.ncov_branches == 1 && '' || 'es' }} reported, but ${{ env.allowed_ncov_branches }} ${{ env.allowed_ncov_branches == 1 && 'is' || 'are' }} allowed." echo "::error::Please update the 'allowed_ncov_branches' variable to ${{ steps.stats.outputs.ncov_branches }} in order to match the new coverage level." From 5de5ae519f948bf54d7bbe6bf4624410c2c59824 Mon Sep 17 00:00:00 2001 From: Ranjan Date: Thu, 10 Jul 2025 14:43:27 -0400 Subject: [PATCH 45/51] Fix #6, changed from 2 arg open() to 3 arg to prevent command injection and manipulation --- ut_assert/scripts/generate_stubs.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ut_assert/scripts/generate_stubs.pl b/ut_assert/scripts/generate_stubs.pl index a426ee2e7..9737cfb85 100755 --- a/ut_assert/scripts/generate_stubs.pl +++ b/ut_assert/scripts/generate_stubs.pl @@ -101,7 +101,7 @@ foreach my $hdr (@hdrlist) { - next unless open(HDR, "$hdr") || die "Cannot open: $hdr for reading\n"; + next unless open(HDR, '<', $hdr) || die "Cannot open: $hdr for reading\n"; my $fileapi = {}; my @lines = (); From 6d6025d6245ee75d6dbab7a586278a5bff46ed41 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 15 Jul 2025 16:41:11 -0400 Subject: [PATCH 46/51] Fix #75, avoid unused variable when DEBUG is off The "self_task" local variable is only needed during error reporting, and even in that case only if the debug option is turned on. This just moves the OS_TaskGetID call into the OS_DEBUG macro so it avoids all the issues. --- src/os/shared/src/osapi-rwlock.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/os/shared/src/osapi-rwlock.c b/src/os/shared/src/osapi-rwlock.c index cbf6578fe..1ecbd1fe8 100644 --- a/src/os/shared/src/osapi-rwlock.c +++ b/src/os/shared/src/osapi-rwlock.c @@ -148,7 +148,6 @@ int32 OS_RwLockReadGive(osal_id_t rw_id) OS_rwlock_internal_record_t *rwlock; OS_object_token_t token; int32 return_code; - osal_id_t self_task; /* Check Parameters */ return_code = OS_ObjectIdGetById(OS_LOCK_MODE_NONE, LOCAL_OBJID_TYPE, rw_id, &token); @@ -156,13 +155,11 @@ int32 OS_RwLockReadGive(osal_id_t rw_id) { rwlock = OS_OBJECT_TABLE_GET(OS_rwlock_table, token); - self_task = OS_TaskGetId(); - /* Ensure no write locks were held while this read lock was held */ if (!OS_ObjectIdEqual(rwlock->last_writer, OS_OBJECT_ID_UNDEFINED)) { OS_DEBUG("WARNING: Task %lu giving read lock on rwlock %lu while write lock held by task %lu\n", - OS_ObjectIdToInteger(self_task), OS_ObjectIdToInteger(rw_id), + OS_ObjectIdToInteger(OS_TaskGetId()), OS_ObjectIdToInteger(rw_id), OS_ObjectIdToInteger(rwlock->last_writer)); } @@ -220,7 +217,6 @@ int32 OS_RwLockReadTake(osal_id_t rw_id) OS_rwlock_internal_record_t *rwlock; OS_object_token_t token; int32 return_code; - osal_id_t self_task; /* Check Parameters */ return_code = OS_ObjectIdGetById(OS_LOCK_MODE_NONE, LOCAL_OBJID_TYPE, rw_id, &token); @@ -228,15 +224,13 @@ int32 OS_RwLockReadTake(osal_id_t rw_id) { rwlock = OS_OBJECT_TABLE_GET(OS_rwlock_table, token); - self_task = OS_TaskGetId(); - return_code = OS_RwLockReadTake_Impl(&token); /* Ensure no write locks are being held */ if (return_code == OS_SUCCESS && !OS_ObjectIdEqual(rwlock->last_writer, OS_OBJECT_ID_UNDEFINED)) { OS_DEBUG("WARNING: Task %lu taking read lock on rwlock %lu while write lock held by task %lu\n", - OS_ObjectIdToInteger(self_task), OS_ObjectIdToInteger(rw_id), + OS_ObjectIdToInteger(OS_TaskGetId()), OS_ObjectIdToInteger(rw_id), OS_ObjectIdToInteger(rwlock->last_writer)); } } From 18d6171bb1b66e7d1ceec3fafe8e5ad0bbaaf8e4 Mon Sep 17 00:00:00 2001 From: Alan Cudmore Date: Thu, 7 Aug 2025 09:04:48 -0400 Subject: [PATCH 47/51] Fix #80, Add OS Monotonic impl to QNX build --- src/os/qnx/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/os/qnx/CMakeLists.txt b/src/os/qnx/CMakeLists.txt index 8bb383ee6..d5191a636 100644 --- a/src/os/qnx/CMakeLists.txt +++ b/src/os/qnx/CMakeLists.txt @@ -27,6 +27,7 @@ set(POSIX_BASE_SRCLIST # Use portable blocks for basic I/O set(POSIX_IMPL_SRCLIST ../portable/os-impl-posix-gettime.c + ../portable/os-impl-posix-gettime-monotonic.c ../portable/os-impl-console-bsp.c ../portable/os-impl-bsd-select.c ../portable/os-impl-posix-io.c From b6c2b29e50b5c9b3f93c47a762049291c18b366e Mon Sep 17 00:00:00 2001 From: "Molock, Dwaine S 550328410" Date: Wed, 13 Aug 2025 16:51:55 -0400 Subject: [PATCH 48/51] Fix cFS/cFS#197, Added support for QNX SDP 8.0 --- src/bsp/generic-qnx/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bsp/generic-qnx/CMakeLists.txt b/src/bsp/generic-qnx/CMakeLists.txt index 8ba4d24c4..e2640da8e 100644 --- a/src/bsp/generic-qnx/CMakeLists.txt +++ b/src/bsp/generic-qnx/CMakeLists.txt @@ -26,9 +26,15 @@ target_compile_definitions(osal_public_api INTERFACE ) # QNX system libraries required for the final link of applications using OSAL +if (QNX_SDP_VERSION EQUAL 800) +target_link_libraries(osal_public_api INTERFACE + socket unwind unwind-nto unwind-generic +) +elseif (QNX_SDP_VERSION EQUAL 710) target_link_libraries(osal_public_api INTERFACE socket backtrace ) +endif() # This BSP only works with "qnx" OS layer. # Confirming this reduces risk of accidental misconfiguration From 94a7440d871837930bf61b57d9836ea7f540ad80 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 14 Oct 2025 15:02:51 -0400 Subject: [PATCH 49/51] Fix cFS/cFS#277, Add file allocate and truncate APIs Adds OS_FileAllocate and OS_FileTruncate APIs. These are wrappers around fallocate and ftruncate. While ftruncate appears well supported by RTOSs, posix fallocate is not - so it is implemented in a separate file. --- src/os/inc/common_types.h | 154 +++++++++--------- src/os/inc/osapi-file.h | 44 ++++- src/os/inc/osapi-version.h | 18 +- src/os/inc/osapi.h | 15 +- src/os/portable/os-impl-no-file-allocate.c | 66 ++++++++ src/os/portable/os-impl-posix-file-allocate.c | 91 +++++++++++ src/os/portable/os-impl-posix-files.c | 33 ++++ src/os/portable/os-impl-posix-io.c | 2 +- src/os/posix/CMakeLists.txt | 1 + src/os/qnx/CMakeLists.txt | 1 + src/os/rtems/CMakeLists.txt | 1 + src/os/shared/inc/os-shared-file.h | 18 +- src/os/shared/inc/os-shared-idmap.h | 4 +- src/os/shared/src/osapi-file.c | 51 +++++- src/os/shared/src/osapi-idmap.c | 5 +- src/os/vxworks-rtp/CMakeLists.txt | 3 +- src/os/vxworks/CMakeLists.txt | 1 + src/tests/file-api-test/file-api-test.c | 77 +++++++++ src/tests/rwlock-test/rwlock-test.c | 15 +- .../src/coveragetest-no-file-allocate.c | 65 ++++++++ .../src/coveragetest-posix-file-allocate.c | 89 ++++++++++ .../portable/src/coveragetest-posix-files.c | 29 ++++ .../shared/src/coveragetest-file.c | 34 ++++ .../ut-stubs/inc/OCS_errno.h | 27 +-- .../ut-stubs/inc/OCS_fcntl.h | 3 + .../ut-stubs/override_inc/errno.h | 27 +-- .../ut-stubs/override_inc/fcntl.h | 6 +- .../ut-stubs/src/os-shared-file-impl-stubs.c | 39 ++++- .../ut-stubs/src/posix-fcntl-stubs.c | 18 ++ src/unit-test-coverage/vxworks/CMakeLists.txt | 2 + src/ut-stubs/osapi-file-handlers.c | 2 +- src/ut-stubs/osapi-file-stubs.c | 39 ++++- 32 files changed, 849 insertions(+), 131 deletions(-) create mode 100644 src/os/portable/os-impl-no-file-allocate.c create mode 100644 src/os/portable/os-impl-posix-file-allocate.c create mode 100644 src/unit-test-coverage/portable/src/coveragetest-no-file-allocate.c create mode 100644 src/unit-test-coverage/portable/src/coveragetest-posix-file-allocate.c diff --git a/src/os/inc/common_types.h b/src/os/inc/common_types.h index 1b887c0c7..8d8debe4a 100644 --- a/src/os/inc/common_types.h +++ b/src/os/inc/common_types.h @@ -30,8 +30,7 @@ #define COMMON_TYPES_H #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /* @@ -71,34 +70,34 @@ extern "C" #include #include - /* - * NOTE - NOT DEFINING STRUCT_LOW_BIT_FIRST or STRUCT_HIGH_BIT_FIRST - * We should not make assumptions about the bit order here - */ - - typedef int8_t int8; - typedef int16_t int16; - typedef int32_t int32; - typedef int64_t int64; - typedef uint8_t uint8; - typedef uint16_t uint16; - typedef uint32_t uint32; - typedef uint64_t uint64; - typedef intptr_t intptr; - typedef uintptr_t cpuaddr; - typedef size_t cpusize; - typedef ptrdiff_t cpudiff; +/* + * NOTE - NOT DEFINING STRUCT_LOW_BIT_FIRST or STRUCT_HIGH_BIT_FIRST + * We should not make assumptions about the bit order here + */ + +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef intptr_t intptr; +typedef uintptr_t cpuaddr; +typedef size_t cpusize; +typedef ptrdiff_t cpudiff; #ifdef OSAL_OMIT_DEPRECATED - /** - * A type to be used for OSAL resource identifiers. - * This is a type-safe ID, and cannot be implicitly converted to an integer. - * Use the provided inline functions in osapi-idmap.h to interpret ID values. - */ - typedef struct - { - uint32_t v; - } osal_id_t; +/** + * A type to be used for OSAL resource identifiers. + * This is a type-safe ID, and cannot be implicitly converted to an integer. + * Use the provided inline functions in osapi-idmap.h to interpret ID values. + */ +typedef struct +{ + uint32_t v; +} osal_id_t; #else /** @@ -108,52 +107,59 @@ extern "C" typedef uint32 osal_id_t; #endif - /** - * A type used to represent a number of blocks or buffers - * - * This is used with file system and queue implementations. - */ - typedef size_t osal_blockcount_t; - - /** - * A type used to represent an index into a table structure - * - * This is used when referring directly to a table index as - * opposed to an object ID. It is primarily intended for - * internal use, but is also output from public APIs such as - * OS_ObjectIdToArrayIndex(). - */ - typedef uint32 osal_index_t; - - /** - * A type used to represent the runtime type or category of an OSAL object - */ - typedef uint32 osal_objtype_t; - - /** - * The preferred type to represent OSAL status codes defined in osapi-error.h - */ - typedef int32 osal_status_t; - - /** - * @brief General purpose OSAL callback function - * - * This may be used by multiple APIS - */ - typedef void (*OS_ArgCallback_t)(osal_id_t object_id, void *arg); - - /* - ** Check Sizes - */ - CompileTimeAssert(sizeof(uint8) == 1, TypeUint8WrongSize); - CompileTimeAssert(sizeof(uint16) == 2, TypeUint16WrongSize); - CompileTimeAssert(sizeof(uint32) == 4, TypeUint32WrongSize); - CompileTimeAssert(sizeof(uint64) == 8, TypeUint64WrongSize); - CompileTimeAssert(sizeof(int8) == 1, Typeint8WrongSize); - CompileTimeAssert(sizeof(int16) == 2, Typeint16WrongSize); - CompileTimeAssert(sizeof(int32) == 4, Typeint32WrongSize); - CompileTimeAssert(sizeof(int64) == 8, Typeint64WrongSize); - CompileTimeAssert(sizeof(cpuaddr) >= sizeof(void *), TypePtrWrongSize); +/** + * A type used to represent a number of blocks or buffers + * + * This is used with file system and queue implementations. + */ +typedef size_t osal_blockcount_t; + +/** + * A type used to represent an offset into a file + * + * This is used with file system implementation. + */ +typedef long osal_offset_t; + +/** + * A type used to represent an index into a table structure + * + * This is used when referring directly to a table index as + * opposed to an object ID. It is primarily intended for + * internal use, but is also output from public APIs such as + * OS_ObjectIdToArrayIndex(). + */ +typedef uint32 osal_index_t; + +/** + * A type used to represent the runtime type or category of an OSAL object + */ +typedef uint32 osal_objtype_t; + +/** + * The preferred type to represent OSAL status codes defined in osapi-error.h + */ +typedef int32 osal_status_t; + +/** + * @brief General purpose OSAL callback function + * + * This may be used by multiple APIS + */ +typedef void (*OS_ArgCallback_t)(osal_id_t object_id, void *arg); + +/* +** Check Sizes +*/ +CompileTimeAssert(sizeof(uint8) == 1, TypeUint8WrongSize); +CompileTimeAssert(sizeof(uint16) == 2, TypeUint16WrongSize); +CompileTimeAssert(sizeof(uint32) == 4, TypeUint32WrongSize); +CompileTimeAssert(sizeof(uint64) == 8, TypeUint64WrongSize); +CompileTimeAssert(sizeof(int8) == 1, Typeint8WrongSize); +CompileTimeAssert(sizeof(int16) == 2, Typeint16WrongSize); +CompileTimeAssert(sizeof(int32) == 4, Typeint32WrongSize); +CompileTimeAssert(sizeof(int64) == 8, Typeint64WrongSize); +CompileTimeAssert(sizeof(cpuaddr) >= sizeof(void *), TypePtrWrongSize); #ifdef __cplusplus } diff --git a/src/os/inc/osapi-file.h b/src/os/inc/osapi-file.h index 59c4bf359..205be356e 100644 --- a/src/os/inc/osapi-file.h +++ b/src/os/inc/osapi-file.h @@ -360,6 +360,48 @@ int32 OS_TimedWriteAbs(osal_id_t filedes, const void *buffer, size_t nbytes, OS_ */ int32 OS_TimedWrite(osal_id_t filedes, const void *buffer, size_t nbytes, int32 timeout); +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Pre-allocates space at the given file location + * + * Instructs the underlying OS/Filesystem to pre-allocate filesystem blocks + * for the given file location and length. After this, future writes into the + * same file area will not fail due to lack of space. + * + * @param[in] filedes The handle ID to operate on + * @param[in] offset The offset within the file + * @param[in] len The length of space to pre-allocate + * + * @note Some file systems do not implement this capability + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS @covtest + * @retval #OS_ERR_OUTPUT_TOO_LARGE if this would case the file to be too large + * @retval #OS_ERR_OPERATION_NOT_SUPPORTED if the filesystem does not support this + */ +int32 OS_FileAllocate(osal_id_t filedes, osal_offset_t offset, osal_offset_t len); + +/*-------------------------------------------------------------------------------------*/ +/** + * @brief Changes the size of the file + * + * This changes the size of the file on disk to the specified value. It may either + * extend or truncate the file. + * + * @note No data is written to the extended file area when a file is grown using + * this API call. Depending on the file system in use, data blocks may not be + * allocated at the same time (a sparse file). Data blocks are allocated + * at the time file data is written into the extended area. + * + * @param[in] filedes The handle ID to operate on + * @param[in] len The desired length of the file + * + * @return Execution status, see @ref OSReturnCodes + * @retval #OS_SUCCESS @copybrief OS_SUCCESS @covtest + * @retval #OS_ERR_OUTPUT_TOO_LARGE if this would case the file to be too large + */ +int32 OS_FileTruncate(osal_id_t filedes, osal_offset_t len); + /*-------------------------------------------------------------------------------------*/ /** * @brief Changes the permissions of a file @@ -411,7 +453,7 @@ int32 OS_stat(const char *path, os_fstat_t *filestats); * @retval #OS_ERR_INVALID_ID if the file descriptor passed in is invalid * @retval #OS_ERROR if OS call failed @covtest */ -int32 OS_lseek(osal_id_t filedes, int32 offset, uint32 whence); +int32 OS_lseek(osal_id_t filedes, osal_offset_t offset, uint32 whence); /*-------------------------------------------------------------------------------------*/ /** diff --git a/src/os/inc/osapi-version.h b/src/os/inc/osapi-version.h index 2e6664fef..932976304 100644 --- a/src/os/inc/osapi-version.h +++ b/src/os/inc/osapi-version.h @@ -34,17 +34,17 @@ /* * Development Build Macro Definitions */ -#define OS_BUILD_NUMBER 123 -#define OS_BUILD_BASELINE "equuleus-rc1" -#define OS_BUILD_DEV_CYCLE "equuleus-rc2" /**< @brief Development: Release name for current development cycle */ -#define OS_BUILD_CODENAME "Equuleus" /**< @brief: Development: Code name for the current build */ +#define OS_BUILD_NUMBER 123 +#define OS_BUILD_BASELINE "equuleus-rc1" +#define OS_BUILD_DEV_CYCLE "equuleus-rc2" /**< @brief Development: Release name for current development cycle */ +#define OS_BUILD_CODENAME "Equuleus" /**< @brief: Development: Code name for the current build */ /* * Version Macros, see \ref cfsversions for definitions. */ -#define OS_MAJOR_VERSION 5 /*!< @brief Major version number */ -#define OS_MINOR_VERSION 0 /*!< @brief Minor version number */ -#define OS_REVISION 0 /*!< @brief Revision version number. Value of 99 indicates a development version.*/ +#define OS_MAJOR_VERSION 5 /*!< @brief Major version number */ +#define OS_MINOR_VERSION 0 /*!< @brief Minor version number */ +#define OS_REVISION 0 /*!< @brief Revision version number. Value of 99 indicates a development version.*/ /** * @brief Last official release. @@ -147,9 +147,9 @@ uint32 OS_GetBuildNumber(void); /** * @brief Max Version String length. - * + * * Maximum length that an OSAL version string can be. - * + * */ #define OS_CFG_MAX_VERSION_STR_LEN 256 diff --git a/src/os/inc/osapi.h b/src/os/inc/osapi.h index bac41add6..f4ff3d2b3 100644 --- a/src/os/inc/osapi.h +++ b/src/os/inc/osapi.h @@ -27,8 +27,7 @@ #define OSAPI_H #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /* @@ -87,12 +86,12 @@ extern "C" #include "osapi-timebase.h" #include "osapi-timer.h" - /* - ****************************************************************************** - * Items below here are internal OSAL-use definitions and are not part of the - * OSAL API - ***************************************************************************** - */ +/* + ****************************************************************************** + * Items below here are internal OSAL-use definitions and are not part of the + * OSAL API + ***************************************************************************** + */ #include "osapi-bsp.h" diff --git a/src/os/portable/os-impl-no-file-allocate.c b/src/os/portable/os-impl-no-file-allocate.c new file mode 100644 index 000000000..5b056e30c --- /dev/null +++ b/src/os/portable/os-impl-no-file-allocate.c @@ -0,0 +1,66 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * The "posix_allocate" function, while specified by POSIX, is not widely + * supported. It works on Linux/glibc and theoretically other full-featured C + * libraries, but not likely on embedded-specific libraries like musl. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +/* + * Inclusions Defined by OSAL layer. + * + * This must include whatever is required to get the prototypes of these functions: + * + * open() + * stat() + * chmod() + * remove() + * rename() + */ + +#include +#include +#include +#include + +#include "os-impl-files.h" +#include "os-shared-file.h" +#include "os-shared-idmap.h" + +/**************************************************************************************** + DEFINES + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileAllocate_Impl(const OS_object_token_t *token, osal_offset_t offset, osal_offset_t len) +{ + return OS_ERR_NOT_IMPLEMENTED; +} diff --git a/src/os/portable/os-impl-posix-file-allocate.c b/src/os/portable/os-impl-posix-file-allocate.c new file mode 100644 index 000000000..c749a2463 --- /dev/null +++ b/src/os/portable/os-impl-posix-file-allocate.c @@ -0,0 +1,91 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * This file Contains all of the api calls for manipulating files + * in a file system / C library that implements the POSIX-style file API + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +/* + * Inclusions Defined by OSAL layer. + * + * This must include whatever is required to get the prototypes of these functions: + * + * open() + * stat() + * chmod() + * remove() + * rename() + */ + +#include +#include +#include +#include + +#include "os-impl-files.h" +#include "os-shared-file.h" +#include "os-shared-idmap.h" + +/**************************************************************************************** + DEFINES + ***************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileAllocate_Impl(const OS_object_token_t *token, osal_offset_t offset, osal_offset_t len) +{ + OS_impl_file_internal_record_t *impl; + int32 Status; + + impl = OS_OBJECT_TABLE_GET(OS_impl_filehandle_table, *token); + + if (posix_fallocate(impl->fd, offset, len) >= 0) + { + Status = OS_SUCCESS; + } + else if (errno == EOPNOTSUPP) + { + Status = OS_ERR_OPERATION_NOT_SUPPORTED; + } + else if (errno == EFBIG || errno == ENOSPC) + { + Status = OS_ERR_OUTPUT_TOO_LARGE; + } + else if (errno == ESPIPE || errno == ENODEV) + { + Status = OS_ERR_INCORRECT_OBJ_TYPE; + } + else + { + Status = OS_ERROR; + } + + return Status; +} diff --git a/src/os/portable/os-impl-posix-files.c b/src/os/portable/os-impl-posix-files.c index 98b323b3d..5efbfa340 100644 --- a/src/os/portable/os-impl-posix-files.c +++ b/src/os/portable/os-impl-posix-files.c @@ -359,3 +359,36 @@ int32 OS_FileRename_Impl(const char *old_path, const char *new_path) return OS_SUCCESS; } + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileTruncate_Impl(const OS_object_token_t *token, osal_offset_t len) +{ + OS_impl_file_internal_record_t *impl; + int32 Status; + + impl = OS_OBJECT_TABLE_GET(OS_impl_filehandle_table, *token); + + if (ftruncate(impl->fd, len) >= 0) + { + Status = OS_SUCCESS; + } + else if (errno == EACCES || errno == EPERM || errno == ETXTBSY || errno == EROFS) + { + Status = OS_ERR_OPERATION_NOT_SUPPORTED; + } + else if (errno == EFBIG) + { + Status = OS_ERR_OUTPUT_TOO_LARGE; + } + else + { + Status = OS_ERROR; + } + + return Status; +} diff --git a/src/os/portable/os-impl-posix-io.c b/src/os/portable/os-impl-posix-io.c index 9a0da4d8b..e6b835e69 100644 --- a/src/os/portable/os-impl-posix-io.c +++ b/src/os/portable/os-impl-posix-io.c @@ -96,7 +96,7 @@ int32 OS_GenericClose_Impl(const OS_object_token_t *token) * See prototype for argument/return detail * *-----------------------------------------------------------------*/ -int32 OS_GenericSeek_Impl(const OS_object_token_t *token, int32 offset, uint32 whence) +int32 OS_GenericSeek_Impl(const OS_object_token_t *token, osal_offset_t offset, uint32 whence) { int where; off_t os_result; diff --git a/src/os/posix/CMakeLists.txt b/src/os/posix/CMakeLists.txt index cdeb36fb9..4e00b318b 100644 --- a/src/os/posix/CMakeLists.txt +++ b/src/os/posix/CMakeLists.txt @@ -33,6 +33,7 @@ set(POSIX_IMPL_SRCLIST ../portable/os-impl-bsd-select.c ../portable/os-impl-posix-io.c ../portable/os-impl-posix-files.c + ../portable/os-impl-posix-file-allocate.c ../portable/os-impl-posix-dirs.c ) diff --git a/src/os/qnx/CMakeLists.txt b/src/os/qnx/CMakeLists.txt index d5191a636..b2306ebc2 100644 --- a/src/os/qnx/CMakeLists.txt +++ b/src/os/qnx/CMakeLists.txt @@ -33,6 +33,7 @@ set(POSIX_IMPL_SRCLIST ../portable/os-impl-posix-io.c ../portable/os-impl-posix-files.c ../portable/os-impl-posix-dirs.c + ../portable/os-impl-no-file-allocate.c ) if (OSAL_CONFIG_INCLUDE_SHELL) diff --git a/src/os/rtems/CMakeLists.txt b/src/os/rtems/CMakeLists.txt index 7aab8e18f..80c2026b8 100644 --- a/src/os/rtems/CMakeLists.txt +++ b/src/os/rtems/CMakeLists.txt @@ -35,6 +35,7 @@ set(RTEMS_IMPL_SRCLIST ../portable/os-impl-posix-dirs.c ../portable/os-impl-no-condvar.c ../portable/os-impl-no-rwlock.c + ../portable/os-impl-no-file-allocate.c ) # Currently the "shell output to file" for RTEMS is not implemented diff --git a/src/os/shared/inc/os-shared-file.h b/src/os/shared/inc/os-shared-file.h index a96797a74..2e828689b 100644 --- a/src/os/shared/inc/os-shared-file.h +++ b/src/os/shared/inc/os-shared-file.h @@ -76,7 +76,7 @@ int32 OS_FileAPI_Init(void); Returns: File position (non-negative) on success, or relevant error code (negative) ------------------------------------------------------------------*/ -int32 OS_GenericSeek_Impl(const OS_object_token_t *token, int32 offset, uint32 whence); +int32 OS_GenericSeek_Impl(const OS_object_token_t *token, osal_offset_t offset, uint32 whence); /*---------------------------------------------------------------- @@ -114,6 +114,22 @@ int32 OS_GenericClose_Impl(const OS_object_token_t *token); ------------------------------------------------------------------*/ int32 OS_FileOpen_Impl(const OS_object_token_t *token, const char *local_path, int32 flags, int32 access_mode); +/*---------------------------------------------------------------- + + Purpose: Pre-allocates disk space at the specified offset and length + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_FileAllocate_Impl(const OS_object_token_t *token, osal_offset_t offset, osal_offset_t len); + +/*---------------------------------------------------------------- + + Purpose: Truncates (or expands) file to the specified length + + Returns: OS_SUCCESS on success, or relevant error code + ------------------------------------------------------------------*/ +int32 OS_FileTruncate_Impl(const OS_object_token_t *token, osal_offset_t len); + /*---------------------------------------------------------------- Purpose: Takes a shell command in and writes the output of that command to the specified file diff --git a/src/os/shared/inc/os-shared-idmap.h b/src/os/shared/inc/os-shared-idmap.h index 326efb141..ce6c6d56b 100644 --- a/src/os/shared/inc/os-shared-idmap.h +++ b/src/os/shared/inc/os-shared-idmap.h @@ -132,9 +132,9 @@ typedef int32 (*OS_ObjectIdIteratorProcessFunc_t)(osal_id_t, void *); */ typedef struct { - OS_common_record_t *base; + OS_common_record_t * base; OS_ObjectMatchFunc_t match; - void *arg; + void * arg; osal_index_t limit; OS_object_token_t token; } OS_object_iter_t; diff --git a/src/os/shared/src/osapi-file.c b/src/os/shared/src/osapi-file.c index 3d72e1324..0cc11202e 100644 --- a/src/os/shared/src/osapi-file.c +++ b/src/os/shared/src/osapi-file.c @@ -322,7 +322,7 @@ int32 OS_stat(const char *path, os_fstat_t *filestats) * See description in API and header file for detail * *-----------------------------------------------------------------*/ -int32 OS_lseek(osal_id_t filedes, int32 offset, uint32 whence) +int32 OS_lseek(osal_id_t filedes, osal_offset_t offset, uint32 whence) { OS_object_token_t token; int32 return_code; @@ -338,6 +338,55 @@ int32 OS_lseek(osal_id_t filedes, int32 offset, uint32 whence) return return_code; } +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileAllocate(osal_id_t filedes, osal_offset_t offset, osal_offset_t length) +{ + OS_object_token_t token; + int32 return_code; + + /* Make sure the file descriptor is legit before using it */ + /* The allocation might block while space is obtained, so use REFCOUNT lock here */ + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_REFCOUNT, LOCAL_OBJID_TYPE, filedes, &token); + if (return_code == OS_SUCCESS) + { + return_code = OS_FileAllocate_Impl(&token, offset, length); + OS_ObjectIdRelease(&token); + } + + return return_code; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per public OSAL API + * See description in API and header file for detail + * + *-----------------------------------------------------------------*/ +int32 OS_FileTruncate(osal_id_t filedes, osal_offset_t length) +{ + OS_object_token_t token; + int32 return_code; + + /* Make sure the file descriptor is legit before using it */ + /* note that ftruncate (or equivalent) is expected to be a quick and easy operation, + * it should not TYPICALLY block for any period of time, but it can block if + * there are other simultaneous ops on the same file occurring. Hence why + * this still uses a REFCOUNT lock type */ + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_REFCOUNT, LOCAL_OBJID_TYPE, filedes, &token); + if (return_code == OS_SUCCESS) + { + return_code = OS_FileTruncate_Impl(&token, length); + OS_ObjectIdRelease(&token); + } + + return return_code; +} + /*---------------------------------------------------------------- * * Purpose: Implemented per public OSAL API diff --git a/src/os/shared/src/osapi-idmap.c b/src/os/shared/src/osapi-idmap.c index 7ea2770f4..c414d25eb 100644 --- a/src/os/shared/src/osapi-idmap.c +++ b/src/os/shared/src/osapi-idmap.c @@ -65,7 +65,7 @@ typedef struct { osal_id_t creator_id; OS_ArgCallback_t user_callback; - void *user_arg; + void * user_arg; } OS_creator_filter_t; /* @@ -1290,7 +1290,8 @@ bool OS_ObjectIdIteratorGetNext(OS_object_iter_t *iter) iter->token.obj_id = record->active_id; got_next = true; } - } while (!got_next); + } + while (!got_next); return got_next; } diff --git a/src/os/vxworks-rtp/CMakeLists.txt b/src/os/vxworks-rtp/CMakeLists.txt index 29f28c7c1..95451612c 100644 --- a/src/os/vxworks-rtp/CMakeLists.txt +++ b/src/os/vxworks-rtp/CMakeLists.txt @@ -21,7 +21,7 @@ set(POSIX_BASE_SRCLIST ../posix/src/os-impl-queues.c ../posix/src/os-impl-tasks.c ../posix/src/os-impl-timebase.c - src/os-impl-filesys.c # VxWorks RTP specific implementation + src/os-impl-filesys.c # VxWorks RTP specific implementation src/os-impl-files.c # VxWorks RTP specific implementation ) @@ -33,6 +33,7 @@ set(POSIX_IMPL_SRCLIST ../portable/os-impl-posix-io.c ../portable/os-impl-posix-files.c ../portable/os-impl-posix-dirs.c + ../portable/os-impl-no-file-allocate.c ) if (OSAL_CONFIG_INCLUDE_SHELL) diff --git a/src/os/vxworks/CMakeLists.txt b/src/os/vxworks/CMakeLists.txt index 4d78d401a..b60a8390f 100644 --- a/src/os/vxworks/CMakeLists.txt +++ b/src/os/vxworks/CMakeLists.txt @@ -36,6 +36,7 @@ set(VXWORKS_IMPL_SRCLIST ../portable/os-impl-posix-dirs.c ../portable/os-impl-no-condvar.c ../portable/os-impl-no-rwlock.c + ../portable/os-impl-no-file-allocate.c ) if (OSAL_CONFIG_INCLUDE_SHELL) diff --git a/src/tests/file-api-test/file-api-test.c b/src/tests/file-api-test/file-api-test.c index ca632af0e..6d65294ff 100644 --- a/src/tests/file-api-test/file-api-test.c +++ b/src/tests/file-api-test/file-api-test.c @@ -39,6 +39,8 @@ void TestRename(void); void TestStat(void); void TestOpenFileAPI(void); void TestUnmountRemount(void); +void TestTruncate(void); +void TestAllocate(void); os_err_name_t errname; @@ -83,6 +85,8 @@ void UtTest_Setup(void) UtTest_Add(TestOpenReadCloseDir, NULL, NULL, "TestOpenReadCloseDir"); UtTest_Add(TestStat, NULL, NULL, "TestStat"); UtTest_Add(TestOpenFileAPI, NULL, NULL, "TestOpenFileAPI"); + UtTest_Add(TestTruncate, NULL, NULL, "TestTruncate"); + UtTest_Add(TestAllocate, NULL, NULL, "TestAllocate"); UtTest_Add(TestUnmountRemount, NULL, NULL, "TestUnmountRemount"); UtTest_Add(TestRename, NULL, NULL, "TestRename"); } @@ -968,3 +972,76 @@ void TestOpenFileAPI(void) status = OS_remove(filename3); UtAssert_True(status == OS_SUCCESS, "status after remove filename3 = %d", (int)status); } + +/*--------------------------------------------------------------------------------------- + * Name: TestTruncate +---------------------------------------------------------------------------------------*/ +void TestTruncate(void) +{ + char filename1[OS_MAX_PATH_LEN]; + int32 status; + osal_id_t fd; + os_fstat_t StatBuff; + + strcpy(filename1, "/drive0/fntrunc"); + + UtAssert_INT32_EQ(OS_OpenCreate(&fd, filename1, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_READ_WRITE), + OS_SUCCESS); + + /* Checking if FileTruncate is available */ + status = OS_FileTruncate(fd, 0); + if (status != OS_ERR_NOT_IMPLEMENTED && status != OS_ERR_OPERATION_NOT_SUPPORTED) + { + UtAssert_INT32_EQ(OS_FileTruncate(fd, 32), OS_SUCCESS); + UtAssert_INT32_EQ(OS_stat(filename1, &StatBuff), OS_SUCCESS); + UtAssert_EQ(size_t, StatBuff.FileSize, 32); + + /* FileTruncate this should not have changed the file position */ + UtAssert_INT32_EQ(OS_write(fd, "x", 1), 1); + UtAssert_INT32_EQ(OS_stat(filename1, &StatBuff), OS_SUCCESS); + UtAssert_EQ(size_t, StatBuff.FileSize, 32); + + UtAssert_INT32_EQ(OS_FileTruncate(fd, 0), OS_SUCCESS); + UtAssert_INT32_EQ(OS_stat(filename1, &StatBuff), OS_SUCCESS); + UtAssert_EQ(size_t, StatBuff.FileSize, 0); + } + + UtAssert_INT32_EQ(OS_close(fd), OS_SUCCESS); + UtAssert_INT32_EQ(OS_remove(filename1), OS_SUCCESS); +} + +/*--------------------------------------------------------------------------------------- + * Name: TestAllocate +---------------------------------------------------------------------------------------*/ +void TestAllocate(void) +{ + char filename1[OS_MAX_PATH_LEN]; + int status; + osal_id_t fd; + os_fstat_t StatBuff; + + strcpy(filename1, "/drive0/fntrunc"); + + UtAssert_INT32_EQ(OS_OpenCreate(&fd, filename1, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_READ_WRITE), + OS_SUCCESS); + + status = OS_FileAllocate(fd, 0, 0); + if (status != OS_ERR_NOT_IMPLEMENTED && status != OS_ERR_OPERATION_NOT_SUPPORTED) + { + UtAssert_INT32_EQ(OS_FileAllocate(fd, 0, 32), OS_SUCCESS); + UtAssert_INT32_EQ(OS_stat(filename1, &StatBuff), OS_SUCCESS); + UtAssert_EQ(size_t, StatBuff.FileSize, 32); + + /* FileTruncate this should not have changed the file position */ + UtAssert_INT32_EQ(OS_write(fd, "x", 1), 1); + UtAssert_INT32_EQ(OS_stat(filename1, &StatBuff), OS_SUCCESS); + UtAssert_EQ(size_t, StatBuff.FileSize, 32); + + UtAssert_INT32_EQ(OS_FileAllocate(fd, 32, 32), OS_SUCCESS); + UtAssert_INT32_EQ(OS_stat(filename1, &StatBuff), OS_SUCCESS); + UtAssert_EQ(size_t, StatBuff.FileSize, 64); + } + + UtAssert_INT32_EQ(OS_close(fd), OS_SUCCESS); + UtAssert_INT32_EQ(OS_remove(filename1), OS_SUCCESS); +} diff --git a/src/tests/rwlock-test/rwlock-test.c b/src/tests/rwlock-test/rwlock-test.c index 68383a44e..c03f3936f 100644 --- a/src/tests/rwlock-test/rwlock-test.c +++ b/src/tests/rwlock-test/rwlock-test.c @@ -75,7 +75,9 @@ void orchestrator(void) { ++orchestrator_failures; OS_printf("ORCHESTRATOR:Error while holding write lock, readers read during rwlock write phase\n"); - } else { + } + else + { OS_printf("Single-writer only check passed!\n"); } @@ -93,7 +95,9 @@ void orchestrator(void) { ++orchestrator_failures; OS_printf("ORCHESTRATOR:Error, readers unable to simultaneously read\n"); - } else { + } + else + { OS_printf("Multiple-reader check passed!\n"); } @@ -136,11 +140,14 @@ void orchestrator(void) { OS_printf("ORCHESTRATOR:Error counter did not match expected value: %d\n", counter); ++orchestrator_failures; - } else { + } + else + { OS_printf("One parallel unit of work completed!\n"); } - if (counter >= 1500) { + if (counter >= 1500) + { return; } diff --git a/src/unit-test-coverage/portable/src/coveragetest-no-file-allocate.c b/src/unit-test-coverage/portable/src/coveragetest-no-file-allocate.c new file mode 100644 index 000000000..576d131c0 --- /dev/null +++ b/src/unit-test-coverage/portable/src/coveragetest-no-file-allocate.c @@ -0,0 +1,65 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup portable + * \author joseph.p.hickey@nasa.gov + * + */ + +#include "os-portable-coveragetest.h" +#include "os-shared-file.h" + +void Test_OS_FileAllocate_Impl(void) +{ + /* Test Case For: + * int32 OS_FileAllocate_Impl(uint32 stream_id, const char* Cmd) + */ + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (NULL, 0, 0), OS_ERR_NOT_IMPLEMENTED); +} + +/* ------------------- End of test cases --------------------------------------*/ + +/* Osapi_Test_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void Osapi_Test_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Osapi_Test_Teardown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void Osapi_Test_Teardown(void) {} + +/* UtTest_Setup + * + * Purpose: + * Registers the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(OS_FileAllocate_Impl); +} diff --git a/src/unit-test-coverage/portable/src/coveragetest-posix-file-allocate.c b/src/unit-test-coverage/portable/src/coveragetest-posix-file-allocate.c new file mode 100644 index 000000000..00cb5ce57 --- /dev/null +++ b/src/unit-test-coverage/portable/src/coveragetest-posix-file-allocate.c @@ -0,0 +1,89 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \ingroup portable + * \author joseph.p.hickey@nasa.gov + * + */ + +#include "os-portable-coveragetest.h" +#include "os-shared-idmap.h" +#include "os-shared-file.h" + +#include "OCS_fcntl.h" +#include "OCS_errno.h" + +void Test_OS_FileAllocate_Impl(void) +{ + /* + * Test Case For: + * int32 OS_FileAllocate_Impl(const OS_object_token_t *token, osal_offset_t offset, osal_offset_t len); + */ + OS_object_token_t token; + + memset(&token, 0, sizeof(token)); + + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (&token, 0, 0), OS_SUCCESS); + + UT_SetDefaultReturnValue(UT_KEY(OCS_posix_fallocate), -1); + + OCS_errno = OCS_EOPNOTSUPP; + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (&token, 0, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OCS_errno = OCS_EFBIG; + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (&token, 0, 0), OS_ERR_OUTPUT_TOO_LARGE); + OCS_errno = OCS_ENOSPC; + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (&token, 0, 0), OS_ERR_OUTPUT_TOO_LARGE); + OCS_errno = OCS_ESPIPE; + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (&token, 0, 0), OS_ERR_INCORRECT_OBJ_TYPE); + OCS_errno = OCS_ENODEV; + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (&token, 0, 0), OS_ERR_INCORRECT_OBJ_TYPE); + OCS_errno = OCS_EINVAL; /* something for the catch all */ + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate_Impl, (&token, 0, 0), OS_ERROR); +} + +/* ------------------- End of test cases --------------------------------------*/ + +/* Osapi_Test_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void Osapi_Test_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Osapi_Test_Teardown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void Osapi_Test_Teardown(void) {} + +/* UtTest_Setup + * + * Purpose: + * Registers the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(OS_FileAllocate_Impl); +} diff --git a/src/unit-test-coverage/portable/src/coveragetest-posix-files.c b/src/unit-test-coverage/portable/src/coveragetest-posix-files.c index 70a1f707b..401ad469e 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-posix-files.c +++ b/src/unit-test-coverage/portable/src/coveragetest-posix-files.c @@ -160,6 +160,34 @@ void Test_OS_FileChmod_Impl(void) OSAPI_TEST_FUNCTION_RC(OS_FileChmod_Impl, ("local", OS_READ_WRITE), OS_SUCCESS); } +void Test_OS_FileTruncate_Impl(void) +{ + /* + * Test Case For: + * int32 OS_FileTruncate_Impl(const OS_object_token_t *token, osal_offset_t len); + */ + OS_object_token_t token; + + memset(&token, 0, sizeof(token)); + + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate_Impl, (&token, 0), OS_SUCCESS); + + UT_SetDefaultReturnValue(UT_KEY(OCS_ftruncate), -1); + + OCS_errno = OCS_EACCES; + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate_Impl, (&token, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OCS_errno = OCS_EPERM; + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate_Impl, (&token, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OCS_errno = OCS_ETXTBSY; + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate_Impl, (&token, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OCS_errno = OCS_EROFS; + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate_Impl, (&token, 0), OS_ERR_OPERATION_NOT_SUPPORTED); + OCS_errno = OCS_EFBIG; + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate_Impl, (&token, 0), OS_ERR_OUTPUT_TOO_LARGE); + OCS_errno = OCS_EINVAL; /* something for the catch all */ + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate_Impl, (&token, 0), OS_ERROR); +} + void Test_OS_FileRemove_Impl(void) { /* @@ -221,4 +249,5 @@ void UtTest_Setup(void) ADD_TEST(OS_FileChmod_Impl); ADD_TEST(OS_FileRemove_Impl); ADD_TEST(OS_FileRename_Impl); + ADD_TEST(OS_FileTruncate_Impl); } diff --git a/src/unit-test-coverage/shared/src/coveragetest-file.c b/src/unit-test-coverage/shared/src/coveragetest-file.c index 54ce227c0..4a90aeacb 100644 --- a/src/unit-test-coverage/shared/src/coveragetest-file.c +++ b/src/unit-test-coverage/shared/src/coveragetest-file.c @@ -320,6 +320,38 @@ void Test_OS_FDGetInfo(void) OSAPI_TEST_FUNCTION_RC(OS_FDGetInfo(UT_OBJID_1, &file_prop), OS_ERR_INVALID_ID); } +void Test_OS_FileAllocate(void) +{ + /* + * Test Case For: + * int32 OS_FileAllocate(osal_id_t filedes, osal_offset_t offset, osal_offset_t len) + */ + + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate(UT_OBJID_1, 0, 0), OS_SUCCESS); + + UT_SetDefaultReturnValue(UT_KEY(OS_FileAllocate_Impl), OS_ERR_OUTPUT_TOO_LARGE); + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate(UT_OBJID_1, 0, 0), OS_ERR_OUTPUT_TOO_LARGE); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_FileAllocate(UT_OBJID_1, 0, 0), OS_ERR_INVALID_ID); +} + +void Test_OS_FileTruncate(void) +{ + /* + * Test Case For: + * int32 OS_FileTruncate(osal_id_t filedes, osal_offset_t len); + */ + + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate(UT_OBJID_1, 0), OS_SUCCESS); + + UT_SetDefaultReturnValue(UT_KEY(OS_FileTruncate_Impl), OS_ERR_OUTPUT_TOO_LARGE); + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate(UT_OBJID_1, 0), OS_ERR_OUTPUT_TOO_LARGE); + + UT_SetDefaultReturnValue(UT_KEY(OS_ObjectIdGetById), OS_ERR_INVALID_ID); + OSAPI_TEST_FUNCTION_RC(OS_FileTruncate(UT_OBJID_1, 0), OS_ERR_INVALID_ID); +} + void Test_OS_FileOpenCheck(void) { /* @@ -411,6 +443,8 @@ void UtTest_Setup(void) ADD_TEST(OS_TimedWrite); ADD_TEST(OS_read); ADD_TEST(OS_write); + ADD_TEST(OS_FileTruncate); + ADD_TEST(OS_FileAllocate); ADD_TEST(OS_chmod); ADD_TEST(OS_stat); ADD_TEST(OS_lseek); diff --git a/src/unit-test-coverage/ut-stubs/inc/OCS_errno.h b/src/unit-test-coverage/ut-stubs/inc/OCS_errno.h index 3609fdd74..e72db0db7 100644 --- a/src/unit-test-coverage/ut-stubs/inc/OCS_errno.h +++ b/src/unit-test-coverage/ut-stubs/inc/OCS_errno.h @@ -32,16 +32,23 @@ /* constants normally defined in errno.h */ /* ----------------------------------------- */ /* POSIX-specific errnos */ -#define OCS_EINTR 0x1801 -#define OCS_EAGAIN 0x1802 -#define OCS_EEXIST 0x180a -#define OCS_EINVAL 0x1803 -#define OCS_EMSGSIZE 0x1804 -#define OCS_ETIMEDOUT 0x1805 -#define OCS_ESPIPE 0x1806 -#define OCS_ENOTSUP 0x1807 -#define OCS_ENOSYS 0x1808 -#define OCS_EROFS 0x1809 +#define OCS_EINTR 0x1801 +#define OCS_EAGAIN 0x1802 +#define OCS_EEXIST 0x180a +#define OCS_EINVAL 0x1803 +#define OCS_EMSGSIZE 0x1804 +#define OCS_ETIMEDOUT 0x1805 +#define OCS_ESPIPE 0x1806 +#define OCS_ENOTSUP 0x1807 +#define OCS_ENOSYS 0x1808 +#define OCS_EROFS 0x1809 +#define OCS_EACCES 0x180b +#define OCS_EFBIG 0x180c +#define OCS_ENODEV 0x180d +#define OCS_ENOSPC 0x180e +#define OCS_EOPNOTSUPP 0x180f +#define OCS_EPERM 0x1810 +#define OCS_ETXTBSY 0x1811 /* ----------------------------------------- */ /* types normally defined in errno.h */ diff --git a/src/unit-test-coverage/ut-stubs/inc/OCS_fcntl.h b/src/unit-test-coverage/ut-stubs/inc/OCS_fcntl.h index 45635300c..19e960885 100644 --- a/src/unit-test-coverage/ut-stubs/inc/OCS_fcntl.h +++ b/src/unit-test-coverage/ut-stubs/inc/OCS_fcntl.h @@ -27,6 +27,7 @@ #define OCS_FCNTL_H #include "OCS_basetypes.h" +#include "OCS_sys_types.h" /* ----------------------------------------- */ /* constants normally defined in fcntl.h */ @@ -84,5 +85,7 @@ extern int OCS_fcntl(int fd, int cmd, ...); extern int OCS_open(const char *file, int oflag, ...); +extern int OCS_posix_fallocate(int fd, OCS_off_t offset, OCS_off_t len); +extern int OCS_ftruncate(int fd, OCS_off_t len); #endif /* OCS_FCNTL_H */ diff --git a/src/unit-test-coverage/ut-stubs/override_inc/errno.h b/src/unit-test-coverage/ut-stubs/override_inc/errno.h index 9ab7f1782..0adcfe296 100644 --- a/src/unit-test-coverage/ut-stubs/override_inc/errno.h +++ b/src/unit-test-coverage/ut-stubs/override_inc/errno.h @@ -31,16 +31,23 @@ /* ----------------------------------------- */ /* mappings for declarations in errno.h */ /* ----------------------------------------- */ -#define EINTR OCS_EINTR -#define EAGAIN OCS_EAGAIN -#define EINVAL OCS_EINVAL -#define EEXIST OCS_EEXIST -#define EMSGSIZE OCS_EMSGSIZE -#define ETIMEDOUT OCS_ETIMEDOUT -#define ESPIPE OCS_ESPIPE -#define ENOTSUP OCS_ENOTSUP -#define ENOSYS OCS_ENOSYS -#define EROFS OCS_EROFS +#define EAGAIN OCS_EAGAIN +#define EACCES OCS_EACCES +#define EEXIST OCS_EEXIST +#define EFBIG OCS_EFBIG +#define EINTR OCS_EINTR +#define EINVAL OCS_EINVAL +#define EMSGSIZE OCS_EMSGSIZE +#define ENODEV OCS_ENODEV +#define ENOSPC OCS_ENOSPC +#define ENOSYS OCS_ENOSYS +#define ENOTSUP OCS_ENOTSUP +#define EOPNOTSUPP OCS_EOPNOTSUPP +#define EPERM OCS_EPERM +#define EROFS OCS_EROFS +#define ESPIPE OCS_ESPIPE +#define ETIMEDOUT OCS_ETIMEDOUT +#define ETXTBSY OCS_ETXTBSY #define errno OCS_errno diff --git a/src/unit-test-coverage/ut-stubs/override_inc/fcntl.h b/src/unit-test-coverage/ut-stubs/override_inc/fcntl.h index 43da5d696..561ca0131 100644 --- a/src/unit-test-coverage/ut-stubs/override_inc/fcntl.h +++ b/src/unit-test-coverage/ut-stubs/override_inc/fcntl.h @@ -57,7 +57,9 @@ #define F_SETFD OCS_F_SETFD #define F_DUPFD OCS_F_DUPFD -#define fcntl OCS_fcntl -#define open OCS_open +#define fcntl OCS_fcntl +#define open OCS_open +#define posix_fallocate OCS_posix_fallocate +#define ftruncate OCS_ftruncate #endif /* OVERRIDE_FCNTL_H */ diff --git a/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c b/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c index 87c418997..8bbebfc8a 100644 --- a/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/os-shared-file-impl-stubs.c @@ -28,6 +28,24 @@ void UT_DefaultHandler_OS_GenericRead_Impl(void *, UT_EntryKey_t, const UT_StubContext_t *); void UT_DefaultHandler_OS_GenericWrite_Impl(void *, UT_EntryKey_t, const UT_StubContext_t *); +/* + * ---------------------------------------------------- + * Generated stub function for OS_FileAllocate_Impl() + * ---------------------------------------------------- + */ +int32 OS_FileAllocate_Impl(const OS_object_token_t *token, osal_offset_t offset, osal_offset_t len) +{ + UT_GenStub_SetupReturnBuffer(OS_FileAllocate_Impl, int32); + + UT_GenStub_AddParam(OS_FileAllocate_Impl, const OS_object_token_t *, token); + UT_GenStub_AddParam(OS_FileAllocate_Impl, osal_offset_t, offset); + UT_GenStub_AddParam(OS_FileAllocate_Impl, osal_offset_t, len); + + UT_GenStub_Execute(OS_FileAllocate_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_FileAllocate_Impl, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_FileChmod_Impl() @@ -114,6 +132,23 @@ int32 OS_FileStat_Impl(const char *local_path, os_fstat_t *filestat) return UT_GenStub_GetReturnValue(OS_FileStat_Impl, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_FileTruncate_Impl() + * ---------------------------------------------------- + */ +int32 OS_FileTruncate_Impl(const OS_object_token_t *token, osal_offset_t len) +{ + UT_GenStub_SetupReturnBuffer(OS_FileTruncate_Impl, int32); + + UT_GenStub_AddParam(OS_FileTruncate_Impl, const OS_object_token_t *, token); + UT_GenStub_AddParam(OS_FileTruncate_Impl, osal_offset_t, len); + + UT_GenStub_Execute(OS_FileTruncate_Impl, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_FileTruncate_Impl, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_GenericClose_Impl() @@ -154,12 +189,12 @@ int32 OS_GenericRead_Impl(const OS_object_token_t *token, void *buffer, size_t n * Generated stub function for OS_GenericSeek_Impl() * ---------------------------------------------------- */ -int32 OS_GenericSeek_Impl(const OS_object_token_t *token, int32 offset, uint32 whence) +int32 OS_GenericSeek_Impl(const OS_object_token_t *token, osal_offset_t offset, uint32 whence) { UT_GenStub_SetupReturnBuffer(OS_GenericSeek_Impl, int32); UT_GenStub_AddParam(OS_GenericSeek_Impl, const OS_object_token_t *, token); - UT_GenStub_AddParam(OS_GenericSeek_Impl, int32, offset); + UT_GenStub_AddParam(OS_GenericSeek_Impl, osal_offset_t, offset); UT_GenStub_AddParam(OS_GenericSeek_Impl, uint32, whence); UT_GenStub_Execute(OS_GenericSeek_Impl, Basic, NULL); diff --git a/src/unit-test-coverage/ut-stubs/src/posix-fcntl-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-fcntl-stubs.c index 433be792e..886721865 100644 --- a/src/unit-test-coverage/ut-stubs/src/posix-fcntl-stubs.c +++ b/src/unit-test-coverage/ut-stubs/src/posix-fcntl-stubs.c @@ -40,3 +40,21 @@ int OCS_open(const char *file, int oflag, ...) return Status; } + +int OCS_posix_fallocate(int fd, OCS_off_t offset, OCS_off_t len) +{ + int32 Status; + + Status = UT_DEFAULT_IMPL(OCS_posix_fallocate); + + return Status; +} + +int OCS_ftruncate(int fd, OCS_off_t len) +{ + int32 Status; + + Status = UT_DEFAULT_IMPL(OCS_ftruncate); + + return Status; +} diff --git a/src/unit-test-coverage/vxworks/CMakeLists.txt b/src/unit-test-coverage/vxworks/CMakeLists.txt index f81bd519b..f4d7ce0b5 100644 --- a/src/unit-test-coverage/vxworks/CMakeLists.txt +++ b/src/unit-test-coverage/vxworks/CMakeLists.txt @@ -25,6 +25,7 @@ set(VXWORKS_PORTABLE_BLOCK_LIST posix-gettime posix-io posix-files + posix-file-allocate posix-dirs console-bsp @@ -38,6 +39,7 @@ set(VXWORKS_PORTABLE_BLOCK_LIST no-network-gethostid no-sockets no-condvar + no-file-allocate ) diff --git a/src/ut-stubs/osapi-file-handlers.c b/src/ut-stubs/osapi-file-handlers.c index bea4c9a32..60b3533b5 100644 --- a/src/ut-stubs/osapi-file-handlers.c +++ b/src/ut-stubs/osapi-file-handlers.c @@ -214,7 +214,7 @@ void UT_DefaultHandler_OS_stat(void *UserObj, UT_EntryKey_t FuncKey, const UT_St */ void UT_DefaultHandler_OS_lseek(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) { - int32 offset = UT_Hook_GetArgValueByName(Context, "offset", int32); + int32 offset = UT_Hook_GetArgValueByName(Context, "offset", osal_offset_t); int32 Status; if (UT_Stub_GetInt32StatusCode(Context, &Status)) diff --git a/src/ut-stubs/osapi-file-stubs.c b/src/ut-stubs/osapi-file-stubs.c index 9adb0fb65..6618da61a 100644 --- a/src/ut-stubs/osapi-file-stubs.c +++ b/src/ut-stubs/osapi-file-stubs.c @@ -82,6 +82,24 @@ int32 OS_FDGetInfo(osal_id_t filedes, OS_file_prop_t *fd_prop) return UT_GenStub_GetReturnValue(OS_FDGetInfo, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_FileAllocate() + * ---------------------------------------------------- + */ +int32 OS_FileAllocate(osal_id_t filedes, osal_offset_t offset, osal_offset_t len) +{ + UT_GenStub_SetupReturnBuffer(OS_FileAllocate, int32); + + UT_GenStub_AddParam(OS_FileAllocate, osal_id_t, filedes); + UT_GenStub_AddParam(OS_FileAllocate, osal_offset_t, offset); + UT_GenStub_AddParam(OS_FileAllocate, osal_offset_t, len); + + UT_GenStub_Execute(OS_FileAllocate, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_FileAllocate, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_FileOpenCheck() @@ -98,6 +116,23 @@ int32 OS_FileOpenCheck(const char *Filename) return UT_GenStub_GetReturnValue(OS_FileOpenCheck, int32); } +/* + * ---------------------------------------------------- + * Generated stub function for OS_FileTruncate() + * ---------------------------------------------------- + */ +int32 OS_FileTruncate(osal_id_t filedes, osal_offset_t len) +{ + UT_GenStub_SetupReturnBuffer(OS_FileTruncate, int32); + + UT_GenStub_AddParam(OS_FileTruncate, osal_id_t, filedes); + UT_GenStub_AddParam(OS_FileTruncate, osal_offset_t, len); + + UT_GenStub_Execute(OS_FileTruncate, Basic, NULL); + + return UT_GenStub_GetReturnValue(OS_FileTruncate, int32); +} + /* * ---------------------------------------------------- * Generated stub function for OS_OpenCreate() @@ -248,12 +283,12 @@ int32 OS_cp(const char *src, const char *dest) * Generated stub function for OS_lseek() * ---------------------------------------------------- */ -int32 OS_lseek(osal_id_t filedes, int32 offset, uint32 whence) +int32 OS_lseek(osal_id_t filedes, osal_offset_t offset, uint32 whence) { UT_GenStub_SetupReturnBuffer(OS_lseek, int32); UT_GenStub_AddParam(OS_lseek, osal_id_t, filedes); - UT_GenStub_AddParam(OS_lseek, int32, offset); + UT_GenStub_AddParam(OS_lseek, osal_offset_t, offset); UT_GenStub_AddParam(OS_lseek, uint32, whence); UT_GenStub_Execute(OS_lseek, Basic, UT_DefaultHandler_OS_lseek); From fb7b335c70cf150bf1b7118a9da9748c10a00c3b Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 14 Oct 2025 18:03:06 -0400 Subject: [PATCH 50/51] Fix cFS/cFS#280, add DNS support to OS_SocketAddrFromString Adds an alternative implementation of OS_SocketAddrFromString that uses the getaddrinfo() system call to look up the name in DNS (or whatever network name service is configured). Without changing the API, this can only return the first address. The existing (non-DNS) option is retained for RTOSs that may not have this feature. The DNS version is only enabled on posix for now. --- src/os/inc/osapi-error.h | 2 + src/os/portable/os-impl-bsd-sockets-common.h | 99 ++++++++++ src/os/portable/os-impl-bsd-sockets-dns.c | 171 +++++++++++++++++ src/os/portable/os-impl-bsd-sockets-no-dns.c | 128 +++++++++++++ src/os/portable/os-impl-bsd-sockets.c | 103 +--------- src/os/posix/CMakeLists.txt | 1 + src/os/posix/inc/os-impl-sockets.h | 1 + src/os/qnx/CMakeLists.txt | 1 + src/os/rtems/CMakeLists.txt | 1 + src/os/vxworks-rtp/CMakeLists.txt | 1 + src/os/vxworks/CMakeLists.txt | 1 + src/tests/network-api-test/network-api-test.c | 17 +- .../src/coveragetest-bsd-sockets-dns.c | 181 ++++++++++++++++++ .../src/coveragetest-bsd-sockets-no-dns.c | 121 ++++++++++++ .../portable/src/coveragetest-bsd-sockets.c | 47 ----- .../ut-stubs/CMakeLists.txt | 1 + .../ut-stubs/inc/OCS_netdb.h | 22 +++ .../ut-stubs/override_inc/netdb.h | 8 + .../ut-stubs/src/posix-netdb-stubs.c | 76 ++++++++ src/unit-test-coverage/vxworks/CMakeLists.txt | 8 + 20 files changed, 838 insertions(+), 152 deletions(-) create mode 100644 src/os/portable/os-impl-bsd-sockets-common.h create mode 100644 src/os/portable/os-impl-bsd-sockets-dns.c create mode 100644 src/os/portable/os-impl-bsd-sockets-no-dns.c create mode 100644 src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-dns.c create mode 100644 src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-no-dns.c create mode 100644 src/unit-test-coverage/ut-stubs/src/posix-netdb-stubs.c diff --git a/src/os/inc/osapi-error.h b/src/os/inc/osapi-error.h index 7dc911fb2..15fe27da2 100644 --- a/src/os/inc/osapi-error.h +++ b/src/os/inc/osapi-error.h @@ -129,6 +129,8 @@ typedef char os_status_string_t[OS_STATUS_STRING_LENGTH]; #define OS_ERR_INVALID_SIZE (-40) /**< @brief Invalid Size */ #define OS_ERR_OUTPUT_TOO_LARGE (-41) /**< @brief Size of output exceeds limit */ #define OS_ERR_INVALID_ARGUMENT (-42) /**< @brief Invalid argument value (other than ID or size) */ +#define OS_ERR_TRY_AGAIN (-43) /**< @brief Failure is temporary in nature, call may be repeated */ +#define OS_ERR_EMPTY_SET (-44) /**< @brief Address or name lookup returned no results */ /* ** Defines for File System Calls diff --git a/src/os/portable/os-impl-bsd-sockets-common.h b/src/os/portable/os-impl-bsd-sockets-common.h new file mode 100644 index 000000000..e14b7ba8b --- /dev/null +++ b/src/os/portable/os-impl-bsd-sockets-common.h @@ -0,0 +1,99 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * Purpose: This file contains the network functionality for + * systems which implement the BSD-style socket API. + */ + +#ifndef OS_IMPL_BSD_SOCKETS_COMMON_H +#define OS_IMPL_BSD_SOCKETS_COMMON_H + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +/* + * Inclusions Defined by OSAL layer. + * + * This must include whatever is required to get the prototypes of these functions: + * + * socket() + * getsockopt() + * setsockopt() + * fcntl() + * bind() + * listen() + * accept() + * connect() + * recvfrom() + * sendto() + * inet_pton() + * ntohl()/ntohs() + * + * As well as any headers for the struct sockaddr type and any address families in use + */ +#include +#include + +#include "os-impl-sockets.h" +#include "os-shared-file.h" +#include "os-shared-sockets.h" +#include "os-shared-idmap.h" + +/**************************************************************************************** + DEFINES +****************************************************************************************/ + +/* + * The OS layer may define a macro to set the proper flags on newly-opened sockets. + * If not set, then a default implementation is used, which uses fcntl() to set O_NONBLOCK + */ +#ifndef OS_IMPL_SOCKET_FLAGS +#ifdef O_NONBLOCK +#define OS_IMPL_SOCKET_FLAGS O_NONBLOCK +#else +#define OS_IMPL_SOCKET_FLAGS 0 /* do not set any flags */ +#endif +#endif + +#ifndef OS_IMPL_SET_SOCKET_FLAGS +#define OS_IMPL_SET_SOCKET_FLAGS(tok) OS_SetSocketDefaultFlags_Impl(tok) +#endif + +typedef union +{ + char data[OS_SOCKADDR_MAX_LEN]; + struct sockaddr sa; + struct sockaddr_in sa_in; +#ifdef OS_NETWORK_SUPPORTS_IPV6 + struct sockaddr_in6 sa_in6; +#endif +} OS_SockAddr_Accessor_t; + +/* + * Default flags implementation: Set the O_NONBLOCK flag via fcntl(). + * An implementation can also elect custom configuration by setting + * the OS_IMPL_SET_SOCKET_FLAGS macro to point to an alternate function. + */ +void OS_SetSocketDefaultFlags_Impl(const OS_object_token_t *token); + +#endif /* OS_IMPL_BSD_SOCKETS_COMMON_H */ diff --git a/src/os/portable/os-impl-bsd-sockets-dns.c b/src/os/portable/os-impl-bsd-sockets-dns.c new file mode 100644 index 000000000..768e5d050 --- /dev/null +++ b/src/os/portable/os-impl-bsd-sockets-dns.c @@ -0,0 +1,171 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * Purpose: This file contains the network functionality for + * systems which implement the BSD-style socket API. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +/* + * Inclusions Defined by OSAL layer. + * + * This must include whatever is required to get the prototypes of these functions: + * + * socket() + * getsockopt() + * setsockopt() + * fcntl() + * bind() + * listen() + * accept() + * connect() + * recvfrom() + * sendto() + * inet_pton() + * ntohl()/ntohs() + * + * As well as any headers for the struct sockaddr type and any address families in use + */ +#include "os-impl-bsd-sockets-common.h" +#include + +/**************************************************************************************** + DEFINES +****************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketAddrToString_Impl(char *buffer, size_t buflen, const OS_SockAddr_t *Addr) +{ + int32 status; + const OS_SockAddr_Accessor_t *Accessor; + int rc; + + Accessor = (const OS_SockAddr_Accessor_t *)&Addr->AddrData; + + switch (Accessor->sa.sa_family) + { + case AF_INET: + break; +#ifdef OS_NETWORK_SUPPORTS_IPV6 + case AF_INET6: + break; +#endif + default: + return OS_ERR_BAD_ADDRESS; + break; + } + + rc = getnameinfo(&Accessor->sa, Addr->ActualLength, buffer, buflen, NULL, 0, 0); + if (rc == 0) + { + status = OS_SUCCESS; + } + else if (rc == EAI_AGAIN) + { + status = OS_ERR_TRY_AGAIN; + } + else if (rc == EAI_NONAME) + { + status = OS_ERR_EMPTY_SET; + } + else + { + status = OS_ERROR; + } + + return status; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketAddrFromString_Impl(OS_SockAddr_t *Addr, const char *string) +{ + int32 status; + size_t addr_offset; + size_t addr_len; + OS_SockAddr_Accessor_t *Accessor; + struct addrinfo * res; + struct addrinfo * rp; + int rc; + + Accessor = (OS_SockAddr_Accessor_t *)&Addr->AddrData; + + switch (Accessor->sa.sa_family) + { + case AF_INET: + addr_offset = offsetof(struct sockaddr_in, sin_addr); + addr_len = sizeof(Accessor->sa_in.sin_addr); + break; +#ifdef OS_NETWORK_SUPPORTS_IPV6 + case AF_INET6: + addr_offset = offsetof(struct sockaddr_in6, sin6_addr); + addr_len = sizeof(Accessor->sa_in6.sin6_addr); + break; +#endif + default: + return OS_ERR_BAD_ADDRESS; + break; + } + + status = OS_ERR_EMPTY_SET; + + rc = getaddrinfo(string, NULL, NULL, &res); + if (rc == 0) + { + for (rp = res; rp != NULL; rp = rp->ai_next) + { + /* the library call should never return something that does not meet this criteria */ + if (rp->ai_family == Accessor->sa.sa_family && rp->ai_addrlen >= sizeof(struct sockaddr)) + { + memcpy(&Addr->AddrData.Buffer[addr_offset], (const char *)rp->ai_addr + addr_offset, addr_len); + Addr->ActualLength = rp->ai_addrlen; + status = OS_SUCCESS; + break; + } + } + + freeaddrinfo(res); + } + else if (rc == EAI_AGAIN) + { + /* Indicate the error is temporary; treat this like a timeout or similar */ + status = OS_ERR_TRY_AGAIN; + } + else if (rc != EAI_NONAME) + { + status = OS_ERROR; + } + + return status; +} diff --git a/src/os/portable/os-impl-bsd-sockets-no-dns.c b/src/os/portable/os-impl-bsd-sockets-no-dns.c new file mode 100644 index 000000000..cfce71fc8 --- /dev/null +++ b/src/os/portable/os-impl-bsd-sockets-no-dns.c @@ -0,0 +1,128 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \file + * \author joseph.p.hickey@nasa.gov + * + * Purpose: This file contains the network functionality for + * systems which implement the BSD-style socket API. + */ + +/**************************************************************************************** + INCLUDE FILES + ***************************************************************************************/ + +/* + * Inclusions Defined by OSAL layer. + * + * This must include whatever is required to get the prototypes of these functions: + * + * socket() + * getsockopt() + * setsockopt() + * fcntl() + * bind() + * listen() + * accept() + * connect() + * recvfrom() + * sendto() + * inet_pton() + * ntohl()/ntohs() + * + * As well as any headers for the struct sockaddr type and any address families in use + */ +#include "os-impl-bsd-sockets-common.h" + +/**************************************************************************************** + DEFINES +****************************************************************************************/ + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketAddrToString_Impl(char *buffer, size_t buflen, const OS_SockAddr_t *Addr) +{ + const void * addrbuffer; + const OS_SockAddr_Accessor_t *Accessor; + + Accessor = (const OS_SockAddr_Accessor_t *)&Addr->AddrData; + + switch (Accessor->sa.sa_family) + { + case AF_INET: + addrbuffer = &Accessor->sa_in.sin_addr; + break; +#ifdef OS_NETWORK_SUPPORTS_IPV6 + case AF_INET6: + addrbuffer = &Accessor->sa_in6.sin6_addr; + break; +#endif + default: + return OS_ERR_BAD_ADDRESS; + break; + } + + if (inet_ntop(Accessor->sa.sa_family, addrbuffer, buffer, buflen) == NULL) + { + return OS_ERROR; + } + + return OS_SUCCESS; +} + +/*---------------------------------------------------------------- + * + * Purpose: Implemented per internal OSAL API + * See prototype for argument/return detail + * + *-----------------------------------------------------------------*/ +int32 OS_SocketAddrFromString_Impl(OS_SockAddr_t *Addr, const char *string) +{ + void * addrbuffer; + OS_SockAddr_Accessor_t *Accessor; + + Accessor = (OS_SockAddr_Accessor_t *)&Addr->AddrData; + + switch (Accessor->sa.sa_family) + { + case AF_INET: + addrbuffer = &Accessor->sa_in.sin_addr; + break; +#ifdef OS_NETWORK_SUPPORTS_IPV6 + case AF_INET6: + addrbuffer = &Accessor->sa_in6.sin6_addr; + break; +#endif + default: + return OS_ERR_BAD_ADDRESS; + break; + } + + /* This function is defined as returning 1 on success, not 0 */ + if (inet_pton(Accessor->sa.sa_family, string, addrbuffer) != 1) + { + return OS_ERROR; + } + + return OS_SUCCESS; +} diff --git a/src/os/portable/os-impl-bsd-sockets.c b/src/os/portable/os-impl-bsd-sockets.c index f33b789e1..56c186ce8 100644 --- a/src/os/portable/os-impl-bsd-sockets.c +++ b/src/os/portable/os-impl-bsd-sockets.c @@ -51,43 +51,15 @@ #include #include -#include "os-impl-sockets.h" +#include "os-impl-bsd-sockets-common.h" #include "os-shared-clock.h" #include "os-shared-file.h" #include "os-shared-select.h" -#include "os-shared-sockets.h" -#include "os-shared-idmap.h" /**************************************************************************************** DEFINES ****************************************************************************************/ -/* - * The OS layer may define a macro to set the proper flags on newly-opened sockets. - * If not set, then a default implementation is used, which uses fcntl() to set O_NONBLOCK - */ -#ifndef OS_IMPL_SOCKET_FLAGS -#ifdef O_NONBLOCK -#define OS_IMPL_SOCKET_FLAGS O_NONBLOCK -#else -#define OS_IMPL_SOCKET_FLAGS 0 /* do not set any flags */ -#endif -#endif - -#ifndef OS_IMPL_SET_SOCKET_FLAGS -#define OS_IMPL_SET_SOCKET_FLAGS(tok) OS_SetSocketDefaultFlags_Impl(tok) -#endif - -typedef union -{ - char data[OS_SOCKADDR_MAX_LEN]; - struct sockaddr sa; - struct sockaddr_in sa_in; -#ifdef OS_NETWORK_SUPPORTS_IPV6 - struct sockaddr_in6 sa_in6; -#endif -} OS_SockAddr_Accessor_t; - /* * Confirm that the abstract socket address buffer size (OS_SOCKADDR_MAX_LEN) is * large enough to store any of the enabled address types. If this is true, the @@ -786,79 +758,6 @@ int32 OS_SocketAddrInit_Impl(OS_SockAddr_t *Addr, OS_SocketDomain_t Domain) return OS_SUCCESS; } -/*---------------------------------------------------------------- - * - * Purpose: Implemented per internal OSAL API - * See prototype for argument/return detail - * - *-----------------------------------------------------------------*/ -int32 OS_SocketAddrToString_Impl(char *buffer, size_t buflen, const OS_SockAddr_t *Addr) -{ - const void * addrbuffer; - const OS_SockAddr_Accessor_t *Accessor; - - Accessor = (const OS_SockAddr_Accessor_t *)&Addr->AddrData; - - switch (Accessor->sa.sa_family) - { - case AF_INET: - addrbuffer = &Accessor->sa_in.sin_addr; - break; -#ifdef OS_NETWORK_SUPPORTS_IPV6 - case AF_INET6: - addrbuffer = &Accessor->sa_in6.sin6_addr; - break; -#endif - default: - return OS_ERR_BAD_ADDRESS; - break; - } - - if (inet_ntop(Accessor->sa.sa_family, addrbuffer, buffer, buflen) == NULL) - { - return OS_ERROR; - } - - return OS_SUCCESS; -} - -/*---------------------------------------------------------------- - * - * Purpose: Implemented per internal OSAL API - * See prototype for argument/return detail - * - *-----------------------------------------------------------------*/ -int32 OS_SocketAddrFromString_Impl(OS_SockAddr_t *Addr, const char *string) -{ - void * addrbuffer; - OS_SockAddr_Accessor_t *Accessor; - - Accessor = (OS_SockAddr_Accessor_t *)&Addr->AddrData; - - switch (Accessor->sa.sa_family) - { - case AF_INET: - addrbuffer = &Accessor->sa_in.sin_addr; - break; -#ifdef OS_NETWORK_SUPPORTS_IPV6 - case AF_INET6: - addrbuffer = &Accessor->sa_in6.sin6_addr; - break; -#endif - default: - return OS_ERR_BAD_ADDRESS; - break; - } - - /* This function is defined as returning 1 on success, not 0 */ - if (inet_pton(Accessor->sa.sa_family, string, addrbuffer) != 1) - { - return OS_ERROR; - } - - return OS_SUCCESS; -} - /*---------------------------------------------------------------- * * Purpose: Implemented per internal OSAL API diff --git a/src/os/posix/CMakeLists.txt b/src/os/posix/CMakeLists.txt index cdeb36fb9..ca571021a 100644 --- a/src/os/posix/CMakeLists.txt +++ b/src/os/posix/CMakeLists.txt @@ -65,6 +65,7 @@ endif () if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation + ../portable/os-impl-bsd-sockets-dns.c # Use functions that invoke DNS ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation ../portable/os-impl-posix-network-gethostid.c # Use POSIX-defined hostid implementation ) diff --git a/src/os/posix/inc/os-impl-sockets.h b/src/os/posix/inc/os-impl-sockets.h index e18a612d7..bb709573f 100644 --- a/src/os/posix/inc/os-impl-sockets.h +++ b/src/os/posix/inc/os-impl-sockets.h @@ -34,6 +34,7 @@ #include #include #include +#include #define OS_NETWORK_SUPPORTS_IPV6 diff --git a/src/os/qnx/CMakeLists.txt b/src/os/qnx/CMakeLists.txt index d5191a636..a3c6bf384 100644 --- a/src/os/qnx/CMakeLists.txt +++ b/src/os/qnx/CMakeLists.txt @@ -74,6 +74,7 @@ endif () if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation + ../portable/os-impl-bsd-sockets-no-dns.c # Use functions that do not require DNS ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation ) else() diff --git a/src/os/rtems/CMakeLists.txt b/src/os/rtems/CMakeLists.txt index 7aab8e18f..5430b16c9 100644 --- a/src/os/rtems/CMakeLists.txt +++ b/src/os/rtems/CMakeLists.txt @@ -62,6 +62,7 @@ if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND RTEMS_IMPL_SRCLIST src/os-impl-network.c ../portable/os-impl-bsd-sockets.c + ../portable/os-impl-bsd-sockets-no-dns.c # Use functions that do not require DNS ../portable/os-impl-bsd-select.c ) diff --git a/src/os/vxworks-rtp/CMakeLists.txt b/src/os/vxworks-rtp/CMakeLists.txt index 29f28c7c1..d8936f213 100644 --- a/src/os/vxworks-rtp/CMakeLists.txt +++ b/src/os/vxworks-rtp/CMakeLists.txt @@ -79,6 +79,7 @@ list(APPEND POSIX_IMPL_SRCLIST if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND POSIX_IMPL_SRCLIST ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation + ../portable/os-impl-bsd-sockets-no-dns.c # Use functions that do not require DNS ../portable/os-impl-posix-network-gethostname.c # Use POSIX-defined hostname implementation ) else() diff --git a/src/os/vxworks/CMakeLists.txt b/src/os/vxworks/CMakeLists.txt index 4d78d401a..d982fe408 100644 --- a/src/os/vxworks/CMakeLists.txt +++ b/src/os/vxworks/CMakeLists.txt @@ -67,6 +67,7 @@ if (OSAL_CONFIG_INCLUDE_NETWORK) list(APPEND VXWORKS_IMPL_SRCLIST src/os-impl-network.c ../portable/os-impl-bsd-sockets.c # Use BSD socket layer implementation + ../portable/os-impl-bsd-sockets-no-dns.c # Use functions that do not require DNS src/os-impl-sockets.c # Additional vxworks-specific code to handle socket flags ) else() diff --git a/src/tests/network-api-test/network-api-test.c b/src/tests/network-api-test/network-api-test.c index cfd53d4c3..1800dbab5 100644 --- a/src/tests/network-api-test/network-api-test.c +++ b/src/tests/network-api-test/network-api-test.c @@ -111,7 +111,9 @@ void TestNetworkApiBadArgs(void) /* OS_SocketAddrFromString */ UtAssert_INT32_EQ(OS_SocketAddrFromString(NULL, "127.0.0.1"), OS_INVALID_POINTER); UtAssert_INT32_EQ(OS_SocketAddrFromString(&addr, NULL), OS_INVALID_POINTER); - UtAssert_INT32_EQ(OS_SocketAddrFromString(&addr, "invalid"), OS_ERROR); + /* Note that if DNS is enabled, there is no guarantee of what the return value + * of this API call will be. It could be OS_ERROR, OS_ERR_EMPTY_SET, or even OS_SUCCESS */ + UtAssert_VOIDCALL(OS_SocketAddrFromString(&addr, "invalid")); /* OS_SocketAddrToString */ UtAssert_INT32_EQ(OS_SocketAddrToString(addr_string, 0, &addr), OS_ERR_INVALID_SIZE); @@ -335,9 +337,18 @@ void TestDatagramNetworkApi(void) /* Get socket info and verify */ UtAssert_INT32_EQ(OS_SocketGetInfo(p1_socket_id, &prop), OS_SUCCESS); UtAssert_True(!OS_ObjectIdDefined(prop.creator), "prop.creator (%lu) == 0", OS_ObjectIdToInteger(prop.creator)); - UtAssert_True(strcmp(prop.name, "127.0.0.1:9999") == 0, "prop.name (%s) == 127.0.0.1:9999", prop.name); - UtAssert_INT32_EQ(OS_SocketGetIdByName(&objid, "127.0.0.1:9999"), OS_SUCCESS); + /* Depending on whether the target is using the DNS version, it may resolve to "localhost" */ + if (strncmp(prop.name, "127", 3) == 0) + { + UtAssert_STRINGBUF_EQ(prop.name, sizeof(prop.name), "127.0.0.1:9999", -1); + } + else + { + UtAssert_STRINGBUF_EQ(prop.name, sizeof(prop.name), "localhost:9999", -1); + } + + UtAssert_INT32_EQ(OS_SocketGetIdByName(&objid, prop.name), OS_SUCCESS); UtAssert_True(OS_ObjectIdEqual(objid, p1_socket_id), "objid (%lu) == p1_socket_id", OS_ObjectIdToInteger(objid)); } diff --git a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-dns.c b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-dns.c new file mode 100644 index 000000000..6d0c067b1 --- /dev/null +++ b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-dns.c @@ -0,0 +1,181 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \brief Coverage test for no network implementation + * \ingroup portable + */ + +#include "os-portable-coveragetest.h" +#include "os-shared-sockets.h" +#include "os-shared-idmap.h" +#include "os-shared-file.h" +#include "os-shared-select.h" +#include "os-impl-io.h" + +#include "OCS_sys_socket.h" +#include "OCS_errno.h" +#include "OCS_fcntl.h" +#include "OCS_arpa_inet.h" +#include "OCS_netdb.h" + +#include "ut-adaptor-portable-posix-io.h" + +/* Unique error code for return testing */ +#define UT_ERR_UNIQUE 0xDEADBEEF + +/* Buffer size */ +#define UT_BUFFER_SIZE 16 + +void Test_OS_SocketAddrToString_Impl(void) +{ + char buffer[UT_BUFFER_SIZE]; + OS_SockAddr_t addr = {0}; + struct OCS_sockaddr *sa = (struct OCS_sockaddr *)&addr.AddrData; + + /* Bad family */ + sa->sa_family = -1; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERR_BAD_ADDRESS); + + sa->sa_family = OCS_AF_INET6; + UT_SetDeferredRetcode(UT_KEY(OCS_getnameinfo), 1, OCS_EAI_NONAME); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERR_EMPTY_SET); + + sa->sa_family = OCS_AF_INET; + UT_SetDeferredRetcode(UT_KEY(OCS_getnameinfo), 1, OCS_EAI_AGAIN); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERR_TRY_AGAIN); + + /* other error */ + UT_SetDeferredRetcode(UT_KEY(OCS_getnameinfo), 1, -1); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERROR); + + /* AF_INET6, success */ + sa->sa_family = OCS_AF_INET6; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_SUCCESS); + + /* AF_INET, success */ + sa->sa_family = OCS_AF_INET; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_SUCCESS); +} + +void Test_OS_SocketAddrFromString_Impl(void) +{ + const char buffer[UT_BUFFER_SIZE] = "UT"; + OS_SockAddr_t addr = {0}; + struct OCS_sockaddr *sa = (struct OCS_sockaddr *)&addr.AddrData; + struct OCS_addrinfo ai; + struct OCS_addrinfo *aip; + + union + { + struct OCS_sockaddr sa; + struct OCS_sockaddr_in sa_in4; + struct OCS_sockaddr_in6 sa_in6; + } sa_buf; + + /* Bad family */ + sa->sa_family = -1; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_BAD_ADDRESS); + + sa->sa_family = OCS_AF_INET6; + UT_SetDeferredRetcode(UT_KEY(OCS_getaddrinfo), 1, OCS_EAI_NONAME); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_EMPTY_SET); + + sa->sa_family = OCS_AF_INET; + UT_SetDeferredRetcode(UT_KEY(OCS_getaddrinfo), 1, OCS_EAI_AGAIN); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_TRY_AGAIN); + + /* other error */ + UT_SetDeferredRetcode(UT_KEY(OCS_getaddrinfo), 1, -1); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERROR); + + /* AF_INET6, empty result, but still needs freeing */ + sa->sa_family = OCS_AF_INET6; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_EMPTY_SET); + UtAssert_STUB_COUNT(OCS_freeaddrinfo, 1); + + /* AF_INET, empty result, but still needs freeing */ + sa->sa_family = OCS_AF_INET; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_EMPTY_SET); + UtAssert_STUB_COUNT(OCS_freeaddrinfo, 2); + + /* set up stub for successful return */ + memset(&ai, 0, sizeof(ai)); + memset(&sa_buf, 0, sizeof(sa_buf)); + + sa->sa_family = OCS_AF_INET; + ai.ai_family = sa->sa_family; + ai.ai_addrlen = sizeof(struct OCS_sockaddr_in); + ai.ai_addr = &sa_buf.sa; + + aip = &ai; + UT_SetDataBuffer(UT_KEY(OCS_getaddrinfo), &aip, sizeof(aip), false); + + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_SUCCESS); + UtAssert_STUB_COUNT(OCS_freeaddrinfo, 3); + UtAssert_EQ(size_t, addr.ActualLength, ai.ai_addrlen); + + sa->sa_family = OCS_AF_INET6; + ai.ai_family = sa->sa_family; + ai.ai_addrlen = sizeof(struct OCS_sockaddr_in6); + ai.ai_addr = &sa_buf.sa; + + aip = &ai; + UT_SetDataBuffer(UT_KEY(OCS_getaddrinfo), &aip, sizeof(aip), false); + + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_SUCCESS); + UtAssert_STUB_COUNT(OCS_freeaddrinfo, 4); + UtAssert_EQ(size_t, addr.ActualLength, ai.ai_addrlen); + + /* wrong family */ + ai.ai_family = OCS_AF_INET; + UT_SetDataBuffer(UT_KEY(OCS_getaddrinfo), &aip, sizeof(aip), false); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_EMPTY_SET); + UtAssert_STUB_COUNT(OCS_freeaddrinfo, 5); +} + +/* ------------------- End of test cases --------------------------------------*/ + +/* Osapi_Test_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void Osapi_Test_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Osapi_Test_Teardown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void Osapi_Test_Teardown(void) {} + +/* UtTest_Setup + * + * Purpose: + * Registers the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(OS_SocketAddrToString_Impl); + ADD_TEST(OS_SocketAddrFromString_Impl); +} diff --git a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-no-dns.c b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-no-dns.c new file mode 100644 index 000000000..7d5cc094a --- /dev/null +++ b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets-no-dns.c @@ -0,0 +1,121 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/** + * \brief Coverage test for no network implementation + * \ingroup portable + */ + +#include "os-portable-coveragetest.h" +#include "os-shared-sockets.h" +#include "os-shared-idmap.h" +#include "os-shared-file.h" +#include "os-shared-select.h" + +#include "OCS_sys_socket.h" +#include "OCS_errno.h" +#include "OCS_fcntl.h" +#include "OCS_arpa_inet.h" + +#include "ut-adaptor-portable-posix-io.h" + +/* Unique error code for return testing */ +#define UT_ERR_UNIQUE 0xDEADBEEF + +/* Buffer size */ +#define UT_BUFFER_SIZE 16 + +void Test_OS_SocketAddrToString_Impl(void) +{ + char buffer[UT_BUFFER_SIZE]; + OS_SockAddr_t addr = {0}; + struct OCS_sockaddr *sa = (struct OCS_sockaddr *)&addr.AddrData; + + /* Bad family */ + sa->sa_family = -1; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERR_BAD_ADDRESS); + + /* AF_INET6 success */ + sa->sa_family = OCS_AF_INET6; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_SUCCESS); + + /* AF_INET, success */ + sa->sa_family = OCS_AF_INET; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_SUCCESS); + + /* AF_INET failed inet_ntop */ + UT_SetDeferredRetcode(UT_KEY(OCS_inet_ntop), 1, -1); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERROR); +} + +void Test_OS_SocketAddrFromString_Impl(void) +{ + const char buffer[UT_BUFFER_SIZE] = "UT"; + OS_SockAddr_t addr = {0}; + struct OCS_sockaddr *sa = (struct OCS_sockaddr *)&addr.AddrData; + + /* Bad family */ + sa->sa_family = -1; + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_BAD_ADDRESS); + + /* AF_INET6 success */ + sa->sa_family = OCS_AF_INET6; + UT_SetDeferredRetcode(UT_KEY(OCS_inet_pton), 1, 1); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_SUCCESS); + + /* AF_INET, success */ + sa->sa_family = OCS_AF_INET; + UT_SetDeferredRetcode(UT_KEY(OCS_inet_pton), 1, 1); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_SUCCESS); + + /* AF_INET, unable to convert (note inet_pton returns 0 if it failed) */ + sa->sa_family = OCS_AF_INET; + UT_SetDeferredRetcode(UT_KEY(OCS_inet_pton), 1, 0); + OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERROR); +} + +/* ------------------- End of test cases --------------------------------------*/ + +/* Osapi_Test_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void Osapi_Test_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Osapi_Test_Teardown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void Osapi_Test_Teardown(void) {} + +/* UtTest_Setup + * + * Purpose: + * Registers the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(OS_SocketAddrToString_Impl); + ADD_TEST(OS_SocketAddrFromString_Impl); +} diff --git a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c index 5741a2f37..12a1f3d25 100644 --- a/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c +++ b/src/unit-test-coverage/portable/src/coveragetest-bsd-sockets.c @@ -455,51 +455,6 @@ void Test_OS_SocketAddrInit_Impl(void) UtAssert_INT32_EQ(addr.ActualLength, sizeof(struct OCS_sockaddr_in6)); } -void Test_OS_SocketAddrToString_Impl(void) -{ - char buffer[UT_BUFFER_SIZE]; - OS_SockAddr_t addr = {0}; - struct OCS_sockaddr *sa = (struct OCS_sockaddr *)&addr.AddrData; - - /* Bad family */ - sa->sa_family = -1; - OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERR_BAD_ADDRESS); - - /* AF_INET6 failed inet_ntop */ - sa->sa_family = OCS_AF_INET6; - UT_SetDeferredRetcode(UT_KEY(OCS_inet_ntop), 1, -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_ERROR); - - /* AF_INET, success */ - sa->sa_family = OCS_AF_INET; - OSAPI_TEST_FUNCTION_RC(OS_SocketAddrToString_Impl, (buffer, sizeof(buffer), &addr), OS_SUCCESS); -} - -void Test_OS_SocketAddrFromString_Impl(void) -{ - const char buffer[UT_BUFFER_SIZE] = "UT"; - OS_SockAddr_t addr = {0}; - struct OCS_sockaddr *sa = (struct OCS_sockaddr *)&addr.AddrData; - - /* Bad family */ - sa->sa_family = -1; - OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERR_BAD_ADDRESS); - - /* AF_INET6 failed inet_ntop */ - sa->sa_family = OCS_AF_INET6; - UT_SetDeferredRetcode(UT_KEY(OCS_inet_pton), 1, -1); - OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERROR); - - /* AF_INET, unable to convert (note inet_pton returns 0 if it failed) */ - sa->sa_family = OCS_AF_INET; - UT_SetDeferredRetcode(UT_KEY(OCS_inet_pton), 1, 0); - OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_ERROR); - - /* AF_INET, success */ - UT_SetDeferredRetcode(UT_KEY(OCS_inet_pton), 1, 1); - OSAPI_TEST_FUNCTION_RC(OS_SocketAddrFromString_Impl, (&addr, buffer), OS_SUCCESS); -} - void Test_OS_SocketAddrGetPort_Impl(void) { uint16 port; @@ -577,8 +532,6 @@ void UtTest_Setup(void) ADD_TEST(OS_SocketSendTo_Impl); ADD_TEST(OS_SocketGetInfo_Impl); ADD_TEST(OS_SocketAddrInit_Impl); - ADD_TEST(OS_SocketAddrToString_Impl); - ADD_TEST(OS_SocketAddrFromString_Impl); ADD_TEST(OS_SocketAddrGetPort_Impl); ADD_TEST(OS_SocketAddrSetPort_Impl); ADD_TEST(OS_SocketGetOption_Impl); diff --git a/src/unit-test-coverage/ut-stubs/CMakeLists.txt b/src/unit-test-coverage/ut-stubs/CMakeLists.txt index 41c67910b..ccd585a7e 100644 --- a/src/unit-test-coverage/ut-stubs/CMakeLists.txt +++ b/src/unit-test-coverage/ut-stubs/CMakeLists.txt @@ -56,6 +56,7 @@ add_library(ut_libc_stubs STATIC EXCLUDE_FROM_ALL src/posix-fcntl-stubs.c src/posix-ioctl-stubs.c src/posix-mqueue-stubs.c + src/posix-netdb-stubs.c src/posix-pthread-stubs.c src/posix-sched-stubs.c src/posix-semaphore-stubs.c diff --git a/src/unit-test-coverage/ut-stubs/inc/OCS_netdb.h b/src/unit-test-coverage/ut-stubs/inc/OCS_netdb.h index 0e3d7b2d2..35f600434 100644 --- a/src/unit-test-coverage/ut-stubs/inc/OCS_netdb.h +++ b/src/unit-test-coverage/ut-stubs/inc/OCS_netdb.h @@ -27,17 +27,39 @@ #define OCS_NETDB_H #include "OCS_basetypes.h" +#include "OCS_sys_socket.h" /* ----------------------------------------- */ /* constants normally defined in netdb.h */ /* ----------------------------------------- */ +#define OCS_EAI_AGAIN 0x1a1a +#define OCS_EAI_NONAME 0x1a1b + /* ----------------------------------------- */ /* types normally defined in netdb.h */ /* ----------------------------------------- */ +struct OCS_addrinfo +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + OCS_socklen_t ai_addrlen; + struct OCS_sockaddr *ai_addr; + char * ai_canonname; + struct OCS_addrinfo *ai_next; +}; + /* ----------------------------------------- */ /* prototypes normally declared in netdb.h */ /* ----------------------------------------- */ +int OCS_getnameinfo(const struct OCS_sockaddr *addr, OCS_socklen_t addrlen, char *host, OCS_socklen_t hostlen, + char *serv, OCS_socklen_t servlen, int flags); + +int OCS_getaddrinfo(const char *node, const char *service, const struct OCS_addrinfo *hints, struct OCS_addrinfo **res); + +void OCS_freeaddrinfo(struct OCS_addrinfo *res); #endif /* OCS_NETDB_H */ diff --git a/src/unit-test-coverage/ut-stubs/override_inc/netdb.h b/src/unit-test-coverage/ut-stubs/override_inc/netdb.h index 5ce893fb9..837686e90 100644 --- a/src/unit-test-coverage/ut-stubs/override_inc/netdb.h +++ b/src/unit-test-coverage/ut-stubs/override_inc/netdb.h @@ -32,4 +32,12 @@ /* mappings for declarations in netdb.h */ /* ----------------------------------------- */ +#define EAI_AGAIN OCS_EAI_AGAIN +#define EAI_NONAME OCS_EAI_NONAME + +#define addrinfo OCS_addrinfo +#define getnameinfo OCS_getnameinfo +#define getaddrinfo OCS_getaddrinfo +#define freeaddrinfo OCS_freeaddrinfo + #endif /* OVERRIDE_NETDB_H */ diff --git a/src/unit-test-coverage/ut-stubs/src/posix-netdb-stubs.c b/src/unit-test-coverage/ut-stubs/src/posix-netdb-stubs.c new file mode 100644 index 000000000..28e711d2d --- /dev/null +++ b/src/unit-test-coverage/ut-stubs/src/posix-netdb-stubs.c @@ -0,0 +1,76 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 2020 United States Government as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ************************************************************************/ + +/* OSAL coverage stub replacement for netdb.h */ +#include +#include "utstubs.h" + +#include "OCS_netdb.h" + +/* ----------------------------------------- */ +/* prototypes normally declared in netdb.h */ +/* ----------------------------------------- */ +int OCS_getnameinfo(const struct OCS_sockaddr *addr, OCS_socklen_t addrlen, char *host, OCS_socklen_t hostlen, + char *serv, OCS_socklen_t servlen, int flags) +{ + int32 Status; + + Status = UT_DEFAULT_IMPL(OCS_getnameinfo); + + if (hostlen > 0) + { + memset(host, 0, hostlen); + UT_Stub_CopyToLocal(UT_KEY(OCS_getaddrinfo), host, hostlen - 1); + } + + if (servlen > 0) + { + memset(serv, 0, servlen); + } + + return Status; +} + +int OCS_getaddrinfo(const char *node, const char *service, const struct OCS_addrinfo *hints, struct OCS_addrinfo **res) +{ + static struct OCS_addrinfo DEFAULT_RESULT; + int32 Status; + + Status = UT_DEFAULT_IMPL(OCS_getaddrinfo); + + if (Status == 0) + { + /* this needs to output a value */ + if (UT_Stub_CopyToLocal(UT_KEY(OCS_getaddrinfo), res, sizeof(*res)) < sizeof(*res)) + { + memset(&DEFAULT_RESULT, 0, sizeof(DEFAULT_RESULT)); + *res = &DEFAULT_RESULT; + } + } + else + { + *res = NULL; + } + + return Status; +} + +void OCS_freeaddrinfo(struct OCS_addrinfo *res) +{ + UT_DEFAULT_IMPL(OCS_freeaddrinfo); +} diff --git a/src/unit-test-coverage/vxworks/CMakeLists.txt b/src/unit-test-coverage/vxworks/CMakeLists.txt index f81bd519b..1ad712e44 100644 --- a/src/unit-test-coverage/vxworks/CMakeLists.txt +++ b/src/unit-test-coverage/vxworks/CMakeLists.txt @@ -30,6 +30,8 @@ set(VXWORKS_PORTABLE_BLOCK_LIST console-bsp bsd-select bsd-sockets + bsd-sockets-dns + bsd-sockets-no-dns no-loader no-shell @@ -84,3 +86,9 @@ endforeach(MODNAME ${VXWORKS_PORTABLE_BLOCK_LIST}) # Custom flags for specific tests to be able to cover all code set_property(SOURCE ${OSAL_SOURCE_DIR}/src/os/portable/os-impl-bsd-sockets.c APPEND PROPERTY COMPILE_DEFINITIONS OS_NETWORK_SUPPORTS_IPV6) + +set_property(SOURCE ${OSAL_SOURCE_DIR}/src/os/portable/os-impl-bsd-sockets-no-dns.c + APPEND PROPERTY COMPILE_DEFINITIONS OS_NETWORK_SUPPORTS_IPV6) + +set_property(SOURCE ${OSAL_SOURCE_DIR}/src/os/portable/os-impl-bsd-sockets-dns.c + APPEND PROPERTY COMPILE_DEFINITIONS OS_NETWORK_SUPPORTS_IPV6) From 754bb0761ed5aedd53414ef8599cec11a65c3020 Mon Sep 17 00:00:00 2001 From: arielswalker <166176736+arielswalker@users.noreply.github.com> Date: Tue, 20 Jan 2026 14:19:44 -0600 Subject: [PATCH 51/51] Test Draco standalone-build.yml --- .github/workflows/standalone-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/standalone-build.yml b/.github/workflows/standalone-build.yml index 534be4091..057ecb4ed 100644 --- a/.github/workflows/standalone-build.yml +++ b/.github/workflows/standalone-build.yml @@ -10,7 +10,7 @@ defaults: env: allowed_ncov_lines: 0 - allowed_ncov_branches: 2 + allowed_ncov_branches: 0 allowed_ncov_functions: 0 jobs: