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 09a692bd401a4066e5fd90851dceaf373d698352
Author: Marco Casaroli <[email protected]>
AuthorDate: Thu Oct 22 01:54:02 2026 +0200

    fs: Create the directories /dev/shm and /dev/pts at boot.
    
    The pseudo file system had no directory of the shared memory objects
    (CONFIG_FS_SHMFS_VFS_PATH) until the first shm_open() created one, and no
    /dev/pts until the first pseudo-terminal was opened.  Programs expect both
    directories: a program that lists them, or checks that it can create a
    file there, fails.  User code cannot create them: with a file system
    mounted at "/", mkdir() creates the directory in that file system, not in
    the pseudo file system.
    
    Add register_pseudodir(), which creates an empty directory in the pseudo
    file system.  fs_initialize() creates the directory of the shared memory
    objects (mode 1777) with it, and ptmx_register() creates /dev/pts (mode
    0755).
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 drivers/serial/ptmx.c                             | 12 ++++
 fs/driver/CMakeLists.txt                          |  2 +-
 fs/driver/Make.defs                               |  2 +-
 fs/{shm/shmfs.h => driver/fs_registerpseudodir.c} | 73 ++++++++++++-----------
 fs/fs_initialize.c                                |  7 +++
 fs/shm/shmfs.c                                    | 28 +++++++++
 fs/shm/shmfs.h                                    | 10 ++++
 include/nuttx/fs/fs.h                             | 19 ++++++
 8 files changed, 117 insertions(+), 36 deletions(-)

diff --git a/drivers/serial/ptmx.c b/drivers/serial/ptmx.c
index 9161657aad2..fd9a1f5ad49 100644
--- a/drivers/serial/ptmx.c
+++ b/drivers/serial/ptmx.c
@@ -265,6 +265,18 @@ static ssize_t ptmx_write(FAR struct file *filep,
 
 int ptmx_register(void)
 {
+  int ret;
+
+  /* The slave devices are /dev/pts/N: create the directory now, so that it
+   * exists before the first pseudo-terminal does.
+   */
+
+  ret = register_pseudodir("/dev/pts", 0755);
+  if (ret < 0 && ret != -EEXIST)
+    {
+      return ret;
+    }
+
   /* Register the PTMX driver */
 
   return register_driver("/dev/ptmx", &g_ptmx_fops, 0600, NULL);
diff --git a/fs/driver/CMakeLists.txt b/fs/driver/CMakeLists.txt
index 61debb9c780..5d3230c556d 100644
--- a/fs/driver/CMakeLists.txt
+++ b/fs/driver/CMakeLists.txt
@@ -21,7 +21,7 @@
 # 
##############################################################################
 
 set(SRCS fs_registerdriver.c fs_unregisterdriver.c fs_registerpipedriver.c
-         fs_unregisterpipedriver.c)
+         fs_unregisterpipedriver.c fs_registerpseudodir.c)
 
 # Don't built-in block driver support if there are no mountpoints
 
diff --git a/fs/driver/Make.defs b/fs/driver/Make.defs
index e7df3c9d402..1085fa97202 100644
--- a/fs/driver/Make.defs
+++ b/fs/driver/Make.defs
@@ -20,7 +20,7 @@
 #
 ############################################################################
 
-CSRCS += fs_registerdriver.c fs_unregisterdriver.c
+CSRCS += fs_registerdriver.c fs_unregisterdriver.c fs_registerpseudodir.c
 CSRCS += fs_registerpipedriver.c fs_unregisterpipedriver.c
 
 # Don't built-in block driver support if there are no mountpoints
diff --git a/fs/shm/shmfs.h b/fs/driver/fs_registerpseudodir.c
similarity index 61%
copy from fs/shm/shmfs.h
copy to fs/driver/fs_registerpseudodir.c
index ce4f0820dca..69d9d6c0e0f 100644
--- a/fs/shm/shmfs.h
+++ b/fs/driver/fs_registerpseudodir.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * fs/shm/shmfs.h
+ * fs/driver/fs_registerpseudodir.c
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -20,53 +20,58 @@
  *
  ****************************************************************************/
 
-#ifndef __FS_SHM_SHMFS_H
-#define __FS_SHM_SHMFS_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <errno.h>
+
 #include <nuttx/fs/fs.h>
 
+#include "inode/inode.h"
+#include "vfs/vfs.h"
+
 /****************************************************************************
- * Public Data
+ * Public Functions
  ****************************************************************************/
 
-extern const struct file_operations g_shmfs_operations;
-
 /****************************************************************************
- * Public Types
+ * Name: register_pseudodir
+ *
+ * Description:
+ *   Create an empty directory in the pseudo file system, for a driver or a
+ *   file system that creates its nodes below it later (e.g. /dev/pts/N).
+ *
+ * Input Parameters:
+ *   path - The path of the directory
+ *   mode - The permissions of the directory
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure, e.g. -EEXIST if
+ *   'path' exists already.
+ *
  ****************************************************************************/
 
-struct shmfs_object_s
+int register_pseudodir(FAR const char *path, mode_t mode)
 {
-  /* Total number of bytes needed from physical memory. */
+  FAR struct inode *node;
+  int               ret;
 
-  size_t length;
+  /* An inode with no operations is a pseudo directory */
 
-  /* Vector of allocations from physical memory.
-   *
-   * - In flat and protected builds this is a pointer to the
-   *   allocated memory.
-   *
-   * - In kernel build this is start of a malloc'd vector of void pointers
-   *   and the length of the vector is MM_NPAGES(length).
-   */
-
-  FAR void *paddr;
-
-  /* The struct continues here as malloc'd array of void pointers
-   * if CONFIG_BUILD_KERNEL
-   */
-};
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-FAR struct shmfs_object_s *shmfs_alloc_object(size_t length);
-
-void shmfs_free_object(FAR struct shmfs_object_s *object);
+  inode_lock();
+  ret = inode_reserve(path, mode, &node);
+  inode_unlock();
 
+#ifdef CONFIG_FS_NOTIFY
+  if (ret >= 0)
+    {
+      notify_mkdir(path);
+    }
 #endif
+
+  return ret;
+}
diff --git a/fs/fs_initialize.c b/fs/fs_initialize.c
index a95f4ac31d0..3a808627a9f 100644
--- a/fs/fs_initialize.c
+++ b/fs/fs_initialize.c
@@ -33,6 +33,7 @@
 #include "aio/aio.h"
 #include "vfs/vfs.h"
 #include "fs_heap.h"
