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


The following commit(s) were added to refs/heads/master by this push:
     new 816bb6fe0d6 libs/libc: Add <mntent.h> and getmntent().
816bb6fe0d6 is described below

commit 816bb6fe0d671755f4e1c6368d7c1609d8ca4fd0
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Oct 9 13:42:36 2026 +0200

    libs/libc: Add <mntent.h> and getmntent().
    
    Add setmntent(), getmntent(), getmntent_r(), addmntent(), endmntent()
    and hasmntopt(), which programs use to list the mounted file systems.
    MOUNTED is /proc/fs/mount, the list that procfs keeps, and
    getmntent_r() reads its "<mount point> type <type>" lines as well as
    the usual fstab and mtab format.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 include/mntent.h              |  92 ++++++++++++++++
 libs/libc/misc/CMakeLists.txt |   3 +-
 libs/libc/misc/Make.defs      |   2 +-
 libs/libc/misc/lib_mntent.c   | 237 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 332 insertions(+), 2 deletions(-)

diff --git a/include/mntent.h b/include/mntent.h
new file mode 100644
index 00000000000..9738d80d4b2
--- /dev/null
+++ b/include/mntent.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * include/mntent.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_MNTENT_H
+#define __INCLUDE_MNTENT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdio.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* The table of mounted file systems.  NuttX lists them in procfs, one line
+ * per mount: "<mount point> type <file system type>".
+ */
+
+#define MOUNTED          "/proc/fs/mount"
+#define _PATH_MOUNTED    MOUNTED
+
+/* Generic mount options */
+
+#define MNTOPT_DEFAULTS  "defaults"
+#define MNTOPT_RO        "ro"
+#define MNTOPT_RW        "rw"
+#define MNTOPT_SUID      "suid"
+#define MNTOPT_NOSUID    "nosuid"
+#define MNTOPT_NOAUTO    "noauto"
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct mntent
+{
+  FAR char *mnt_fsname;  /* Mounted device or file system name */
+  FAR char *mnt_dir;     /* Mount point */
+  FAR char *mnt_type;    /* File system type */
+  FAR char *mnt_opts;    /* Comma-separated mount options */
+  int mnt_freq;          /* Dump frequency in days */
+  int mnt_passno;        /* Pass number for parallel fsck */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+FAR FILE *setmntent(FAR const char *filename, FAR const char *type);
+FAR struct mntent *getmntent(FAR FILE *stream);
+FAR struct mntent *getmntent_r(FAR FILE *stream, FAR struct mntent *mntbuf,
+                               FAR char *buf, int buflen);
+int addmntent(FAR FILE *stream, FAR const struct mntent *mnt);
+int endmntent(FAR FILE *stream);
+FAR char *hasmntopt(FAR const struct mntent *mnt, FAR const char *opt);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __INCLUDE_MNTENT_H */
diff --git a/libs/libc/misc/CMakeLists.txt b/libs/libc/misc/CMakeLists.txt
index 8820b1b2ebd..774710ad3f5 100644
--- a/libs/libc/misc/CMakeLists.txt
+++ b/libs/libc/misc/CMakeLists.txt
@@ -48,7 +48,8 @@ list(
   lib_mkdirat.c
   lib_utimensat.c
   lib_mallopt.c
-  lib_getnprocs.c)
+  lib_getnprocs.c
+  lib_mntent.c)
 
 if(CONFIG_LIBC_TEMPBUFFER)
   list(APPEND SRCS lib_tempbuffer.c)
diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs
index b9ad85bc614..c5fa595206e 100644
--- a/libs/libc/misc/Make.defs
+++ b/libs/libc/misc/Make.defs
@@ -27,7 +27,7 @@ CSRCS += lib_utsname.c lib_getrandom.c lib_xorshift128.c 
lib_tea_encrypt.c
 CSRCS += lib_tea_decrypt.c lib_cxx_initialize.c lib_impure.c lib_memfd.c
 CSRCS += lib_mutex.c lib_fchmodat.c lib_fstatat.c lib_getfullpath.c
 CSRCS += lib_openat.c lib_mkdirat.c lib_utimensat.c lib_mallopt.c
-CSRCS += lib_idr.c lib_getnprocs.c
+CSRCS += lib_idr.c lib_getnprocs.c lib_mntent.c
 
 ifeq ($(CONFIG_LIBC_TEMPBUFFER),y)
 CSRCS += lib_tempbuffer.c
