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