From 631c9cec128f87c592ebc7f145d4b90b57e53a97 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 28 Nov 2015 11:13:47 -0600 Subject: [PATCH] apps/nshlib: The I/O buffer, g_iobuffer, should not be a global buffer. That will not work in an environment where there are multiple NSH sessions. The I/O buffer must, instead, be a part part of the session-specific data defined in nsh_console.h # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. --- ChangeLog.txt | 5 ++++- nshlib/nsh.h | 19 ++++++++++++++++--- nshlib/nsh_console.h | 6 ++++++ nshlib/nsh_fscmds.c | 40 +++++++++++----------------------------- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 2c99b9adb..8c6adb3ec 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1477,4 +1477,7 @@ * apps/nshlib: Add a new NSH losmart command. losmart setups up a loop device for the smart MTD driver similar to losetup but with different syntax. From Ket Petit (2015-11-28). - + * apps/nshlib: The I/O buffer, g_iobuffer, should not be a global + buffer. That will not work in an environment where there are multiple + NSH sessions. The I/O buffer must, instead, be a part part of the + session-specific data defined in nsh_console.h (2015-11-28). diff --git a/nshlib/nsh.h b/nshlib/nsh.h index b100d8872..5e79f3054 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -567,7 +567,20 @@ * large as PATH_MAX. */ -#if CONFIG_NFILE_DESCRIPTORS > 0 +#define NSH_HAVE_IOBUFFER 1 + +#if CONFIG_NFILE_DESCRIPTORS <= 0 +# undef NSH_HAVE_IOBUFFER +#endif + +/* The I/O buffer is needed for the ls, cp, and ps commands */ + +#if defined(CONFIG_NSH_DISABLE_LS) && defined(CONFIG_NSH_DISABLE_CP) && \ + defined(CONFIG_NSH_DISABLE_PS) +# undef NSH_HAVE_IOBUFFER +#endif + +#ifdef NSH_HAVE_IOBUFFER # ifdef CONFIG_NSH_FILEIOSIZE # if CONFIG_NSH_FILEIOSIZE > (PATH_MAX + 1) # define IOBUFFERSIZE CONFIG_NSH_FILEIOSIZE @@ -577,8 +590,8 @@ # else # define IOBUFFERSIZE 1024 # endif -# else -# define IOBUFFERSIZE (PATH_MAX + 1) +#else +# define IOBUFFERSIZE (PATH_MAX + 1) #endif /* Certain commands are not available in a kernel builds because they depend diff --git a/nshlib/nsh_console.h b/nshlib/nsh_console.h index 8731b6bf1..8ad9c7b37 100644 --- a/nshlib/nsh_console.h +++ b/nshlib/nsh_console.h @@ -123,6 +123,12 @@ struct nsh_vtbl_s #endif void (*exit)(FAR struct nsh_vtbl_s *vtbl, int exitstatus) noreturn_function; +#ifdef NSH_HAVE_IOBUFFER +/* Common buffer for file I/O. */ + + char iobuffer[IOBUFFERSIZE]; +#endif + /* Parser state data */ struct nsh_parser_s np; diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index b19d35ba2..530720401 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -97,25 +97,6 @@ #define LSFLAGS_LONG 2 #define LSFLAGS_RECURSIVE 4 -/**************************************************************************** - * Private Data - ****************************************************************************/ - -#if CONFIG_NFILE_DESCRIPTORS > 0 && \ - (!defined(CONFIG_NSH_DISABLE_LS) || !defined(CONFIG_NSH_DISABLE_CP)) -/* Common buffer for file I/O. Note the use of this common buffer precludes - * multiple copies of NSH running concurrently. It should be allocated per - * NSH instance and retained in the "vtbl" as is done for the telnet - * connection. - */ - -static char g_iobuffer[IOBUFFERSIZE]; -#endif - -/**************************************************************************** - * Public Data - ****************************************************************************/ - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -126,21 +107,22 @@ static char g_iobuffer[IOBUFFERSIZE]; #if CONFIG_NFILE_DESCRIPTORS > 0 && \ (!defined(CONFIG_NSH_DISABLE_LS) || !defined(CONFIG_NSH_DISABLE_CP)) -static char *nsh_getdirpath(FAR const char *path, FAR const char *file) +static char *nsh_getdirpath(FAR struct nsh_vtbl_s *vtbl, + FAR const char *path, FAR const char *file) { /* Handle the case where all that is left is '/' */ if (strcmp(path, "/") == 0) { - sprintf(g_iobuffer, "/%s", file); + sprintf(vtbl->iobuffer, "/%s", file); } else { - sprintf(g_iobuffer, "%s/%s", path, file); + sprintf(vtbl->iobuffer, "%s/%s", path, file); } - g_iobuffer[PATH_MAX] = '\0'; - return strdup(g_iobuffer); + vtbl->iobuffer[PATH_MAX] = '\0'; + return strdup(vtbl->iobuffer); } #endif @@ -176,7 +158,7 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, FAR const char *dirpath, if (entryp != NULL) { - char *fullpath = nsh_getdirpath(dirpath, entryp->d_name); + FAR char *fullpath = nsh_getdirpath(vtbl, dirpath, entryp->d_name); ret = stat(fullpath, &buf); free(fullpath); } @@ -311,7 +293,7 @@ static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, /* Yes.. */ FAR char *newpath; - newpath = nsh_getdirpath(dirpath, entryp->d_name); + newpath = nsh_getdirpath(vtbl, dirpath, entryp->d_name); /* List the directory contents */ @@ -508,7 +490,7 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) /* Construct the full path to the new file */ - allocpath = nsh_getdirpath(argv[2], basename(argv[1]) ); + allocpath = nsh_getdirpath(vtbl, argv[2], basename(argv[1]) ); if (!allocpath) { nsh_output(vtbl, g_fmtcmdoutofmemory, argv[0]); @@ -546,7 +528,7 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) do { - nbytesread = read(rdfd, g_iobuffer, IOBUFFERSIZE); + nbytesread = read(rdfd, vtbl->iobuffer, IOBUFFERSIZE); if (nbytesread == 0) { /* End of file */ @@ -577,7 +559,7 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) do { - nbyteswritten = write(wrfd, g_iobuffer, nbytesread); + nbyteswritten = write(wrfd, vtbl->iobuffer, nbytesread); if (nbyteswritten >= 0) { nbytesread -= nbyteswritten;