+#include "shm/shmfs.h"
 
 /****************************************************************************
  * Private Functions
@@ -106,6 +107,12 @@ void fs_initialize(void)
   notify_initialize();
 #endif
 
+#ifdef CONFIG_FS_SHMFS
+  /* The directory of the shared memory objects */
+
+  shmfs_initialize();
+#endif
+
   register_reboot_notifier(&g_sync_nb);
   fs_trace_end();
 }
diff --git a/fs/shm/shmfs.c b/fs/shm/shmfs.c
index 63aacbff1b4..bd7749a0a5b 100644
--- a/fs/shm/shmfs.c
+++ b/fs/shm/shmfs.c
@@ -25,6 +25,8 @@
  ****************************************************************************/
 
 #include <assert.h>
+#include <debug.h>
+#include <errno.h>
 #include <stdbool.h>
 #include <string.h>
 #include <sys/param.h>
@@ -509,3 +511,29 @@ static int shmfs_munmap(FAR struct task_group_s *group,
 
   return ret;
 }
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: shmfs_initialize
+ *
+ * Description:
+ *   Create the directory of the shared memory objects
+ *   (CONFIG_FS_SHMFS_VFS_PATH) at boot, so that it exists before the first
+ *   object does.  Anyone can create an object in it (mode 1777).
+ *
+ ****************************************************************************/
+
+void shmfs_initialize(void)
+{
+  int ret;
+
+  ret = register_pseudodir(CONFIG_FS_SHMFS_VFS_PATH, 01777);
+  if (ret < 0 && ret != -EEXIST)
+    {
+      ferr("ERROR: Failed to create %s: %d\n", CONFIG_FS_SHMFS_VFS_PATH,
+           ret);
+    }
+}
diff --git a/fs/shm/shmfs.h b/fs/shm/shmfs.h
index ce4f0820dca..b13b3fa85ff 100644
--- a/fs/shm/shmfs.h
+++ b/fs/shm/shmfs.h
@@ -69,4 +69,14 @@ FAR struct shmfs_object_s *shmfs_alloc_object(size_t length);
 
 void shmfs_free_object(FAR struct shmfs_object_s *object);
 
+/****************************************************************************
+ * Name: shmfs_initialize
+ *
+ * Description:
+ *   Create the directory of the shared memory objects at boot.
+ *
+ ****************************************************************************/
+
+void shmfs_initialize(void);
+
 #endif
diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h
index d115cf4604c..bcd438ece95 100644
--- a/include/nuttx/fs/fs.h
+++ b/include/nuttx/fs/fs.h
@@ -588,6 +588,25 @@ int register_driver(FAR const char *path,
                     FAR const struct file_operations *fops, mode_t mode,
                     FAR void *priv);
 
+/****************************************************************************
+ * Name: register_pseudodir
+ *
+ * Description:
+ *   Create an empty directory in the pseudo file system, for a driver or a
+ *   file system that creates its nodes below it later.
+ *
+ * Input Parameters:
+ *   path - The path of the directory
+ *   mode - The permissions of the directory
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure, e.g. -EEXIST if
+ *   'path' exists already.
+ *
+ ****************************************************************************/
+
+int register_pseudodir(FAR const char *path, mode_t mode);
+
 /****************************************************************************
  * Name: register_driver_with_size
  *

Reply via email to