diff --git a/libs/libc/misc/lib_mntent.c b/libs/libc/misc/lib_mntent.c
new file mode 100644
index 00000000000..6c683294804
--- /dev/null
+++ b/libs/libc/misc/lib_mntent.c
@@ -0,0 +1,237 @@
+/****************************************************************************
+ * libs/libc/misc/lib_mntent.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <limits.h>
+#include <mntent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Size of the line buffer that getmntent() uses */
+
+#define MNTENT_BUFSIZE (PATH_MAX + 64)
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct mntent g_mntent;
+static char g_mntbuf[MNTENT_BUFSIZE];
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: setmntent
+ *
+ * Description:
+ *   Open a file system description file, such as MOUNTED.
+ *
+ ****************************************************************************/
+
+FAR FILE *setmntent(FAR const char *filename, FAR const char *type)
+{
+  return fopen(filename, type);
+}
+
+/****************************************************************************
+ * Name: getmntent_r
+ *
+ * Description:
+ *   Read the next entry of a file system description file into mntbuf,
+ *   with its strings in buf.  Two line formats are accepted: the one of
+ *   MOUNTED ("<mount point> type <type>") and the one of fstab and mtab
+ *   ("<fsname> <dir> <type> [<options> [<freq> [<passno>]]]").  Blank
+ *   lines, comments and lines longer than buflen are skipped.
+ *
+ * Returned Value:
+ *   mntbuf, or NULL at the end of the file.
+ *
+ ****************************************************************************/
+
+FAR struct mntent *getmntent_r(FAR FILE *stream, FAR struct mntent *mntbuf,
+                               FAR char *buf, int buflen)
+{
+  FAR char *field[6];
+  FAR char *save;
+  FAR char *p;
+  size_t len;
+  int n;
+  int c;
+
+  while (fgets(buf, buflen, stream) != NULL)
+    {
+      len = strlen(buf);
+      if (len > 0 && buf[len - 1] != '\n' && !feof(stream))
+        {
+          /* The line does not fit: skip the rest of it */
+
+          while ((c = fgetc(stream)) != EOF && c != '\n')
+            {
+            }
+
+          continue;
+        }
+
+      n = 0;
+      for (p = strtok_r(buf, " \t\n", &save); p != NULL && n < 6;
+           p = strtok_r(NULL, " \t\n", &save))
+        {
+          field[n++] = p;
+        }
+
+      if (n < 3 || field[0][0] == '#')
+        {
+          continue;
+        }
+
+      if (n == 3 && strcmp(field[1], "type") == 0)
+        {
+          /* MOUNTED: "<mount point> type <type>".  The file system name is
+           * not known; use the type, as for a virtual file system.
+           */
+
+          mntbuf->mnt_fsname = field[2];
+          mntbuf->mnt_dir    = field[0];
+          mntbuf->mnt_type   = field[2];
+          mntbuf->mnt_opts   = (FAR char *)MNTOPT_RW;
+          mntbuf->mnt_freq   = 0;
+          mntbuf->mnt_passno = 0;
+        }
+      else
+        {
+          mntbuf->mnt_fsname = field[0];
+          mntbuf->mnt_dir    = field[1];
+          mntbuf->mnt_type   = field[2];
+          mntbuf->mnt_opts   = n > 3 ? field[3] :
+                               (FAR char *)MNTOPT_DEFAULTS;
+          mntbuf->mnt_freq   = n > 4 ? atoi(field[4]) : 0;
+          mntbuf->mnt_passno = n > 5 ? atoi(field[5]) : 0;
+        }
+
+      return mntbuf;
+    }
+
+  return NULL;
+}
+
+/****************************************************************************
+ * Name: getmntent
+ *
+ * Description:
+ *   As getmntent_r(), with a static entry and buffer.
+ *
+ ****************************************************************************/
+
+FAR struct mntent *getmntent(FAR FILE *stream)
+{
+  return getmntent_r(stream, &g_mntent, g_mntbuf, sizeof(g_mntbuf));
+}
+
+/****************************************************************************
+ * Name: addmntent
+ *
+ * Description:
+ *   Append an entry in the fstab and mtab format to the file.
+ *
+ * Returned Value:
+ *   0 on success, 1 on failure.
+ *
+ ****************************************************************************/
+
+int addmntent(FAR FILE *stream, FAR const struct mntent *mnt)
+{
+  if (fseek(stream, 0, SEEK_END) < 0)
+    {
+      return 1;
+    }
+
+  return fprintf(stream, "%s %s %s %s %d %d\n", mnt->mnt_fsname,
+                 mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,
+                 mnt->mnt_freq, mnt->mnt_passno) < 0 ? 1 : 0;
+}
+
+/****************************************************************************
+ * Name: endmntent
+ *
+ * Description:
+ *   Close a file opened with setmntent().
+ *
+ * Returned Value:
+ *   Always 1.
+ *
+ ****************************************************************************/
+
+int endmntent(FAR FILE *stream)
+{
+  if (stream != NULL)
+    {
+      fclose(stream);
+    }
+
+  return 1;
+}
+
+/****************************************************************************
+ * Name: hasmntopt
+ *
+ * Description:
+ *   Find the option opt in the comma-separated options of an entry.
+ *
+ * Returned Value:
+ *   A pointer to the option in mnt->mnt_opts, or NULL.
+ *
+ ****************************************************************************/
+
+FAR char *hasmntopt(FAR const struct mntent *mnt, FAR const char *opt)
+{
+  size_t len = strlen(opt);
+  FAR char *p = mnt->mnt_opts;
+
+  while (p != NULL && *p != '\0')
+    {
+      if (strncmp(p, opt, len) == 0 &&
+          (p[len] == '\0' || p[len] == ',' || p[len] == '='))
+        {
+          return p;
+        }
+
+      p = strchr(p, ',');
+      if (p != NULL)
+        {
+          p++;
+        }
+    }
+
+  return NULL;
+}

Reply via email to