You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by da...@apache.org on 2021/07/01 21:55:10 UTC

[incubator-nuttx-apps] branch master updated: nshlib: Add 'rm -r' recursive remove directory support

This is an automated email from the ASF dual-hosted git repository.

davids5 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new 4b8e0fd  nshlib: Add 'rm -r' recursive remove directory support
4b8e0fd is described below

commit 4b8e0fde62112510c2753c638496be9a621e3e13
Author: liuhaitao <li...@xiaomi.com>
AuthorDate: Fri Apr 23 14:31:23 2021 +0800

    nshlib: Add 'rm -r' recursive remove directory support
    
    Change-Id: Iafecb0a25cc9d091a1aee8f381b217e67d6e3925
    Signed-off-by: liuhaitao <li...@xiaomi.com>
---
 nshlib/nsh_command.c |  2 +-
 nshlib/nsh_fscmds.c  | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c
index 9622b39..ddee35f 100644
--- a/nshlib/nsh_command.c
+++ b/nshlib/nsh_command.c
@@ -435,7 +435,7 @@ static const struct cmdmap_s g_cmdmap[] =
 
 #ifdef NSH_HAVE_DIROPTS
 # ifndef CONFIG_NSH_DISABLE_RM
-  { "rm",       cmd_rm,       2, 2, "<file-path>" },
+  { "rm",       cmd_rm,       2, 3, "[-r] <file-path>" },
 # endif
 #endif
 
diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c
index 4b571d8..a52be80 100644
--- a/nshlib/nsh_fscmds.c
+++ b/nshlib/nsh_fscmds.c
@@ -1640,14 +1640,83 @@ int cmd_readlink(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 
 #ifdef NSH_HAVE_DIROPTS
 #ifndef CONFIG_NSH_DISABLE_RM
+
+static int unlink_recursive(FAR char *path)
+{
+  struct dirent *d;
+  struct stat stat;
+  size_t len;
+  int ret;
+  DIR *dp;
+
+  ret = lstat(path, &stat);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  if (!S_ISDIR(stat.st_mode))
+    {
+      return unlink(path);
+    }
+
+  dp = opendir(path);
+  if (dp == NULL)
+    {
+      return -1;
+    }
+
+  len = strlen(path);
+  if (len > 0 && path[len - 1] == '/')
+    {
+      path[--len] = '\0';
+    }
+
+  while ((d = readdir(dp)) != NULL)
+    {
+      if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
+        {
+          continue;
+        }
+
+      snprintf(&path[len], PATH_MAX - len, "/%s", d->d_name);
+      ret = unlink_recursive(path);
+      if (ret < 0)
+        {
+          closedir(dp);
+          return ret;
+        }
+    }
+
+  ret = closedir(dp);
+  if (ret >= 0)
+    {
+      path[len] = '\0';
+      ret = rmdir(path);
+    }
+
+  return ret;
+}
+
 int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 {
-  FAR char *fullpath = nsh_getfullpath(vtbl, argv[1]);
+  bool recursive = (strcmp(argv[1], "-r") == 0);
+  FAR char *fullpath = nsh_getfullpath(vtbl, recursive ? argv[2] : argv[1]);
+  char buf[PATH_MAX];
   int ret = ERROR;
 
   if (fullpath != NULL)
     {
-      ret = unlink(fullpath);
+      if (recursive)
+        {
+          strlcpy(buf, fullpath, PATH_MAX);
+          ret = unlink_recursive(buf);
+        }
+      else
+        {
+          ret = unlink(fullpath);
+        }
+
       if (ret < 0)
         {
           nsh_error(vtbl, g_fmtcmdfailed, argv[0], "unlink", NSH_ERRNO);