This is an automated email from the ASF dual-hosted git repository. michallenc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 69112fdb9e1a051b4072f298998f28d4154d96de Author: Marco Casaroli <[email protected]> AuthorDate: Sun Oct 11 10:46:29 2026 +0200 libs/libc/stdio: Close the descriptor in fclose() of a standard stream. fclose() of stdin, stdout or stderr flushed the stream and returned, so the file descriptor stayed open. POSIX says that fclose() closes the file descriptor of any stream. A program that sends its output through a pipe and ends it with fclose(stdout) never closed the write end: the reader waited for the end of file forever. Close the file descriptor of the builtin streams as for any other stream. The FILE structures stay in the stream list and are not freed, and they keep -1 as the file descriptor, so a later use of the stream fails and does not reach a new file with the same descriptor. freopen() of the stream still works. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- libs/libc/stdio/lib_fclose.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libs/libc/stdio/lib_fclose.c b/libs/libc/stdio/lib_fclose.c index 89e18631895..e36a658497a 100644 --- a/libs/libc/stdio/lib_fclose.c +++ b/libs/libc/stdio/lib_fclose.c @@ -108,17 +108,17 @@ int fclose(FAR FILE *stream) errcode = get_errno(); } - /* Skip close the builtin streams(stdin, stdout and stderr) */ + /* The builtin streams (stdin, stdout and stderr) stay in the stream + * list and are not freed, but their file descriptor is closed as for + * any other stream. + */ - if (stdstream) + if (!stdstream) { - nxmutex_unlock(&slist->sl_lock); - goto done; - } - - /* Remove FILE structure from the stream list */ + /* Remove FILE structure from the stream list */ - sq_rem(&stream->fs_entry, &slist->sl_queue); + sq_rem(&stream->fs_entry, &slist->sl_queue); + } nxmutex_unlock(&slist->sl_lock); @@ -152,6 +152,16 @@ int fclose(FAR FILE *stream) errcode = get_errno(); } + if (stdstream) + { + /* A later use of the stream fails, and does not reach a file + * that gets the same descriptor. + */ + + stream->fs_cookie = (FAR void *)(intptr_t)-1; + goto done; + } + #ifndef CONFIG_STDIO_DISABLE_BUFFERING /* Destroy the mutex */
