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
This commit is contained in:
parent
1e1e828a3d
commit
1b46dae578
@ -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 <fstype> <block-device> <code><dir-path></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 <fstype> <block-device> <code><dir-path></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">
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user