Extend the NSH mount command so that it will enumerate mountpoints if no arguments are provided

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5006 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo
2012-08-03 23:47:32 +00:00
parent 606c031000
commit aa8c93baab
11 changed files with 495 additions and 308 deletions
+3
View File
@@ -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.
+4
View File
@@ -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
+17 -5
View File
@@ -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
+1 -225
View File
@@ -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)
@@ -1126,96 +1126,6 @@ errout_with_fmt:
#endif
#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
****************************************************************************/
@@ -1260,113 +1170,6 @@ int cmd_mv(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
#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_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
+384
View File
@@ -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
+1 -1
View File
@@ -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
+16 -4
View File
@@ -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">
+31 -28
View File
@@ -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 */
+25 -33
View File
@@ -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
+2 -1
View File
@@ -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
+11 -11
View File
@@ -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
****************************************************************************/