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-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new ecfc1b5b6 nshlib: add chmod and chown builtins
ecfc1b5b6 is described below

commit ecfc1b5b61ad505aeb0f75a399ed2738d200c459
Author: Abhishek Mishra <[email protected]>
AuthorDate: Wed May 13 21:40:51 2026 +0000

    nshlib: add chmod and chown builtins
    
    Add minimal chmod/chown support to NSH using the
    existing libc/VFS syscall interfaces.
    
    Supported forms:
    
      - chmod <octal-mode> <path>
      - chown <uid>[:gid] <path>
    
    The chown implementation supports the numeric
    ownership forms already handled by the underlying
    NuttX chown() implementation, including unchanged
    uid/gid semantics via omitted fields.
    
    Only numeric permission modes and numeric uid/gid
    forms are supported in this initial implementation.
    
    This adds interactive filesystem permission and
    ownership management support to NSH and aligns the
    shell more closely with standard POSIX environments.
    
    Signed-off-by: Abhishek Mishra <[email protected]>
---
 nshlib/Kconfig       |  10 +++++
 nshlib/nsh.h         |   6 +++
 nshlib/nsh_command.c |   8 ++++
 nshlib/nsh_fscmds.c  | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+)

diff --git a/nshlib/Kconfig b/nshlib/Kconfig
index 1fc34cb21..2d1570b87 100644
--- a/nshlib/Kconfig
+++ b/nshlib/Kconfig
@@ -341,6 +341,16 @@ config NSH_DISABLE_CD
        bool "Disable cd"
        default DEFAULT_SMALL
 
+config NSH_DISABLE_CHMOD
+       bool "Disable chmod"
+       default DEFAULT_SMALL
+       depends on FS_PERMISSION
+
+config NSH_DISABLE_CHOWN
+       bool "Disable chown"
+       default DEFAULT_SMALL
+       depends on FS_PERMISSION
+
 config NSH_DISABLE_CP
        bool "Disable cp"
        default DEFAULT_SMALL
diff --git a/nshlib/nsh.h b/nshlib/nsh.h
index 2fb3cf867..7abb7c38f 100644
--- a/nshlib/nsh.h
+++ b/nshlib/nsh.h
@@ -963,6 +963,12 @@ int cmd_irqinfo(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv);
 #ifndef CONFIG_NSH_DISABLE_CAT
   int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
 #endif
+#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD)
+  int cmd_chmod(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
+#endif
+#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN)
+  int cmd_chown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
+#endif
 #ifndef CONFIG_NSH_DISABLE_CP
   int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
 #endif
diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c
index ec3f8a385..23534fbe5 100644
--- a/nshlib/nsh_command.c
+++ b/nshlib/nsh_command.c
@@ -168,6 +168,14 @@ static const struct cmdmap_s g_cmdmap[] =
   CMD_MAP("cd",       cmd_cd,       1, 2, "[<dir-path>|-|~|..]"),
 #endif
 
+#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD)
+  CMD_MAP("chmod",    cmd_chmod,    3, 3, "<octal-mode> <path>"),
+#endif
+
+#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN)
+  CMD_MAP("chown",    cmd_chown,    3, 3, "[<uid>][:<gid>] <path>"),
+#endif
+
 #ifndef CONFIG_NSH_DISABLE_CP
   CMD_MAP("cp",       cmd_cp,       3, 4, "[-r] <source-path> <dest-path>"),
 #endif
diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c
index a88c1a20d..13daa8258 100644
--- a/nshlib/nsh_fscmds.c
+++ b/nshlib/nsh_fscmds.c
@@ -843,6 +843,129 @@ int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, FAR 
char **argv)
 }
 #endif
 
+/****************************************************************************
+ * Name: cmd_chmod
+ *
+ * Description:
+ *   chmod <octal-mode> <path>
+ *
+ *   Only numeric (octal) modes are supported.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD)
+int cmd_chmod(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
+{
+  FAR char *fullpath;
+  FAR char *endptr;
+  long      mode;
+  int       ret = ERROR;
+
+  UNUSED(argc);
+
+  mode = strtol(argv[1], &endptr, 8);
+  if (endptr == argv[1] || *endptr != '\0' || mode < 0 || mode > 0777)
+    {
+      nsh_error(vtbl, g_fmtarginvalid, argv[0]);
+      return ERROR;
+    }
+
+  fullpath = nsh_getfullpath(vtbl, argv[2]);
+  if (fullpath != NULL)
+    {
+      ret = chmod(fullpath, (mode_t)mode);
+      if (ret < 0)
+        {
+          nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chmod", NSH_ERRNO);
+        }
+
+      nsh_freefullpath(fullpath);
+    }
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: cmd_chown
+ *
+ * Description:
+ *   chown <uid>[:<gid>] <path>
+ *   chown [<uid>]:<gid> <path>
+ *
+ *   Only numeric uid/gid forms are supported.  Empty uid or gid fields
+ *   leave that side unchanged.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHOWN)
+int cmd_chown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
+{
+  FAR const char *spec = argv[1];
+  FAR char       *endptr;
+  FAR char       *fullpath;
+  long            value;
+  uid_t           uid = (uid_t)-1;
+  gid_t           gid = (gid_t)-1;
+  int             ret = ERROR;
+
+  UNUSED(argc);
+
+  value = strtol(spec, &endptr, 10);
+  if (endptr != spec)
+    {
+      if (value < 0)
+        {
+          nsh_error(vtbl, g_fmtarginvalid, argv[0]);
+          return ERROR;
+        }
+
+      uid = (uid_t)value;
+    }
+
+  if (*endptr == ':')
+    {
+      FAR const char *gidstr = endptr + 1;
+      if (*gidstr != '\0')
+        {
+          value = strtol(gidstr, &endptr, 10);
+          if (*endptr != '\0' || value < 0)
+            {
+              nsh_error(vtbl, g_fmtarginvalid, argv[0]);
+              return ERROR;
+            }
+
+          gid = (gid_t)value;
+        }
+    }
+  else if (*endptr != '\0')
+    {
+      nsh_error(vtbl, g_fmtarginvalid, argv[0]);
+      return ERROR;
+    }
+
+  if (uid == (uid_t)-1 && gid == (gid_t)-1)
+    {
+      nsh_error(vtbl, g_fmtarginvalid, argv[0]);
+      return ERROR;
+    }
+
+  fullpath = nsh_getfullpath(vtbl, argv[2]);
+  if (fullpath != NULL)
+    {
+      ret = lchown(fullpath, uid, gid);
+      if (ret < 0)
+        {
+          nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chown", NSH_ERRNO);
+        }
+
+      nsh_freefullpath(fullpath);
+    }
+
+  return ret;
+}
+#endif
+
 /****************************************************************************
  * Name: cmd_dmesg
  ****************************************************************************/

Reply via email to