summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-08-03 23:47:32 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-08-03 23:47:32 +0000
commita98c9af060ce31895336fd3170e5efc961f1b298 (patch)
treee591f268857f6ec0f27b064bdb0b438ae8515a29
parent16d6e830b07e83e2e791c7d7bc6c712af28541e1 (diff)
downloadnuttx-a98c9af060ce31895336fd3170e5efc961f1b298.tar.gz
nuttx-a98c9af060ce31895336fd3170e5efc961f1b298.tar.bz2
nuttx-a98c9af060ce31895336fd3170e5efc961f1b298.zip
Extend the NSH mount command so that it will enumerate mountpoints if no arguments are provided
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5006 42af7a65-404d-4744-a932-0658087f49c3
-rwxr-xr-xapps/ChangeLog.txt3
-rw-r--r--apps/nshlib/Makefile4
-rw-r--r--apps/nshlib/README.txt22
-rw-r--r--apps/nshlib/nsh_fscmds.c226
-rw-r--r--apps/nshlib/nsh_mntcmds.c384
-rw-r--r--apps/nshlib/nsh_parse.c2
-rw-r--r--nuttx/Documentation/NuttShell.html20
-rw-r--r--nuttx/fs/fs_foreachinode.c59
-rw-r--r--nuttx/fs/fs_foreachmountpoint.c58
-rw-r--r--nuttx/fs/fs_internal.h3
-rw-r--r--nuttx/include/nuttx/fs/fs.h22
11 files changed, 495 insertions, 308 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index fa476a06d..ecba28589 100755
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -265,3 +265,6 @@
in order to eliminate race conditions (also from Mike Smith).
* apps/examples/adc, pwm, and qencoder: Add support for testing
devices with multiple ADC, PWM, and QE devices.
+ * apps/nshlib/nsh_mntcmds.c: Separated mount-related commands out of
+ nsh_fscmds.c. Extended to the mount command so that if no arguments
+ are provided, then the current mountpoints are enumerated.
diff --git a/apps/nshlib/Makefile b/apps/nshlib/Makefile
index ba162a086..f616374bf 100644
--- a/apps/nshlib/Makefile
+++ b/apps/nshlib/Makefile
@@ -59,6 +59,10 @@ ifeq ($(CONFIG_RTC),y)
CSRCS += nsh_timcmds.c
endif
+ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
+CSRCS += nsh_mntcmds.c
+endif
+
ifeq ($(CONFIG_NSH_CONSOLE),y)
CSRCS += nsh_consolemain.c
endif
diff --git a/apps/nshlib/README.txt b/apps/nshlib/README.txt
index 83f2b007b..45d14f30d 100644
--- a/apps/nshlib/README.txt
+++ b/apps/nshlib/README.txt
@@ -553,10 +553,17 @@ o mkrd [-m <minor>] [-s <sector-size>] <nsectors>
/tmp:
nsh>
-o mount -t <fstype> <block-device> <dir-path>
+o mount [-t <fstype> <block-device> <dir-path>]
- The 'mount' command mounts a file system in the NuttX psuedo
- filesystem. 'mount' performs a three way associating, binding
+ The mount command performs one of two different operations. If no
+ paramters are provided on the command line after the mount command,
+ then the 'mount' command will enumerate all of the current
+ mountpoints on the console.
+
+ If the mount parameters are provied on the command after the 'mount'
+ command, then the 'mount' command will mount a file system in the
+ NuttX psuedo-file system. 'mount' performs a three way association,
+ binding:
File system. The '-t <fstype>' option identifies the type of
file system that has been formatted on the <block-device>. As
@@ -579,8 +586,8 @@ o mount -t <fstype> <block-device> <dir-path>
system, it may be access in the same way as other objects in the
file system.
- Example:
- ^^^^^^^^
+ Examples:
+ ^^^^^^^^^
nsh> ls -l /dev
/dev:
@@ -602,6 +609,11 @@ o mount -t <fstype> <block-device> <dir-path>
This is a test
nsh>
+ nsh> mount
+ /etc type romfs
+ /tmp type vfat
+ /mnt/fs type vfat
+
o mv <old-path> <new-path>
Rename the file object at <old-path> to <new-path>. Both paths must
diff --git a/apps/nshlib/nsh_fscmds.c b/apps/nshlib/nsh_fscmds.c
index f6784d5b6..1a9f2eb57 100644
--- a/apps/nshlib/nsh_fscmds.c
+++ b/apps/nshlib/nsh_fscmds.c
@@ -1032,7 +1032,7 @@ int cmd_mkrd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
int minor = 0;
int ret;
- /* Get the mount options */
+ /* Get the mkrd options */
int option;
while ((option = getopt(argc, argv, ":m:s:")) != ERROR)
@@ -1127,96 +1127,6 @@ errout_with_fmt:
#endif
/****************************************************************************
- * Name: cmd_mount
- ****************************************************************************/
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
-#ifndef CONFIG_NSH_DISABLE_MOUNT
-int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
-{
- char *source;
- char *target;
- char *filesystem = 0;
- bool badarg = false;
- int ret;
-
- /* Get the mount options */
-
- int option;
- while ((option = getopt(argc, argv, ":t:")) != ERROR)
- {
- switch (option)
- {
- case 't':
- filesystem = optarg;
- break;
-
- case ':':
- nsh_output(vtbl, g_fmtargrequired, argv[0]);
- badarg = true;
- break;
-
- case '?':
- default:
- nsh_output(vtbl, g_fmtarginvalid, argv[0]);
- badarg = true;
- break;
- }
- }
-
- /* If a bad argument was encountered, then return without processing the command */
-
- if (badarg)
- {
- return ERROR;
- }
-
- /* There are two required arguments after the options */
-
- if (optind + 2 < argc)
- {
- nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
- return ERROR;
- }
- else if (optind + 2 > argc)
- {
- nsh_output(vtbl, g_fmtargrequired, argv[0]);
- return ERROR;
- }
-
- /* The source and target paths might be relative to the current
- * working directory.
- */
-
- source = nsh_getfullpath(vtbl, argv[optind]);
- if (!source)
- {
- return ERROR;
- }
-
- target = nsh_getfullpath(vtbl, argv[optind+1]);
- if (!target)
- {
- nsh_freefullpath(source);
- return ERROR;
- }
-
- /* Perform the mount */
-
- ret = mount(source, target, filesystem, 0, NULL);
- if (ret < 0)
- {
- nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
- }
-
- nsh_freefullpath(source);
- nsh_freefullpath(target);
- return ret;
-}
-#endif
-#endif
-
-/****************************************************************************
* Name: cmd_mv
****************************************************************************/
@@ -1261,113 +1171,6 @@ int cmd_mv(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
#endif
/****************************************************************************
- * Name: cmd_nfsmount
- ****************************************************************************/
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && \
- defined(CONFIG_NET) && defined(CONFIG_NFS)
-#ifndef CONFIG_NSH_DISABLE_NFSMOUNT
-int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
-{
- struct nfs_args data;
- FAR char *address;
- FAR char *lpath;
- FAR char *rpath;
- bool badarg = false;
-#ifdef CONFIG_NET_IPv6
- FAR struct sockaddr_in6 *sin;
- struct in6_addr inaddr;
-#else
- FAR struct sockaddr_in *sin;
- struct in_addr inaddr;
-#endif
- int ret;
-
- /* If a bad argument was encountered, then return without processing the
- * command.
- */
-
- if (badarg)
- {
- return ERROR;
- }
-
- /* The fist argument on the command line should be the NFS server IP address
- * in standard IPv4 (or IPv6) dot format.
- */
-
- address = argv[1];
- if (!address)
- {
- return ERROR;
- }
-
- /* The local mount point path (lpath) might be relative to the current working
- * directory.
- */
-
- lpath = nsh_getfullpath(vtbl, argv[2]);
- if (!lpath)
- {
- return ERROR;
- }
-
- /* Get the remote mount point path */
-
- rpath = argv[3];
-
- /* Convert the IP address string into its binary form */
-
-#ifdef CONFIG_NET_IPv6
- ret = inet_pton(AF_INET6, address, &inaddr);
-#else
- ret = inet_pton(AF_INET, address, &inaddr);
-#endif
- if (ret != 1)
- {
- nsh_freefullpath(lpath);
- return ERROR;
- }
-
- /* Place all of the NFS arguements into the nfs_args structure */
-
- memset(&data, 0, sizeof(data));
-
-#ifdef CONFIG_NET_IPv6
- sin = (FAR struct sockaddr_in6 *)&data.addr;
- sin->sin_family = AF_INET6;
- sin->sin_port = htons(NFS_PMAPPORT);
- memcpy(&sin->sin6_addr, &inaddr, sizeof(struct in6_addr));
- data.addrlen = sizeof(struct sockaddr_in6);
-#else
- sin = (FAR struct sockaddr_in *)&data.addr;
- sin->sin_family = AF_INET;
- sin->sin_port = htons(NFS_PMAPPORT);
- sin->sin_addr = inaddr;
- data.addrlen = sizeof(struct sockaddr_in);
-#endif
-
- data.sotype = SOCK_DGRAM;
- data.path = rpath;
- data.flags = 0; /* 0=Use all defaults */
-
- /* Perform the mount */
-
- ret = mount(NULL, lpath, "nfs", 0, (FAR void *)&data);
- if (ret < 0)
- {
- nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
- }
-
- /* We no longer need the allocated mount point path */
-
- nsh_freefullpath(lpath);
- return ret;
-}
-#endif
-#endif
-
-/****************************************************************************
* Name: cmd_rm
****************************************************************************/
@@ -1494,30 +1297,3 @@ int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
}
#endif
#endif
-
-/****************************************************************************
- * Name: cmd_umount
- ****************************************************************************/
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
-#ifndef CONFIG_NSH_DISABLE_UMOUNT
-int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
-{
- char *fullpath = nsh_getfullpath(vtbl, argv[1]);
- int ret = ERROR;
-
- if (fullpath)
- {
- /* Perform the umount */
-
- ret = umount(fullpath);
- if (ret < 0)
- {
- nsh_output(vtbl, g_fmtcmdfailed, argv[0], "umount", NSH_ERRNO);
- }
- nsh_freefullpath(fullpath);
- }
- return ret;
-}
-#endif
-#endif
diff --git a/apps/nshlib/nsh_mntcmds.c b/apps/nshlib/nsh_mntcmds.c
new file mode 100644
index 000000000..054119e02
--- /dev/null
+++ b/apps/nshlib/nsh_mntcmds.c
@@ -0,0 +1,384 @@
+/****************************************************************************
+ * apps/nshlib/nsh_mntcmds.c
+ *
+ * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/statfs.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "nsh.h"
+#include "nsh_console.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mount_handler
+ ****************************************************************************/
+
+#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
+#ifndef CONFIG_NSH_DISABLE_MOUNT
+static int mount_handler(FAR const char *mountpoint,
+ FAR struct statfs *statbuf, FAR void *arg)
+{
+ FAR struct nsh_vtbl_s *vtbl = (FAR struct nsh_vtbl_s *)arg;
+ FAR const char *fstype;
+
+ DEBUGASSERT(mountpoint && statbuf && vtbl);
+
+ /* Get the file system type */
+
+ switch (statbuf->f_type)
+ {
+#ifdef CONFIG_FS_FAT
+ case MSDOS_SUPER_MAGIC:
+ fstype = "vfat";
+ break;
+#endif
+
+#ifdef CONFIG_FS_ROMFS
+ case ROMFS_MAGIC:
+ fstype = "romfs";
+ break;
+#endif
+
+#ifdef CONFIG_APPS_BINDIR
+ case BINFS_MAGIC:
+ fstype = "bindir";
+ break;
+#endif
+
+#ifdef CONFIG_FS_NXFFS
+ case NXFFS_MAGIC:
+ fstype = "nxffs";
+ break;
+#endif
+
+#ifdef CONFIG_NFS
+ case NFS_SUPER_MAGIC:
+ fstype = "nfs";
+ break;
+#endif
+
+ default:
+ fstype = "Unrecognized";
+ break;
+ }
+
+ nsh_output(vtbl, " %s type %s\n", mountpoint, fstype);
+ return OK;
+}
+#endif
+#endif
+
+/****************************************************************************
+ * Name: mount_show
+ ****************************************************************************/
+
+#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
+#ifndef CONFIG_NSH_DISABLE_MOUNT
+static inline int mount_show(FAR struct nsh_vtbl_s *vtbl, FAR const char *progname)
+{
+ return foreach_mountpoint(mount_handler, (FAR void *)vtbl);
+}
+#endif
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cmd_mount
+ ****************************************************************************/
+
+#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
+#ifndef CONFIG_NSH_DISABLE_MOUNT
+int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ char *source;
+ char *target;
+ char *filesystem = 0;
+ bool badarg = false;
+ int ret;
+
+ /* The mount command behaves differently if no parameters are provided */
+
+ if (argc < 2)
+ {
+ return mount_show(vtbl, argv[0]);
+ }
+
+ /* Get the mount options */
+
+ int option;
+ while ((option = getopt(argc, argv, ":t:")) != ERROR)
+ {
+ switch (option)
+ {
+ case 't':
+ filesystem = optarg;
+ break;
+
+ case ':':
+ nsh_output(vtbl, g_fmtargrequired, argv[0]);
+ badarg = true;
+ break;
+
+ case '?':
+ default:
+ nsh_output(vtbl, g_fmtarginvalid, argv[0]);
+ badarg = true;
+ break;
+ }
+ }
+
+ /* If a bad argument was encountered, then return without processing the command */
+
+ if (badarg)
+ {
+ return ERROR;
+ }
+
+ /* There are two required arguments after the options */
+
+ if (optind + 2 < argc)
+ {
+ nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
+ return ERROR;
+ }
+ else if (optind + 2 > argc)
+ {
+ nsh_output(vtbl, g_fmtargrequired, argv[0]);
+ return ERROR;
+ }
+
+ /* The source and target paths might be relative to the current
+ * working directory.
+ */
+
+ source = nsh_getfullpath(vtbl, argv[optind]);
+ if (!source)
+ {
+ return ERROR;
+ }
+
+ target = nsh_getfullpath(vtbl, argv[optind+1]);
+ if (!target)
+ {
+ nsh_freefullpath(source);
+ return ERROR;
+ }
+
+ /* Perform the mount */
+
+ ret = mount(source, target, filesystem, 0, NULL);
+ if (ret < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
+ }
+
+ nsh_freefullpath(source);
+ nsh_freefullpath(target);
+ return ret;
+}
+#endif
+#endif
+
+/****************************************************************************
+ * Name: cmd_nfsmount
+ ****************************************************************************/
+
+#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && \
+ defined(CONFIG_NET) && defined(CONFIG_NFS)
+#ifndef CONFIG_NSH_DISABLE_NFSMOUNT
+int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ struct nfs_args data;
+ FAR char *address;
+ FAR char *lpath;
+ FAR char *rpath;
+ bool badarg = false;
+#ifdef CONFIG_NET_IPv6
+ FAR struct sockaddr_in6 *sin;
+ struct in6_addr inaddr;
+#else
+ FAR struct sockaddr_in *sin;
+ struct in_addr inaddr;
+#endif
+ int ret;
+
+ /* If a bad argument was encountered, then return without processing the
+ * command.
+ */
+
+ if (badarg)
+ {
+ return ERROR;
+ }
+
+ /* The fist argument on the command line should be the NFS server IP address
+ * in standard IPv4 (or IPv6) dot format.
+ */
+
+ address = argv[1];
+ if (!address)
+ {
+ return ERROR;
+ }
+
+ /* The local mount point path (lpath) might be relative to the current working
+ * directory.
+ */
+
+ lpath = nsh_getfullpath(vtbl, argv[2]);
+ if (!lpath)
+ {
+ return ERROR;
+ }
+
+ /* Get the remote mount point path */
+
+ rpath = argv[3];
+
+ /* Convert the IP address string into its binary form */
+
+#ifdef CONFIG_NET_IPv6
+ ret = inet_pton(AF_INET6, address, &inaddr);
+#else
+ ret = inet_pton(AF_INET, address, &inaddr);
+#endif
+ if (ret != 1)
+ {
+ nsh_freefullpath(lpath);
+ return ERROR;
+ }
+
+ /* Place all of the NFS arguements into the nfs_args structure */
+
+ memset(&data, 0, sizeof(data));
+
+#ifdef CONFIG_NET_IPv6
+ sin = (FAR struct sockaddr_in6 *)&data.addr;
+ sin->sin_family = AF_INET6;
+ sin->sin_port = htons(NFS_PMAPPORT);
+ memcpy(&sin->sin6_addr, &inaddr, sizeof(struct in6_addr));
+ data.addrlen = sizeof(struct sockaddr_in6);
+#else
+ sin = (FAR struct sockaddr_in *)&data.addr;
+ sin->sin_family = AF_INET;
+ sin->sin_port = htons(NFS_PMAPPORT);
+ sin->sin_addr = inaddr;
+ data.addrlen = sizeof(struct sockaddr_in);
+#endif
+
+ data.sotype = SOCK_DGRAM;
+ data.path = rpath;
+ data.flags = 0; /* 0=Use all defaults */
+
+ /* Perform the mount */
+
+ ret = mount(NULL, lpath, "nfs", 0, (FAR void *)&data);
+ if (ret < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
+ }
+
+ /* We no longer need the allocated mount point path */
+
+ nsh_freefullpath(lpath);
+ return ret;
+}
+#endif
+#endif
+
+/****************************************************************************
+ * Name: cmd_umount
+ ****************************************************************************/
+
+#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
+#ifndef CONFIG_NSH_DISABLE_UMOUNT
+int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ char *fullpath = nsh_getfullpath(vtbl, argv[1]);
+ int ret = ERROR;
+
+ if (fullpath)
+ {
+ /* Perform the umount */
+
+ ret = umount(fullpath);
+ if (ret < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "umount", NSH_ERRNO);
+ }
+ nsh_freefullpath(fullpath);
+ }
+ return ret;
+}
+#endif
+#endif
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index 4c4300cc6..d62f6b5a9 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -259,7 +259,7 @@ static const struct cmdmap_s g_cmdmap[] =
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
# ifndef CONFIG_NSH_DISABLE_MOUNT
- { "mount", cmd_mount, 4, 5, "-t <fstype> <block-device> <mount-point>" },
+ { "mount", cmd_mount, 1, 5, "[-t <fstype> <block-device> <mount-point>]" },
# endif
#endif
diff --git a/nuttx/Documentation/NuttShell.html b/nuttx/Documentation/NuttShell.html
index 2f7bb7974..86014074f 100644
--- a/nuttx/Documentation/NuttShell.html
+++ b/nuttx/Documentation/NuttShell.html
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttShell (NSH)</i></font></big></h1>
- <p>Last Updated: June 15, 2012</p>
+ <p>Last Updated: August 3, 2012</p>
</td>
</tr>
</table>
@@ -1439,8 +1439,12 @@ mount -t &lt;fstype&gt; &lt;block-device&gt; <code>&lt;dir-path&gt;</code>
</pre></ul>
<p>
<b>Synopsis</b>.
- The 'm ount' command mounts a file system in the NuttX psuedo
- filesystem. 'mount' performs a three way associating, binding:
+ The <code>mount</code> command performs one of two different operations.
+ If no paramters are provided on the command line after the <code>mount</code> command, then the <code>mount</code> command will enumerate all of the current mountpoints on the console.
+</p>
+<p>
+ If the mount parameters are provied on the command after the <code>mount</code> command, then the <code>mount</code> command will mount a file system in the NuttX psuedo-file system.
+ <code>mount</code>' performs a three way association, binding:
</p>
<ol>
<li><b>File system.</b>
@@ -1469,7 +1473,8 @@ mount -t &lt;fstype&gt; &lt;block-device&gt; <code>&lt;dir-path&gt;</code>
<a href="NuttxUserGuide.html#FileSystemOverview"><i>pseudo</i> filesystem</a>,
it may be access in the same way as other objects in thefile system.
</p>
-<p><b>Example</b></p>
+<p><b>Examples</b>:</p>
+<p>Using <code>mount</code> to mount a file system:</p>
<ul><pre>
nsh> ls -l /dev
/dev:
@@ -1491,6 +1496,13 @@ nsh> cat /mnt/fs/testdir/example.txt
This is a test
nsh>
</pre></ul>
+<p>Using <code>mount</code> to enumerate mounts:</p>
+<ul><pre>
+nsh> mount
+ /etc type romfs
+ /mnt/fs type vfat
+ /tmp type vfat
+</pre></ul>
<table width ="100%">
<tr bgcolor="#e4e4e4">
diff --git a/nuttx/fs/fs_foreachinode.c b/nuttx/fs/fs_foreachinode.c
index 7aefcb1c6..08630263b 100644
--- a/nuttx/fs/fs_foreachinode.c
+++ b/nuttx/fs/fs_foreachinode.c
@@ -39,6 +39,7 @@
#include <nuttx/config.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@@ -96,7 +97,7 @@ struct inode_path_s
int foreach_inodelevel(FAR struct inode *node, struct inode_path_s *info)
{
- int ret;
+ int ret = OK;
/* Visit each node at this level */
@@ -106,11 +107,13 @@ int foreach_inodelevel(FAR struct inode *node, struct inode_path_s *info)
ret = info->handler(node, info->path, info->arg);
- /* Return early if the handler returns a non-zero value */
+ /* Break out of the looop early if the handler returns a non-zero
+ * value
+ */
if (ret != 0)
{
- return ret;
+ break;
}
/* If there is a level 'beneath' this one, then recurse to visit all
@@ -126,33 +129,35 @@ int foreach_inodelevel(FAR struct inode *node, struct inode_path_s *info)
/* Make sure that this would not exceed the maximum path length */
- if (pathlen + namlen < PATH_MAX)
+ if (pathlen + namlen > PATH_MAX)
{
- /* Append the path segment to this inode */
+ ret = -ENAMETOOLONG;
+ break;
+ }
- strcat(info->path, "/");
- strcat(info->path, node->i_name);
- ret = foreach_inodelevel(node->i_child, info);
+ /* Append the path segment to this inode and recurse */
- /* Truncate the path name back to the correct length */
+ sprintf(&info->path[pathlen], "/%s", node->i_name);
+ ret = foreach_inodelevel(node->i_child, info);
- info->path[pathlen] = '\0';
+ /* Truncate the path name back to the correct length */
- /* Return early if the handler at the lower level returned a non-
- * zero value
- */
+ info->path[pathlen] = '\0';
- if (ret != 0)
- {
- return ret;
- }
+ /* Return early if the handler at the lower level returned a non-
+ * zero value
+ */
+
+ if (ret != 0)
+ {
+ break;
}
}
}
- /* No handler complained... return zero */
+ /* Return the result of the traversal. */
- return 0;
+ return ret;
}
/****************************************************************************
@@ -176,24 +181,23 @@ int foreach_inodelevel(FAR struct inode *node, struct inode_path_s *info)
int foreach_inode(foreach_inode_t handler, FAR void *arg)
{
-#ifdef ENUM_MOUNTPOINT_ALLOC
+#ifdef ENUM_INODE_ALLOC
FAR struct inode_path_s *info;
int ret;
/* Allocate the mountpoint info structure */
info = (FAR struct inode_path_s *)malloc(sizeof(struct inode_path_s));
- if (!path)
+ if (!info)
{
return -ENOMEM;
}
- /* Initialize the path structure */
+ /* Initialize the info structure */
info->handler = handler;
info->arg = arg;
- info->path[0] = '/';
- info->path[1] = '\0';
+ info->path[0] = '\0';
/* Start the recursion at the root inode */
@@ -201,7 +205,7 @@ int foreach_inode(foreach_inode_t handler, FAR void *arg)
ret = foreach_inodelevel(root_inode, info);
inode_semgive();
- /* Free the path structure and return the result */
+ /* Free the info structure and return the result */
free(info);
return ret;
@@ -210,12 +214,11 @@ int foreach_inode(foreach_inode_t handler, FAR void *arg)
struct inode_path_s info;
int ret;
- /* Initialize the path structure */
+ /* Initialize the info structure */
info.handler = handler;
info.arg = arg;
- info.path[0] = '/';
- info.path[1] = '\0';
+ info.path[0] = '\0';
/* Start the recursion at the root inode */
diff --git a/nuttx/fs/fs_foreachmountpoint.c b/nuttx/fs/fs_foreachmountpoint.c
index a2867c55e..e7a620650 100644
--- a/nuttx/fs/fs_foreachmountpoint.c
+++ b/nuttx/fs/fs_foreachmountpoint.c
@@ -56,11 +56,6 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
-/* Is it better to allocate the struct enum_mountpoint_s from the heap? or
- * from the stack?
- */
-
-#define ENUM_MOUNTPOINT_ALLOC 1
/****************************************************************************
* Private Types
@@ -74,7 +69,6 @@ struct enum_mountpoint_s
{
foreach_mountpoint_t handler;
FAR void *arg;
- char path[CONFIG_PATH_MAX];
};
/****************************************************************************
@@ -90,25 +84,41 @@ struct enum_mountpoint_s
****************************************************************************/
static int mountpoint_filter(FAR struct inode *node,
- FAR const char *dirpath, FAR void *arg)
+ FAR char dirpath[PATH_MAX], FAR void *arg)
{
FAR struct enum_mountpoint_s *info = (FAR struct enum_mountpoint_s *)arg;
struct statfs statbuf;
+ int pathlen;
+ int namlen;
int ret = OK;
- DEBUGASSERT(node && node->u.i_mops && info && info->handler);
+ DEBUGASSERT(node && info && info->handler);
/* Check if the inode is a mountpoint. Mountpoints must support statfs.
* If this one does not for some reason, then it will be ignored.
+ *
+ * The root node is a special case: It has no operations (u.i_mops == NULL)
*/
- if (INODE_IS_MOUNTPT(node) && node->u.i_mops->statfs)
+ if (INODE_IS_MOUNTPT(node) && node->u.i_mops && node->u.i_mops->statfs)
{
/* Yes... get the full path to the inode by concatenating the inode
* name and the path to the directory containing the inode.
*/
- snprintf(info->path, PATH_MAX, "%s/%s", dirpath, node->i_name);
+ pathlen = strlen(dirpath);
+ namlen = strlen(node->i_name) + 1;
+
+ /* Make sure that this would not exceed the maximum path length */
+
+ if (pathlen + namlen > PATH_MAX)
+ {
+ return -ENAMETOOLONG;
+ }
+
+ /* Append the inode name to the directory path */
+
+ sprintf(&dirpath[pathlen], "/%s", node->i_name);
/* Get the status of the file system */
@@ -117,8 +127,12 @@ static int mountpoint_filter(FAR struct inode *node,
{
/* And pass the full path and file system status to the handler */
- ret = info->handler(info->path, &statbuf, info->arg);
+ ret = info->handler(dirpath, &statbuf, info->arg);
}
+
+ /* Truncate the path name back to the correct length */
+
+ dirpath[pathlen] = '\0';
}
return ret;
@@ -150,27 +164,6 @@ static int mountpoint_filter(FAR struct inode *node,
int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg)
{
-#ifdef ENUM_MOUNTPOINT_ALLOC
- FAR struct enum_mountpoint_s *info;
- int ret;
-
- /* Allocate the mountpoint info structure */
-
- info = (FAR struct enum_mountpoint_s *)malloc(sizeof(struct enum_mountpoint_s));
- if (!info)
- {
- return -ENOMEM;
- }
-
- /* Let foreach_inode do the real work */
-
- info->handler = handler;
- info->arg = arg;
-
- ret = foreach_inode(mountpoint_filter, (FAR void *)info);
- free(info);
- return ret;
-#else
struct enum_mountpoint_s info;
/* Let foreach_inode do the real work */
@@ -179,7 +172,6 @@ int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg)
info.arg = arg;
return foreach_inode(mountpoint_filter, (FAR void *)&info);
-#endif
}
#endif
diff --git a/nuttx/fs/fs_internal.h b/nuttx/fs/fs_internal.h
index 4405b07ba..dbabb63d1 100644
--- a/nuttx/fs/fs_internal.h
+++ b/nuttx/fs/fs_internal.h
@@ -89,7 +89,8 @@
*/
typedef int (*foreach_inode_t)(FAR struct inode *node,
- FAR const char *dirpath, FAR void *arg);
+ FAR char dirpath[PATH_MAX],
+ FAR void *arg);
/****************************************************************************
* Global Variables
diff --git a/nuttx/include/nuttx/fs/fs.h b/nuttx/include/nuttx/fs/fs.h
index 4990d8773..07d28597e 100644
--- a/nuttx/include/nuttx/fs/fs.h
+++ b/nuttx/include/nuttx/fs/fs.h
@@ -216,17 +216,6 @@ struct inode
};
#define FSNODE_SIZE(n) (sizeof(struct inode) + (n))
-/* Callback used by foreach_mountpoints to traverse all mountpoints in the
- * pseudo-file system.
- */
-
-#ifndef CONFIG_DISABLE_MOUNTPOUNT
-struct statfs; /* Forward reference */
-typedef int (*foreach_mountpoint_t)(FAR const char *mountpoint,
- FAR struct statfs *statbuf,
- FAR void *arg);
-#endif
-
/* This is the underlying representation of an open file. A file
* descriptor is an index into an array of such types. The type associates
* the file descriptor to the file state and to a set of inode operations.
@@ -305,6 +294,17 @@ struct streamlist
};
#endif /* CONFIG_NFILE_STREAMS */
+/* Callback used by foreach_mountpoints to traverse all mountpoints in the
+ * pseudo-file system.
+ */
+
+#ifndef CONFIG_DISABLE_MOUNTPOUNT
+struct statfs; /* Forward reference */
+typedef int (*foreach_mountpoint_t)(FAR const char *mountpoint,
+ FAR struct statfs *statbuf,
+ FAR void *arg);
+#endif
+
/****************************************************************************
* Global Function Prototypes
****************************************************************************/