This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit f731eaf729613328cee1996e332ecc37f1c17edf Author: Marco Casaroli <[email protected]> AuthorDate: Mon Oct 19 01:49:35 2026 +0200 libc/stdio: Let remove() remove a directory after unlink() fails with EPERM. remove() calls unlink() first, and calls rmdir() only when unlink() fails with EISDIR. POSIX also lets unlink() of a directory fail with EPERM, and v9fs on a macOS host does that. Then remove() of an empty directory failed. Also call rmdir() after EPERM. If rmdir() then fails with ENOTDIR, the path is not a directory: keep the errno of unlink(). Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- libs/libc/stdio/lib_remove.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/libs/libc/stdio/lib_remove.c b/libs/libc/stdio/lib_remove.c index f5947124dbe..60f1de5f335 100644 --- a/libs/libc/stdio/lib_remove.c +++ b/libs/libc/stdio/lib_remove.c @@ -54,16 +54,34 @@ int remove(FAR const char *path) { - /* First try to unlink since this is - * more frequently the necessary action. - */ + int errcode; - if (unlink(path) != 0 && (get_errno() != EISDIR || rmdir(path) != 0)) + if (unlink(path) == 0) { - /* Cannot remove the object for whatever reason. */ + return 0; + } + + /* unlink() of a directory fails with EISDIR, or with EPERM (POSIX + * allows both). Then try rmdir(). + */ + errcode = get_errno(); + if (errcode != EISDIR && errcode != EPERM) + { return -1; } - return 0; + if (rmdir(path) == 0) + { + return 0; + } + + /* Not a directory: keep the error of unlink() */ + + if (get_errno() == ENOTDIR) + { + set_errno(errcode); + } + + return -1; }
