From 1b46dae57847b1145674d6c5edec631661e1c006 Mon Sep 17 00:00:00 2001
From: patacongo
Date: Fri, 3 Aug 2012 23:47:32 +0000
Subject: [PATCH] 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
---
Documentation/NuttShell.html | 20 +++++++++---
fs/fs_foreachinode.c | 59 +++++++++++++++++++-----------------
fs/fs_foreachmountpoint.c | 58 +++++++++++++++--------------------
fs/fs_internal.h | 3 +-
include/nuttx/fs/fs.h | 22 +++++++-------
5 files changed, 85 insertions(+), 77 deletions(-)
diff --git a/Documentation/NuttShell.html b/Documentation/NuttShell.html
index 2f7bb7974b..86014074f4 100644
--- a/Documentation/NuttShell.html
+++ b/Documentation/NuttShell.html
@@ -8,7 +8,7 @@
NuttShell (NSH)
- Last Updated: June 15, 2012
+ Last Updated: August 3, 2012
|
@@ -1439,8 +1439,12 @@ mount -t <fstype> <block-device> <dir-path>
Synopsis.
- The 'm ount' 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.
@@ -1469,7 +1473,8 @@ mount -t <fstype> <block-device>
<dir-path>
pseudo filesystem,
it may be access in the same way as other objects in thefile system.
-Example
+Examples:
+Using mount
to mount a file system:
nsh> ls -l /dev
/dev:
@@ -1491,6 +1496,13 @@ nsh> cat /mnt/fs/testdir/example.txt
This is a test
nsh>
+Using mount
to enumerate mounts:
+
+nsh> mount
+ /etc type romfs
+ /mnt/fs type vfat
+ /tmp type vfat
+
diff --git a/fs/fs_foreachinode.c b/fs/fs_foreachinode.c
index 7aefcb1c69..08630263b2 100644
--- a/fs/fs_foreachinode.c
+++ b/fs/fs_foreachinode.c
@@ -39,6 +39,7 @@
#include
+#include
#include
#include
#include
@@ -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/fs/fs_foreachmountpoint.c b/fs/fs_foreachmountpoint.c
index a2867c55e0..e7a6206506 100644
--- a/fs/fs_foreachmountpoint.c
+++ b/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/fs/fs_internal.h b/fs/fs_internal.h
index 4405b07ba7..dbabb63d1b 100644
--- a/fs/fs_internal.h
+++ b/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/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h
index 4990d87734..07d28597e8 100644
--- a/include/nuttx/fs/fs.h
+++ b/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
****************************************************************************/