diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-09-13 11:41:00 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-09-13 11:41:00 -0600 |
commit | 51829f1bcfafa46e2d2ec024c38e988f2d0f19e0 (patch) | |
tree | f0be25b27eaa8d4a1348372f2cef5243a076a02c | |
parent | e5222a9685f26a250a83a9931528d45c588e2163 (diff) | |
download | nuttx-51829f1bcfafa46e2d2ec024c38e988f2d0f19e0.tar.gz nuttx-51829f1bcfafa46e2d2ec024c38e988f2d0f19e0.tar.bz2 nuttx-51829f1bcfafa46e2d2ec024c38e988f2d0f19e0.zip |
NSH: Fix 'ls' output for a single file. Provided by Lorenz Meier
-rw-r--r-- | apps/ChangeLog.txt | 3 | ||||
-rw-r--r-- | apps/nshlib/nsh_fscmds.c | 74 |
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; } |