From abba7dd7da953990568f0d5eaa83701de30d0c8f Mon Sep 17 00:00:00 2001 From: Balazs Racz Date: Thu, 8 Oct 2020 13:49:04 +0200 Subject: [PATCH] Adds an intermediate stage in closing an fd. (#441) * Adds an intermediate stage in closing an fd. Adds a new bit to mark an fd being in shutdown. This is a state during close that marks the fd as being bad, with all kernel calls (from other threads) returning EBADF if they refer to this fd. At the same time the fd is not marked as free for reuse by another open. This fixes the race condition in https://github.com/bakerstu/openmrn/issues/440 * Fix bug when dev->close returns an error. --- src/freertos_drivers/common/Device.cxx | 2 ++ src/freertos_drivers/common/Devtab.hxx | 1 + src/freertos_drivers/common/Fileio.cxx | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/freertos_drivers/common/Device.cxx b/src/freertos_drivers/common/Device.cxx index 5530fdab9..8b0347945 100644 --- a/src/freertos_drivers/common/Device.cxx +++ b/src/freertos_drivers/common/Device.cxx @@ -144,9 +144,11 @@ int Device::close(struct _reent *reent, int fd) // stdin, stdout, and stderr never get closed return 0; } + files[fd].inshdn = true; int result = f->dev->close(f); if (result < 0) { + files[fd].inshdn = false; errno = -result; return -1; } diff --git a/src/freertos_drivers/common/Devtab.hxx b/src/freertos_drivers/common/Devtab.hxx index 76b062336..c807ed58f 100644 --- a/src/freertos_drivers/common/Devtab.hxx +++ b/src/freertos_drivers/common/Devtab.hxx @@ -62,6 +62,7 @@ struct File off_t offset; /**< current offset within file */ int flags; /**< open flags */ uint8_t inuse : 1; /**< true if this is an open fd. */ + uint8_t inshdn : 1; /**< true if this fd is in shutdown. */ uint8_t device : 1; /**< true if this is a device, false if file system */ uint8_t dir : 1; /**< true if this is a directory, else false */ uint8_t dirty : 1; /**< true if this file is dirty and needs flush */ diff --git a/src/freertos_drivers/common/Fileio.cxx b/src/freertos_drivers/common/Fileio.cxx index 2ebd83206..d6c64b692 100644 --- a/src/freertos_drivers/common/Fileio.cxx +++ b/src/freertos_drivers/common/Fileio.cxx @@ -51,6 +51,7 @@ int FileIO::fd_alloc(void) if (files[i].inuse == false) { files[i].inuse = true; + files[i].inshdn = false; files[i].device = true; files[i].dir = false; files[i].dirty = false; @@ -85,7 +86,7 @@ File* FileIO::file_lookup(int fd) errno = EBADF; return nullptr; } - if (files[fd].inuse == 0) + if (files[fd].inuse == 0 || files[fd].inshdn == 1) { errno = EBADF; return nullptr;