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
This commit is contained in:
Aaron Nyholm
2025-10-14 13:06:31 +11:00
parent 523b97ed40
commit 62bbd05a31

View File

@@ -45,7 +45,6 @@ int close(
) )
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
unsigned int flags;
int rc; int rc;
if ( (uint32_t) fd >= rtems_libio_number_iops ) { if ( (uint32_t) fd >= rtems_libio_number_iops ) {
@@ -53,17 +52,28 @@ int close(
} }
LIBIO_GET_IOP( fd, iop ); LIBIO_GET_IOP( fd, iop );
flags = rtems_libio_iop_flags( iop );
while ( true ) { while ( true ) {
unsigned int flags;
unsigned int desired; unsigned int desired;
bool success; bool success;
flags = rtems_libio_iop_flags( iop );
if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) { if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) {
rtems_libio_iop_drop( iop ); rtems_libio_iop_drop( iop );
rtems_set_errno_and_return_minus_one( EBADF ); 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; desired = flags & ~LIBIO_FLAGS_OPEN;
success = _Atomic_Compare_exchange_uint( success = _Atomic_Compare_exchange_uint(
&iop->flags, &iop->flags,