NSH: Fix 'ls' output for a single file. Provided by Lorenz Meier

This commit is contained in:
Gregory Nutt 2013-09-13 11:41:00 -06:00
parent 645d02acdc
commit 2ee72f55d3
2 changed files with 59 additions and 22 deletions

View File

@ -643,4 +643,5 @@
is created in a different task group (2013-9-7). is created in a different task group (2013-9-7).
* apps/system/usbmonitor: The USB monitor has been extended so * 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). 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).

View File

@ -232,7 +232,8 @@ static inline int ls_specialdir(const char *dir)
****************************************************************************/ ****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 #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; unsigned int lsflags = (unsigned int)pvarg;
int ret; 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) if ((lsflags & (LSFLAGS_SIZE|LSFLAGS_LONG)) != 0)
{ {
struct stat buf; 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) if (ret != 0)
{ {
nsh_output(vtbl, g_fmtcmdfailed, "ls", "stat", NSH_ERRNO); 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 */
#ifdef CONFIG_NSH_FULLPATH if (entryp != NULL)
nsh_output(vtbl, " %s/%s", arg, entryp->d_name);
#else
nsh_output(vtbl, " %s", entryp->d_name);
#endif
if (DIRENT_ISDIRECTORY(entryp->d_type) && !ls_specialdir(entryp->d_name))
{ {
nsh_output(vtbl, "/\n"); #ifdef CONFIG_NSH_FULLPATH
nsh_output(vtbl, " %s/%s", arg, entryp->d_name);
#else
nsh_output(vtbl, " %s", entryp->d_name);
#endif
if (DIRENT_ISDIRECTORY(entryp->d_type) &&
!ls_specialdir(entryp->d_name))
{
nsh_output(vtbl, "/\n");
}
else
{
nsh_output(vtbl, "\n");
}
} }
else else
{ {
nsh_output(vtbl, "\n"); /* A single file */
nsh_output(vtbl, " %s\n", dirpath);
} }
return OK; return OK;
} }
#endif #endif
@ -860,6 +881,7 @@ errout_with_paths:
#ifndef CONFIG_NSH_DISABLE_LS #ifndef CONFIG_NSH_DISABLE_LS
int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{ {
struct stat st;
const char *relpath; const char *relpath;
unsigned int lsflags = 0; unsigned int lsflags = 0;
char *fullpath; char *fullpath;
@ -929,16 +951,30 @@ int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
return ERROR; return ERROR;
} }
/* List the directory contents */ /* See if it is a single file */
nsh_output(vtbl, "%s:\n", fullpath); if (stat(fullpath, &st) == 0 && !S_ISDIR(st.st_mode))
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 */ /* Pass a null dirent to ls_handler to signify that this is a single
* file
*/
ret = foreach_direntry(vtbl, "ls", fullpath, ls_recursive, (void*)lsflags); ret = ls_handler(vtbl, fullpath, NULL, (void*)lsflags);
} }
else
{
/* List the directory contents */
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); nsh_freefullpath(fullpath);
return ret; return ret;
} }