From 6b86b9fd13def788eb57a5e990cfb1656b6d8225 Mon Sep 17 00:00:00 2001 From: Aaron Nyholm Date: Tue, 14 Oct 2025 13:06:31 +1100 Subject: [PATCH] cpukit/close.c: Open flag corrected for busy closes Fix closing while busy. Previously open flag in the iop would be unset despite close returning EBUSY. Updates #5311 --- cpukit/libcsupport/src/close.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cpukit/libcsupport/src/close.c b/cpukit/libcsupport/src/close.c index 968f1471ce..a566fb3fb7 100644 --- a/cpukit/libcsupport/src/close.c +++ b/cpukit/libcsupport/src/close.c @@ -45,7 +45,6 @@ int close( ) { rtems_libio_t *iop; - unsigned int flags; int rc; if ( (uint32_t) fd >= rtems_libio_number_iops ) { @@ -53,17 +52,28 @@ int close( } LIBIO_GET_IOP( fd, iop ); - flags = rtems_libio_iop_flags( iop ); while ( true ) { + unsigned int flags; unsigned int desired; bool success; + flags = rtems_libio_iop_flags( iop ); if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) { rtems_libio_iop_drop( iop ); rtems_set_errno_and_return_minus_one( EBADF ); } + /** + * When LIBIO_FLAGS_CLOSE_BUSY is not set check that only one reference + * is held to prevent closing while busy. Otherwise atomically check that + * the flags match to ensure the reference count is maintained. + */ + if ( ( flags & LIBIO_FLAGS_CLOSE_BUSY ) == 0 ) { + flags &= LIBIO_FLAGS_FLAGS_MASK; + flags |= LIBIO_FLAGS_REFERENCE_INC; + } + desired = flags & ~LIBIO_FLAGS_OPEN; success = _Atomic_Compare_exchange_uint( &iop->flags,