summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-09-13 11:41:00 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-09-13 11:41:00 -0600
commit51829f1bcfafa46e2d2ec024c38e988f2d0f19e0 (patch)
treef0be25b27eaa8d4a1348372f2cef5243a076a02c
parente5222a9685f26a250a83a9931528d45c588e2163 (diff)
downloadpx4-nuttx-51829f1bcfafa46e2d2ec024c38e988f2d0f19e0.tar.gz
px4-nuttx-51829f1bcfafa46e2d2ec024c38e988f2d0f19e0.tar.bz2
px4-nuttx-51829f1bcfafa46e2d2ec024c38e988f2d0f19e0.zip
NSH: Fix 'ls' output for a single file. Provided by Lorenz Meier
-rw-r--r--apps/ChangeLog.txt3
-rw-r--r--apps/nshlib/nsh_fscmds.c74
2 files changed, 57 insertions, 20 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 6ae95a206..8fbf769ad 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -643,4 +643,5 @@
is created in a different task group (2013-9-7).
* apps/system/usbmonitor: The USB monitor has been extended so
that it can be used with USB device or host trace data (2013-9-9).
-
+ * apps/nshlib/nsh_fscmds.c: Fix NSH listing output for the case
+ of a single file. Provied by Lorenz Meier (2013-9-13).
diff --git a/apps/nshlib/nsh_fscmds.c b/apps/nshlib/nsh_fscmds.c
index c2fb55078..26391fa3f 100644
--- a/apps/nshlib/nsh_fscmds.c
+++ b/apps/nshlib/nsh_fscmds.c
@@ -232,7 +232,8 @@ static inline int ls_specialdir(const char *dir)
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
-static int ls_handler(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct dirent *entryp, void *pvarg)
+static int ls_handler(FAR struct nsh_vtbl_s *vtbl, FAR const char *dirpath,
+ FAR struct dirent *entryp, FAR void *pvarg)
{
unsigned int lsflags = (unsigned int)pvarg;
int ret;
@@ -242,12 +243,22 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct d
if ((lsflags & (LSFLAGS_SIZE|LSFLAGS_LONG)) != 0)
{
struct stat buf;
- char *fullpath = nsh_getdirpath(dirpath, entryp->d_name);
- /* Yes, stat the file */
+ /* stat the file */
+
+ if (entryp != NULL)
+ {
+ char *fullpath = nsh_getdirpath(dirpath, entryp->d_name);
+ ret = stat(fullpath, &buf);
+ free(fullpath);
+ }
+ else
+ {
+ /* A NULL entryp signifies that we are running ls on a single file */
+
+ ret = stat(dirpath, &buf);
+ }
- ret = stat(fullpath, &buf);
- free(fullpath);
if (ret != 0)
{
nsh_output(vtbl, g_fmtcmdfailed, "ls", "stat", NSH_ERRNO);
@@ -324,22 +335,32 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct d
}
}
- /* then provide the filename that is common to normal and verbose output */
+ /* Then provide the filename that is common to normal and verbose output */
+ if (entryp != NULL)
+ {
#ifdef CONFIG_NSH_FULLPATH
- nsh_output(vtbl, " %s/%s", arg, entryp->d_name);
+ nsh_output(vtbl, " %s/%s", arg, entryp->d_name);
#else
- nsh_output(vtbl, " %s", entryp->d_name);
+ nsh_output(vtbl, " %s", entryp->d_name);
#endif
-
- if (DIRENT_ISDIRECTORY(entryp->d_type) && !ls_specialdir(entryp->d_name))
- {
- nsh_output(vtbl, "/\n");
+ if (DIRENT_ISDIRECTORY(entryp->d_type) &&
+ !ls_specialdir(entryp->d_name))
+ {
+ nsh_output(vtbl, "/\n");
+ }
+ else
+ {
+ nsh_output(vtbl, "\n");
+ }
}
else
{
- nsh_output(vtbl, "\n");
+ /* A single file */
+
+ nsh_output(vtbl, " %s\n", dirpath);
}
+
return OK;
}
#endif
@@ -860,6 +881,7 @@ errout_with_paths:
#ifndef CONFIG_NSH_DISABLE_LS
int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
+ struct stat st;
const char *relpath;
unsigned int lsflags = 0;
char *fullpath;
@@ -929,16 +951,30 @@ int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
return ERROR;
}
- /* List the directory contents */
+ /* See if it is a single file */
- nsh_output(vtbl, "%s:\n", fullpath);
- ret = foreach_direntry(vtbl, "ls", fullpath, ls_handler, (void*)lsflags);
- if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0)
+ if (stat(fullpath, &st) == 0 && !S_ISDIR(st.st_mode))
+ {
+ /* Pass a null dirent to ls_handler to signify that this is a single
+ * file
+ */
+
+ ret = ls_handler(vtbl, fullpath, NULL, (void*)lsflags);
+ }
+ else
{
- /* Then recurse to list each directory within the directory */
+ /* List the directory contents */
- ret = foreach_direntry(vtbl, "ls", fullpath, ls_recursive, (void*)lsflags);
+ nsh_output(vtbl, "%s:\n", fullpath);
+ ret = foreach_direntry(vtbl, "ls", fullpath, ls_handler, (void*)lsflags);
+ if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0)
+ {
+ /* Then recurse to list each directory within the directory */
+
+ ret = foreach_direntry(vtbl, "ls", fullpath, ls_recursive, (void*)lsflags);
+ }
}
+
nsh_freefullpath(fullpath);
return ret;
}