[PATCH v2 1/1] newlib01: Check exit procs for global FILE obj
Matthew Joyce
matthew.joyce at embedded-brains.de
Mon Mar 28 09:04:27 UTC 2022
From: Matt Joyce <matthew.joyce at embedded-brains.de>
---
testsuites/libtests/newlib01/init.c | 110 ++++++++++++++++++++++------
1 file changed, 88 insertions(+), 22 deletions(-)
diff --git a/testsuites/libtests/newlib01/init.c b/testsuites/libtests/newlib01/init.c
index c58154023b..bba187e8e2 100644
--- a/testsuites/libtests/newlib01/init.c
+++ b/testsuites/libtests/newlib01/init.c
@@ -28,6 +28,8 @@ const char rtems_test_name[] = "NEWLIB 1";
static const char file_path[] = "/file";
+static const char file_path2[] = "/file2";
+
typedef enum {
INIT,
OPEN,
@@ -39,6 +41,8 @@ typedef struct {
rtems_id main_task_id;
rtems_id worker_task_id;
test_state current;
+ FILE *glob_file_stream;
+ int glob_fd;
} test_context;
static test_context test_instance;
@@ -59,7 +63,7 @@ static void wait(void)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
-static void worker_task(rtems_task_argument arg)
+static void thread_specific_worker(rtems_task_argument arg)
{
test_context *ctx = &test_instance;
struct _reent *reent = _REENT;
@@ -90,6 +94,30 @@ static void worker_task(rtems_task_argument arg)
rtems_test_assert(0);
}
+static void global_file_object_worker(rtems_task_argument arg)
+{
+ test_context *ctx = &test_instance;
+ FILE *fp;
+ char buf[1] = { 'y' };
+ size_t n;
+ int fd;
+
+ fp = ctx->glob_file_stream = fopen(&file_path2[0], "w");
+ rtems_test_assert(fp != NULL);
+
+ /* Get file descriptor of new global file stream, store it in text context */
+ fd = fileno(fp);
+ rtems_test_assert(fd != -1);
+ ctx->glob_fd = fd;
+
+ n = fwrite(&buf[0], sizeof(buf), 1, fp);
+ rtems_test_assert(n == 1);
+
+ wake_up_main(ctx);
+
+ rtems_test_assert(0);
+}
+
static int handler_open(
rtems_libio_t *iop,
const char *path,
@@ -250,9 +278,34 @@ static const IMFS_node_control node_control = IMFS_GENERIC_INITIALIZER(
IMFS_node_destroy_default
);
-static void test_thread_specific_close(test_context *ctx)
+static void task_create_and_delete_helper(
+ test_context *ctx,
+ rtems_task_entry entry
+)
{
rtems_status_code sc;
+
+ sc = rtems_task_create(
+ rtems_build_name('W', 'O', 'R', 'K'),
+ 2,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->worker_task_id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(ctx->worker_task_id, entry, 0);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ wait();
+
+ sc = rtems_task_delete(ctx->worker_task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_thread_specific_close(test_context *ctx)
+{
int rv;
rtems_resource_snapshot snapshot;
@@ -266,23 +319,7 @@ static void test_thread_specific_close(test_context *ctx)
);
rtems_test_assert(rv == 0);
- sc = rtems_task_create(
- rtems_build_name('W', 'O', 'R', 'K'),
- 2,
- RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_DEFAULT_MODES,
- RTEMS_DEFAULT_ATTRIBUTES,
- &ctx->worker_task_id
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_start(ctx->worker_task_id, worker_task, 0);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- wait();
-
- sc = rtems_task_delete(ctx->worker_task_id);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ task_create_and_delete_helper(ctx, thread_specific_worker);
rv = unlink(&file_path[0]);
rtems_test_assert(rv == 0);
@@ -290,6 +327,11 @@ static void test_thread_specific_close(test_context *ctx)
rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
}
+static void test_global_file_object_close(test_context *ctx)
+{
+ task_create_and_delete_helper(ctx, global_file_object_worker);
+}
+
/*
* This exit handler will be called last among the functions registered with
* atexit(). Check that stdio file descriptors are closed. The Newlib cleanup
@@ -298,6 +340,7 @@ static void test_thread_specific_close(test_context *ctx)
*/
static void check_after_libio_exit(void)
{
+ test_context *ctx = &test_instance;
struct stat unused;
int rv;
@@ -319,6 +362,11 @@ static void check_after_libio_exit(void)
rtems_test_assert(stdin->_flags != 0);
rtems_test_assert(stdout->_flags != 0);
rtems_test_assert(stderr->_flags != 0);
+
+ /* Global file tests. Global fd still open at this point. */
+ rv = fstat(ctx->glob_fd, &unused);
+ rtems_test_assert(rv == 0);
+ rtems_test_assert(ctx->glob_file_stream->_flags != 0);
}
static void register_exit_handler_before_libio_exit(void)
@@ -342,7 +390,7 @@ RTEMS_SYSINIT_ITEM(register_exit_handler_before_libio_exit,
* cleanup procedures have been called. Therefore, stdio file descriptors
* should be open and stdio FILE object flags should be non-zero.
*/
-static void test_exit_handling(void)
+static void test_exit_handling(test_context *ctx)
{
struct stat unused;
int rv;
@@ -360,6 +408,14 @@ static void test_exit_handling(void)
rtems_test_assert(stdout->_flags != 0);
rtems_test_assert(stderr->_flags != 0);
+ /*
+ * Global file descriptor should still be open; global FILE object flags
+ * should still be non-zero.
+ */
+ rv = fstat(ctx->glob_fd, &unused);
+ rtems_test_assert(rv == 0);
+ rtems_test_assert(ctx->glob_file_stream->_flags != 0);
+
/* Run exit handlers and Newlib cleanup procedures */
exit(0);
}
@@ -380,7 +436,8 @@ static void Init(rtems_task_argument arg)
rtems_test_assert(rv == 0);
test_thread_specific_close(ctx);
- test_exit_handling();
+ test_global_file_object_close(ctx);
+ test_exit_handling(ctx);
}
static void fatal_extension(
@@ -400,6 +457,7 @@ static void fatal_extension(
*/
struct stat unused;
int rv;
+ test_context *ctx = &test_instance;
errno = 0;
rv = fstat(0, &unused);
@@ -419,6 +477,14 @@ static void fatal_extension(
rtems_test_assert(stdin->_flags == 0);
rtems_test_assert(stdout->_flags == 0);
rtems_test_assert(stderr->_flags == 0);
+
+ /* Global file tests */
+ errno = 0;
+ rv = fstat(ctx->glob_fd, &unused);
+ rtems_test_assert(rv == -1);
+ rtems_test_assert(errno == EBADF);
+ rtems_test_assert(ctx->glob_file_stream->_flags == 0);
+
TEST_END();
}
}
@@ -426,7 +492,7 @@ static void fatal_extension(
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
-#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 5
#define CONFIGURE_MAXIMUM_TASKS 2
--
2.31.1
More information about the devel
mailing list