diff --git a/cpukit/include/rtems/libio_.h b/cpukit/include/rtems/libio_.h index eb487934bc..cc72fb4074 100644 --- a/cpukit/include/rtems/libio_.h +++ b/cpukit/include/rtems/libio_.h @@ -94,7 +94,7 @@ extern rtems_filesystem_mount_table_entry_t rtems_filesystem_null_mt_entry; * The purpose of this location is to deliver the error return status for a * previous error condition which must set the errno accordingly. * - * The usage of this null location instead of the NULL pointer eliminates + * The usage of this null location instead of the NULL pointer eliminates * a lot of branches. * * The user environment root and current directory are statically initialized @@ -463,6 +463,11 @@ void rtems_libio_free( rtems_libio_t *iop ); +/** + * Return the number of open iop descriptors + */ +int rtems_libio_count_open_iops( void ); + /* * File System Routine Prototypes */ diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c index 6a0fb31e71..9cef2a6fb6 100644 --- a/cpukit/libcsupport/src/libio.c +++ b/cpukit/libcsupport/src/libio.c @@ -176,3 +176,21 @@ void rtems_libio_free( rtems_libio_unlock(); } + +int rtems_libio_count_open_iops( + void +) +{ + int open = 0; + int i; + /* + * No locking needed to count the open iops + */ + for (i = 0; i < rtems_libio_number_iops; ++i) { + const rtems_libio_t *iop = &rtems_libio_iops[ i ]; + if (( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_OPEN ) != 0 ) { + ++open; + } + } + return open; +} diff --git a/spec/build/testsuites/libtests/grp.yml b/spec/build/testsuites/libtests/grp.yml index c63d845983..b4caf657b0 100644 --- a/spec/build/testsuites/libtests/grp.yml +++ b/spec/build/testsuites/libtests/grp.yml @@ -170,6 +170,8 @@ links: uid: kill - role: build-dependency uid: libfdt01 +- role: build-dependency + uid: libiofdopen - role: build-dependency uid: longjmp - role: build-dependency diff --git a/testsuites/libtests/libiofdopen/init.c b/testsuites/libtests/libiofdopen/init.c new file mode 100644 index 0000000000..07a947b5af --- /dev/null +++ b/testsuites/libtests/libiofdopen/init.c @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (c) 2024 Contemporary Software, Chris Johns + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tmacros.h" + +#include +#include +#include + +#include + +/* Use assert() not rtems_test_assert() since it uses exit() */ +#include + +#include + +const char rtems_test_name[] = "LIBIO FD OPEN"; + +#define NUMOF(_a) (sizeof(_a) / sizeof(_a[0])) + +static void Init(rtems_task_argument arg) +{ + int fd[10]; + int i; + int base_count; + + TEST_BEGIN(); + + for (i = 0; i < NUMOF(fd); i++) { + fd[i] = -1; + } + + base_count = rtems_libio_count_open_iops(); + + fd[0] = open("/x123", O_WRONLY | O_TRUNC | O_CREAT, 0x777); + rtems_test_assert(fd[0] != -1); + rtems_test_assert(rtems_libio_count_open_iops() == 3 + 1); + rtems_test_assert(write(fd[0], "0123456789\n", 11) == 11); + rtems_test_assert(close(fd[0]) == 0); + + for (i = 0; i < 5; ++i) { + fd[i] = open("/x123", O_RDONLY); + rtems_test_assert(fd[i] >= 0); + rtems_test_assert(rtems_libio_count_open_iops() == base_count + i + 1); + } + + for (i = 5; i < 10; ++i) { + fd[i] = open("/x123", O_RDONLY); + rtems_test_assert(fd[i] >= 0); + rtems_test_assert(rtems_libio_count_open_iops() == base_count + i + 1); + } + + for (i = 0; i < 10; ++i) { + rtems_test_assert(close(fd[i]) == 0); + } + + TEST_END(); +} + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER + +#define CONFIGURE_USE_MINIIMFS_AS_BASE_FILESYSTEM +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 13 + +#define CONFIGURE_MAXIMUM_TASKS 1 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/libtests/libiofdopen/libiofdopen.doc b/testsuites/libtests/libiofdopen/libiofdopen.doc new file mode 100644 index 0000000000..cb095efb5b --- /dev/null +++ b/testsuites/libtests/libiofdopen/libiofdopen.doc @@ -0,0 +1,11 @@ +This file describes the directives and concepts tested by this test set. + +test set name: libiofdopen + +directives: + + rtems_libio_count_open_iops() + +concepts: + + Check the number of open files diff --git a/testsuites/libtests/libiofdopen/libiofdopen.scn b/testsuites/libtests/libiofdopen/libiofdopen.scn new file mode 100644 index 0000000000..612e79e32d --- /dev/null +++ b/testsuites/libtests/libiofdopen/libiofdopen.scn @@ -0,0 +1,7 @@ +*** BEGIN OF TEST LIBIO FD OPEN *** +*** TEST VERSION: 6.0.0.2089f993c0d01126f6766f4d323be4b9a1b54c60 +*** TEST STATE: EXPECTED_PASS +*** TEST BUILD: RTEMS_DEBUG RTEMS_POSIX_API +*** TEST TOOLS: 13.3.0 20240521 (RTEMS 6, RSB 0c685d82082ab6d821b5a4da89b2d904ea7a705c, Newlib 1ed1516) + +*** END OF TEST LIBIO FD OPEN ***