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;
 }

Reply via email to