Added ch and pwd to NSH
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@841 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
c7419e57d3
commit
3f2dfbb298
@ -420,5 +420,7 @@
|
|||||||
* Add chdir() and getcwd()
|
* Add chdir() and getcwd()
|
||||||
* Fix error in getopt() when called with argc==1
|
* Fix error in getopt() when called with argc==1
|
||||||
* Fix error in stat() when used on the root directory
|
* Fix error in stat() when used on the root directory
|
||||||
|
* NSH: Add cd and pwd commands and current working directory to all NSH
|
||||||
|
commands that refer to paths.
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<tr align="center" bgcolor="#e4e4e4">
|
<tr align="center" bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||||
<p>Last Updated: August 22, 2008</p>
|
<p>Last Updated: August 23, 2008</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -1052,6 +1052,10 @@ nuttx-0.3.13 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
|||||||
* NSH now supports commands to inspect and modify memory
|
* NSH now supports commands to inspect and modify memory
|
||||||
* NSH cat command now supports multiple files on command line
|
* NSH cat command now supports multiple files on command line
|
||||||
* Add chdir() and getcwd()
|
* Add chdir() and getcwd()
|
||||||
|
* Fix error in getopt() when called with argc==1
|
||||||
|
* Fix error in stat() when used on the root directory
|
||||||
|
* NSH: Add cd and pwd commands and current working directory to all NSH
|
||||||
|
commands that refer to paths.
|
||||||
|
|
||||||
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ examples/nsh
|
|||||||
Command Depends on Configuration
|
Command Depends on Configuration
|
||||||
---------- --------------------------
|
---------- --------------------------
|
||||||
cat CONFIG_NFILE_DESCRIPTORS > 0
|
cat CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
|
cd !CONFIG_DISABLE_ENVIRON && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
cp CONFIG_NFILE_DESCRIPTORS > 0
|
cp CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
echo --
|
echo --
|
||||||
exec --
|
exec --
|
||||||
@ -51,6 +52,7 @@ examples/nsh
|
|||||||
mkfifo !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0
|
mkfifo !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
mount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_FAT
|
mount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_FAT
|
||||||
ps --
|
ps --
|
||||||
|
pwd !CONFIG_DISABLE_ENVIRON && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
set !CONFIG_DISABLE_ENVIRON
|
set !CONFIG_DISABLE_ENVIRON
|
||||||
sleep !CONFIG_DISABLE_SIGNALS
|
sleep !CONFIG_DISABLE_SIGNALS
|
||||||
sh CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
|
sh CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
|
||||||
|
@ -100,6 +100,12 @@
|
|||||||
#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER
|
#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER
|
||||||
#undef CONFIG_EXAMPLES_NSH_FULLPATH
|
#undef CONFIG_EXAMPLES_NSH_FULLPATH
|
||||||
|
|
||||||
|
/* Make sure that the home directory is defined */
|
||||||
|
|
||||||
|
#ifndef CONFIG_LIB_HOMEDIR
|
||||||
|
# define CONFIG_LIB_HOMEDIR "/"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define nsh_clone(v) (v)->clone(v)
|
#define nsh_clone(v) (v)->clone(v)
|
||||||
#define nsh_addref(v) (v)->addref(v)
|
#define nsh_addref(v) (v)->addref(v)
|
||||||
#define nsh_release(v) (v)->release(v)
|
#define nsh_release(v) (v)->release(v)
|
||||||
@ -116,6 +122,13 @@
|
|||||||
|
|
||||||
#define SAVE_SIZE (sizeof(int) + sizeof(FILE*) + sizeof(boolean))
|
#define SAVE_SIZE (sizeof(int) + sizeof(FILE*) + sizeof(boolean))
|
||||||
|
|
||||||
|
/* Stubs used when working directory is not supported */
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS <= 0 || defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
# define nsh_getfullpath(v,p) (p)
|
||||||
|
# define nsh_freefullpath(p)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -211,6 +224,14 @@ extern int nsh_consolemain(int argc, char *argv[]);
|
|||||||
extern int nsh_telnetmain(int argc, char *argv[]);
|
extern int nsh_telnetmain(int argc, char *argv[]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Working directory support */
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
extern FAR const char *nsh_getcwd(void);
|
||||||
|
extern char *nsh_getfullpath(FAR struct nsh_vtbl_s *vtbl, const char *relpath);
|
||||||
|
extern void nsh_freefullpath(char *relpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Shell command handlers */
|
/* Shell command handlers */
|
||||||
|
|
||||||
extern int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
extern int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||||
@ -238,6 +259,10 @@ extern int cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
|||||||
extern int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
extern int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||||
# endif /* CONFIG_FS_FAT */
|
# endif /* CONFIG_FS_FAT */
|
||||||
# endif /* !CONFIG_DISABLE_MOUNTPOINT */
|
# endif /* !CONFIG_DISABLE_MOUNTPOINT */
|
||||||
|
# if !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
extern int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||||
|
extern int cmd_pwd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||||
|
# endif /* !CONFIG_DISABLE_MOUNTPOINT */
|
||||||
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||||
|
|
||||||
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
|
@ -42,7 +42,9 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "nsh.h"
|
#include "nsh.h"
|
||||||
@ -63,6 +65,12 @@
|
|||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
static const char g_pwd[] = "PWD";
|
||||||
|
static const char g_oldpwd[] = "OLDPWD";
|
||||||
|
static const char g_home[] = CONFIG_LIB_HOMEDIR;
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -71,10 +79,188 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_getwd
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
static inline FAR const char *nsh_getwd(const char *wd)
|
||||||
|
{
|
||||||
|
const char *val;
|
||||||
|
|
||||||
|
/* If no working directory is defined, then default to the home directory */
|
||||||
|
|
||||||
|
val = getenv(wd);
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
val = g_home;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_getdirpath
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline char *nsh_getdirpath(FAR struct nsh_vtbl_s *vtbl,
|
||||||
|
const char *dirpath, const char *relpath)
|
||||||
|
{
|
||||||
|
char *alloc;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/* Handle the special case where the dirpath is simply */
|
||||||
|
|
||||||
|
if (strcmp(dirpath, "/") == 0)
|
||||||
|
{
|
||||||
|
len = strlen(relpath) + 2;
|
||||||
|
alloc = (char*)malloc(len);
|
||||||
|
if (alloc)
|
||||||
|
{
|
||||||
|
sprintf(alloc, "/%s", relpath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = strlen(dirpath) + strlen(relpath) + 2;
|
||||||
|
alloc = (char*)malloc(len);
|
||||||
|
if (alloc)
|
||||||
|
{
|
||||||
|
sprintf(alloc, "%s/%s", dirpath, relpath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alloc)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtcmdoutofmemory, "nsh_getdirpath");
|
||||||
|
}
|
||||||
|
return alloc;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_getwd
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
FAR const char *nsh_getcwd(void)
|
||||||
|
{
|
||||||
|
return nsh_getwd(g_pwd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_getfullpath
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
char *nsh_getfullpath(FAR struct nsh_vtbl_s *vtbl, const char *relpath)
|
||||||
|
{
|
||||||
|
const char *wd;
|
||||||
|
|
||||||
|
/* Handle some special cases */
|
||||||
|
|
||||||
|
if (!relpath || relpath[0] == '\0')
|
||||||
|
{
|
||||||
|
/* No relative path provided */
|
||||||
|
|
||||||
|
return strdup(g_home);
|
||||||
|
}
|
||||||
|
else if (relpath[0] == '/')
|
||||||
|
{
|
||||||
|
return strdup(relpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the path to the current working directory */
|
||||||
|
|
||||||
|
wd = nsh_getcwd();
|
||||||
|
|
||||||
|
/* Fake the '.' directory */
|
||||||
|
|
||||||
|
if (strcmp(relpath, ".") == 0)
|
||||||
|
{
|
||||||
|
return strdup(wd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the full path */
|
||||||
|
|
||||||
|
return nsh_getdirpath(vtbl, wd, relpath);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nsh_freefullpath
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
void nsh_freefullpath(char *relpath)
|
||||||
|
{
|
||||||
|
if (relpath)
|
||||||
|
{
|
||||||
|
free(relpath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: cmd_cd
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *path = argv[1];
|
||||||
|
char *alloc = NULL;
|
||||||
|
char *fullpath = NULL;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
/* Check for special arguments */
|
||||||
|
|
||||||
|
if (argc < 2 || strcmp(path, "~") == 0)
|
||||||
|
{
|
||||||
|
path = g_home;
|
||||||
|
}
|
||||||
|
else if (strcmp(path, "-") == 0)
|
||||||
|
{
|
||||||
|
alloc = strdup(nsh_getwd(g_oldpwd));
|
||||||
|
path = alloc;
|
||||||
|
}
|
||||||
|
else if (strcmp(path, "..") == 0)
|
||||||
|
{
|
||||||
|
alloc = strdup(nsh_getcwd());
|
||||||
|
path = dirname(alloc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fullpath = nsh_getfullpath(vtbl, path);
|
||||||
|
path = fullpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the new workding directory */
|
||||||
|
|
||||||
|
if (chdir(path) != 0)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "chdir", NSH_ERRNO);
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free any memory that was allocated */
|
||||||
|
|
||||||
|
if (alloc)
|
||||||
|
{
|
||||||
|
free(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fullpath)
|
||||||
|
{
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: cmd_echo
|
* Name: cmd_echo
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -95,6 +281,18 @@ int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: cmd_pwd
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
int cmd_pwd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
|
{
|
||||||
|
nsh_output(vtbl, "%s\n", nsh_getcwd());
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: cmd_set
|
* Name: cmd_set
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -136,10 +136,10 @@ static void trim_dir(char *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: getdirpath
|
* Name: nsh_getdirpath
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static char *getdirpath(const char *path, const char *file)
|
static char *nsh_getdirpath(const char *path, const char *file)
|
||||||
{
|
{
|
||||||
/* Handle the case where all that is left is '/' */
|
/* Handle the case where all that is left is '/' */
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ 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 = getdirpath(dirpath, entryp->d_name);
|
char *fullpath = nsh_getdirpath(dirpath, entryp->d_name);
|
||||||
|
|
||||||
/* Yes, stat the file */
|
/* Yes, stat the file */
|
||||||
|
|
||||||
@ -345,7 +345,7 @@ static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct
|
|||||||
/* Yes.. */
|
/* Yes.. */
|
||||||
|
|
||||||
char *newpath;
|
char *newpath;
|
||||||
newpath = getdirpath(dirpath, entryp->d_name);
|
newpath = nsh_getdirpath(dirpath, entryp->d_name);
|
||||||
|
|
||||||
/* List the directory contents */
|
/* List the directory contents */
|
||||||
|
|
||||||
@ -375,6 +375,7 @@ static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath, struct
|
|||||||
int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
char buffer[IOBUFFERSIZE];
|
char buffer[IOBUFFERSIZE];
|
||||||
|
char *fullpath;
|
||||||
int fd;
|
int fd;
|
||||||
int i;
|
int i;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
@ -382,14 +383,18 @@ int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
/* Loop for each file name on the command line */
|
/* Loop for each file name on the command line */
|
||||||
|
|
||||||
for (i = 1; i < argc && ret == OK; i++)
|
for (i = 1; i < argc && ret == OK; i++)
|
||||||
|
{
|
||||||
|
/* Get the fullpath to the file */
|
||||||
|
|
||||||
|
fullpath = nsh_getfullpath(vtbl, argv[i]);
|
||||||
|
if (fullpath)
|
||||||
{
|
{
|
||||||
/* Open the file for reading */
|
/* Open the file for reading */
|
||||||
|
|
||||||
fd = open(argv[1], O_RDONLY);
|
fd = open(fullpath, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
|
||||||
ret = ERROR;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -450,6 +455,11 @@ int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
|
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free the allocated full path */
|
||||||
|
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -463,25 +473,42 @@ int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
char *fullpath = NULL;
|
char *srcpath = NULL;
|
||||||
const char *wrpath = argv[2];
|
char *destpath = NULL;
|
||||||
|
char *allocpath = NULL;
|
||||||
int oflags = O_WRONLY|O_CREAT|O_TRUNC;
|
int oflags = O_WRONLY|O_CREAT|O_TRUNC;
|
||||||
int rdfd;
|
int rdfd;
|
||||||
int wrfd;
|
int wrfd;
|
||||||
int ret = ERROR;
|
int ret = ERROR;
|
||||||
|
|
||||||
|
/* Get the full path to the source file */
|
||||||
|
|
||||||
|
srcpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
if (!srcpath)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the source file for reading */
|
/* Open the source file for reading */
|
||||||
|
|
||||||
rdfd = open(argv[1], O_RDONLY);
|
rdfd = open(srcpath, O_RDONLY);
|
||||||
if (rdfd < 0)
|
if (rdfd < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
|
||||||
return ERROR;
|
goto errout_with_srcpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the full path to the destination file or directory */
|
||||||
|
|
||||||
|
destpath = nsh_getfullpath(vtbl, argv[2]);
|
||||||
|
if (!destpath)
|
||||||
|
{
|
||||||
|
goto errout_with_rdfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the destination is a directory */
|
/* Check if the destination is a directory */
|
||||||
|
|
||||||
ret = stat(wrpath, &buf);
|
ret = stat(destpath, &buf);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
/* Something exists here... is it a directory? */
|
/* Something exists here... is it a directory? */
|
||||||
@ -494,15 +521,17 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
|
|
||||||
/* Construct the full path to the new file */
|
/* Construct the full path to the new file */
|
||||||
|
|
||||||
fullpath = getdirpath(argv[2], basename(argv[1]) );
|
allocpath = nsh_getdirpath(argv[2], basename(argv[1]) );
|
||||||
if (!fullpath)
|
if (!allocpath)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdoutofmemory, argv[0]);
|
nsh_output(vtbl, g_fmtcmdoutofmemory, argv[0]);
|
||||||
goto out_with_rdfd;
|
goto errout_with_destpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open then fullpath for writing */
|
/* Open then dest for writing */
|
||||||
wrpath = fullpath;
|
|
||||||
|
nsh_freefullpath(destpath);
|
||||||
|
destpath = allocpath;
|
||||||
}
|
}
|
||||||
else if (!S_ISREG(buf.st_mode))
|
else if (!S_ISREG(buf.st_mode))
|
||||||
{
|
{
|
||||||
@ -514,11 +543,11 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
|
|
||||||
/* Now open the destination */
|
/* Now open the destination */
|
||||||
|
|
||||||
wrfd = open(wrpath, oflags, 0666);
|
wrfd = open(destpath, oflags, 0666);
|
||||||
if (wrfd < 0)
|
if (wrfd < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
|
||||||
goto out_with_fullpath;
|
goto errout_with_allocpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now copy the file */
|
/* Now copy the file */
|
||||||
@ -536,14 +565,14 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
/* End of file */
|
/* End of file */
|
||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
goto out_with_wrfd;
|
goto errout_with_wrfd;
|
||||||
}
|
}
|
||||||
else if (nbytesread < 0 && errno != EINTR)
|
else if (nbytesread < 0 && errno != EINTR)
|
||||||
{
|
{
|
||||||
/* Read error */
|
/* Read error */
|
||||||
|
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
|
||||||
goto out_with_wrfd;
|
goto errout_with_wrfd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (nbytesread <= 0);
|
while (nbytesread <= 0);
|
||||||
@ -560,23 +589,36 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
/* Read error */
|
/* Read error */
|
||||||
|
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "write", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "write", NSH_ERRNO);
|
||||||
goto out_with_wrfd;
|
goto errout_with_wrfd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (nbytesread > 0);
|
while (nbytesread > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_with_wrfd:
|
errout_with_wrfd:
|
||||||
close(wrfd);
|
close(wrfd);
|
||||||
|
|
||||||
out_with_fullpath:
|
errout_with_allocpath:
|
||||||
if (fullpath)
|
if (allocpath)
|
||||||
{
|
{
|
||||||
free(fullpath);
|
free(allocpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_with_rdfd:
|
errout_with_destpath:
|
||||||
|
if (destpath && !allocpath)
|
||||||
|
{
|
||||||
|
nsh_freefullpath(destpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
errout_with_rdfd:
|
||||||
close(rdfd);
|
close(rdfd);
|
||||||
|
|
||||||
|
errout_with_srcpath:
|
||||||
|
if (srcpath)
|
||||||
|
{
|
||||||
|
nsh_freefullpath(srcpath);
|
||||||
|
}
|
||||||
|
errout:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -588,7 +630,9 @@ out_with_rdfd:
|
|||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
const char *relpath;
|
||||||
unsigned int lsflags = 0;
|
unsigned int lsflags = 0;
|
||||||
|
char *fullpath;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Get the ls options */
|
/* Get the ls options */
|
||||||
@ -617,29 +661,46 @@ int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is one required arguments after the options */
|
/* There may be one argument after the options */
|
||||||
|
|
||||||
if (optind + 1 < argc)
|
if (optind + 1 < argc)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
|
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
else if (optind + 1 > argc)
|
else if (optind >= argc)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_DISABLE_ENVIRON
|
||||||
|
relpath = nsh_getcwd();
|
||||||
|
#else
|
||||||
nsh_output(vtbl, g_fmtargrequired, argv[0]);
|
nsh_output(vtbl, g_fmtargrequired, argv[0]);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
relpath = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the fullpath to the directory */
|
||||||
|
|
||||||
|
fullpath = nsh_getfullpath(vtbl, relpath);
|
||||||
|
if (!fullpath)
|
||||||
|
{
|
||||||
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List the directory contents */
|
/* List the directory contents */
|
||||||
|
|
||||||
nsh_output(vtbl, "%s:\n", argv[optind]);
|
nsh_output(vtbl, "%s:\n", fullpath);
|
||||||
ret = foreach_direntry(vtbl, "ls", argv[optind], ls_handler, (void*)lsflags);
|
ret = foreach_direntry(vtbl, "ls", fullpath, ls_handler, (void*)lsflags);
|
||||||
if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0)
|
if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0)
|
||||||
{
|
{
|
||||||
/* Then recurse to list each directory within the directory */
|
/* Then recurse to list each directory within the directory */
|
||||||
|
|
||||||
ret = foreach_direntry(vtbl, "ls", argv[optind], ls_recursive, (void*)lsflags);
|
ret = foreach_direntry(vtbl, "ls", fullpath, ls_recursive, (void*)lsflags);
|
||||||
}
|
}
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -651,11 +712,18 @@ int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = mkdir(argv[1], 0777);
|
char *fullpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
int ret = ERROR;
|
||||||
|
|
||||||
|
if (fullpath)
|
||||||
|
{
|
||||||
|
ret = mkdir(fullpath, 0777);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkdir", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkdir", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -668,11 +736,18 @@ int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct fat_format_s fmt = FAT_FORMAT_INITIALIZER;
|
struct fat_format_s fmt = FAT_FORMAT_INITIALIZER;
|
||||||
int ret = mkfatfs(argv[1], &fmt);
|
char *fullpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
int ret = ERROR;
|
||||||
|
|
||||||
|
if (fullpath)
|
||||||
|
{
|
||||||
|
ret = mkfatfs(fullpath, &fmt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfatfs", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfatfs", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -684,11 +759,18 @@ int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = mkfifo(argv[1], 0777);
|
char *fullpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
int ret = ERROR;
|
||||||
|
|
||||||
|
if (fullpath)
|
||||||
|
{
|
||||||
|
ret = mkfifo(fullpath, 0777);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfifo", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfifo", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -701,8 +783,10 @@ int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
#ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */
|
#ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */
|
||||||
int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char *source;
|
||||||
|
char *target;
|
||||||
char *filesystem = 0;
|
char *filesystem = 0;
|
||||||
int result;
|
int ret;
|
||||||
|
|
||||||
/* Get the mount options */
|
/* Get the mount options */
|
||||||
|
|
||||||
@ -739,13 +823,34 @@ int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The source and target pathes 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 (!source)
|
||||||
|
{
|
||||||
|
nsh_freefullpath(source);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform the mount */
|
/* Perform the mount */
|
||||||
result = mount(argv[optind], argv[optind+1], filesystem, 0, NULL);
|
|
||||||
if ( result < 0)
|
ret = mount(source, target, filesystem, 0, NULL);
|
||||||
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
nsh_freefullpath(source);
|
||||||
|
nsh_freefullpath(target);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -757,11 +862,18 @@ int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = unlink(argv[1]);
|
char *fullpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (fullpath)
|
||||||
|
{
|
||||||
|
ret = unlink(fullpath);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "unlink", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "unlink", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -773,11 +885,18 @@ int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = rmdir(argv[1]);
|
char *fullpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (fullpath)
|
||||||
|
{
|
||||||
|
ret = rmdir(fullpath);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "rmdir", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "rmdir", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -789,11 +908,20 @@ int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
|
||||||
int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char *fullpath;
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
char *pret;
|
char *pret;
|
||||||
int ret = ERROR;
|
int ret = ERROR;
|
||||||
|
|
||||||
|
/* The path to the script may be relative to the current working directory */
|
||||||
|
|
||||||
|
fullpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
if (!fullpath)
|
||||||
|
{
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get a reference to the common input buffer */
|
/* Get a reference to the common input buffer */
|
||||||
|
|
||||||
buffer = nsh_linebuffer(vtbl);
|
buffer = nsh_linebuffer(vtbl);
|
||||||
@ -801,10 +929,11 @@ int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
{
|
{
|
||||||
/* Open the file containing the script */
|
/* Open the file containing the script */
|
||||||
|
|
||||||
stream = fopen(argv[1], "r");
|
stream = fopen(fullpath, "r");
|
||||||
if (!stream)
|
if (!stream)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "fopen", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "fopen", NSH_ERRNO);
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,6 +960,8 @@ int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
while (pret && ret == OK);
|
while (pret && ret == OK);
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsh_freefullpath(fullpath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -843,13 +974,21 @@ int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
|||||||
#ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */
|
#ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */
|
||||||
int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
char *fullpath = nsh_getfullpath(vtbl, argv[1]);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (fullpath)
|
||||||
|
{
|
||||||
/* Perform the umount */
|
/* Perform the umount */
|
||||||
int result = umount(argv[1]);
|
|
||||||
if (result < 0)
|
ret = umount(fullpath);
|
||||||
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "umount", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "umount", NSH_ERRNO);
|
||||||
}
|
}
|
||||||
return result;
|
nsh_freefullpath(fullpath);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,6 +91,9 @@ static const struct cmdmap_s g_cmdmap[] =
|
|||||||
{
|
{
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
{ "cat", cmd_cat, 2, NSH_MAX_ARGUMENTS, "<path> [<path> [<path> ...]]" },
|
{ "cat", cmd_cat, 2, NSH_MAX_ARGUMENTS, "<path> [<path> [<path> ...]]" },
|
||||||
|
#ifndef CONFIG_DISABLE_ENVIRON
|
||||||
|
{ "cd", cmd_cd, 1, 2, "[<dir-path>|-|~|..]" },
|
||||||
|
#endif
|
||||||
{ "cp", cmd_cp, 3, 3, "<source-path> <dest-path>" },
|
{ "cp", cmd_cp, 3, 3, "<source-path> <dest-path>" },
|
||||||
#endif
|
#endif
|
||||||
#ifndef CONFIG_DISABLE_ENVIRON
|
#ifndef CONFIG_DISABLE_ENVIRON
|
||||||
@ -105,7 +108,7 @@ static const struct cmdmap_s g_cmdmap[] =
|
|||||||
{ "ifconfig", cmd_ifconfig, 1, 1, NULL },
|
{ "ifconfig", cmd_ifconfig, 1, 1, NULL },
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
{ "ls", cmd_ls, 2, 5, "[-lRs] <dir-path>" },
|
{ "ls", cmd_ls, 1, 5, "[-lRs] <dir-path>" },
|
||||||
#endif
|
#endif
|
||||||
{ "mb", cmd_mb, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
|
{ "mb", cmd_mb, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
|
||||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
@ -123,6 +126,9 @@ static const struct cmdmap_s g_cmdmap[] =
|
|||||||
#endif
|
#endif
|
||||||
{ "mw", cmd_mw, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
|
{ "mw", cmd_mw, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
|
||||||
{ "ps", cmd_ps, 1, 1, NULL },
|
{ "ps", cmd_ps, 1, 1, NULL },
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
{ "pwd", cmd_pwd, 1, 1, NULL },
|
||||||
|
#endif
|
||||||
#ifndef CONFIG_DISABLE_ENVIRON
|
#ifndef CONFIG_DISABLE_ENVIRON
|
||||||
{ "set", cmd_set, 3, 3, "<name> <value>" },
|
{ "set", cmd_set, 3, 3, "<name> <value>" },
|
||||||
#endif
|
#endif
|
||||||
@ -132,7 +138,7 @@ static const struct cmdmap_s g_cmdmap[] =
|
|||||||
#endif
|
#endif
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
|
||||||
{ "sh", cmd_sh, 2, 2, "<script-path>" },
|
{ "sh", cmd_sh, 2, 2, "<script-path>" },
|
||||||
# endif /* CONFIG_NFILE_STREAMS */
|
#endif /* CONFIG_NFILE_DESCRIPTORS && CONFIG_NFILE_STREAMS */
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
{ "sleep", cmd_sleep, 2, 2, "<sec>" },
|
{ "sleep", cmd_sleep, 2, 2, "<sec>" },
|
||||||
#endif /* CONFIG_DISABLE_SIGNALS */
|
#endif /* CONFIG_DISABLE_SIGNALS */
|
||||||
@ -847,7 +853,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
|
|||||||
{
|
{
|
||||||
vtbl->np.np_redirect = TRUE;
|
vtbl->np.np_redirect = TRUE;
|
||||||
oflags = O_WRONLY|O_CREAT|O_TRUNC;
|
oflags = O_WRONLY|O_CREAT|O_TRUNC;
|
||||||
redirfile = argv[argc-1];
|
redirfile = nsh_getfullpath(vtbl, argv[argc-1]);
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,7 +863,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
|
|||||||
{
|
{
|
||||||
vtbl->np.np_redirect = TRUE;
|
vtbl->np.np_redirect = TRUE;
|
||||||
oflags = O_WRONLY|O_CREAT|O_APPEND;
|
oflags = O_WRONLY|O_CREAT|O_APPEND;
|
||||||
redirfile = argv[argc-1];
|
redirfile = nsh_getfullpath(vtbl, argv[argc-1]);
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -873,6 +879,9 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
fd = open(redirfile, oflags, 0666);
|
fd = open(redirfile, oflags, 0666);
|
||||||
|
nsh_freefullpath(redirfile);
|
||||||
|
redirfile = NULL;
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO);
|
nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO);
|
||||||
|
@ -57,7 +57,7 @@ STDIO_SRCS = lib_printf.c lib_rawprintf.c lib_lowprintf.c lib_dbg.c \
|
|||||||
lib_lowstream.c lib_nullstream.c lib_sscanf.c
|
lib_lowstream.c lib_nullstream.c lib_sscanf.c
|
||||||
|
|
||||||
ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
|
ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
|
||||||
STDIO_SRCS += lib_rawstream.c lib_chdir.c lib_getcwd.c lib_cwdsem.c
|
STDIO_SRCS += lib_rawstream.c
|
||||||
ifneq ($(CONFIG_NFILE_STREAMS),0)
|
ifneq ($(CONFIG_NFILE_STREAMS),0)
|
||||||
STDIO_SRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c \
|
STDIO_SRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c \
|
||||||
lib_fgetc.c lib_fgets.c lib_gets.c lib_fwrite.c lib_libfwrite.c \
|
lib_fgetc.c lib_fgets.c lib_gets.c lib_fwrite.c lib_libfwrite.c \
|
||||||
@ -72,6 +72,11 @@ STDLIB_SRCS = lib_rand.c
|
|||||||
MATH_SRCS = lib_rint.c
|
MATH_SRCS = lib_rint.c
|
||||||
|
|
||||||
UNISTD_SRCS = lib_getopt.c
|
UNISTD_SRCS = lib_getopt.c
|
||||||
|
ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
|
||||||
|
ifneq ($(CONFIG_DISABLE_ENVIRON),y)
|
||||||
|
UNISTD_SRCS += lib_chdir.c lib_getcwd.c
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
NET_SRCS = lib_htons.c lib_htonl.c lib_inetntoa.c lib_etherntoa.c
|
NET_SRCS = lib_htons.c lib_htonl.c lib_inetntoa.c lib_etherntoa.c
|
||||||
|
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -47,13 +49,35 @@
|
|||||||
|
|
||||||
#include "lib_internal.h"
|
#include "lib_internal.h"
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Variables
|
* Public Variables
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
/****************************************************************************
|
||||||
char *g_cwd = NULL;
|
* Private Functions
|
||||||
char *g_prevcwd = NULL;
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: _trimdir
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static inline void _trimdir(char *path)
|
||||||
|
{
|
||||||
|
/* Skip any trailing '/' characters (unless it is also the leading '/') */
|
||||||
|
|
||||||
|
int len = strlen(path) - 1;
|
||||||
|
while (len > 0 && path[len] == '/')
|
||||||
|
{
|
||||||
|
path[len] = '\0';
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define _trimdir(p)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@ -94,38 +118,64 @@ char *g_prevcwd = NULL;
|
|||||||
|
|
||||||
int chdir(FAR const char *path)
|
int chdir(FAR const char *path)
|
||||||
{
|
{
|
||||||
char *duppath;
|
struct stat buf;
|
||||||
|
char *oldpwd;
|
||||||
|
char *alloc;
|
||||||
|
int err;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Verify the input parameters */
|
/* Verify the input parameters */
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
{
|
{
|
||||||
errno = ENOENT;
|
err = ENOENT;
|
||||||
return ERROR;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that 'path' refers to a directory */
|
/* Verify that 'path' refers to a directory */
|
||||||
/* (To be provided) */
|
|
||||||
|
|
||||||
/* Make a persistent copy of 'path' */
|
ret = stat(path, &buf);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
err = ENOENT;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
duppath = strdup(path);
|
/* Something exists here... is it a directory? */
|
||||||
|
|
||||||
/* Free any preceding cwd and set the previous to the cwd (this
|
if (!S_ISDIR(buf.st_mode))
|
||||||
* is to support 'cd -' in NSH
|
{
|
||||||
|
err = ENOTDIR;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yes, it is a directory. Remove any trailing '/' characters from the path */
|
||||||
|
|
||||||
|
_trimdir(path);
|
||||||
|
|
||||||
|
/* Replace any preceding OLDPWD with the current PWD (this is to
|
||||||
|
* support 'cd -' in NSH)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cwd_semtake();
|
sched_lock();
|
||||||
if (g_prevcwd)
|
oldpwd = getenv("PWD");
|
||||||
|
if (!oldpwd)
|
||||||
{
|
{
|
||||||
free(g_prevcwd);
|
oldpwd = CONFIG_LIB_HOMEDIR;
|
||||||
}
|
}
|
||||||
g_prevcwd = g_cwd;
|
|
||||||
|
|
||||||
/* Set the cwd to a persistent copy of the input 'path' */
|
alloc = strdup(oldpwd); /* kludge needed because environment is realloc'ed */
|
||||||
|
setenv("OLDPWD", alloc, TRUE);
|
||||||
|
free(alloc);
|
||||||
|
|
||||||
g_cwd = duppath;
|
/* Set the cwd to the input 'path' */
|
||||||
cwd_semgive();
|
|
||||||
|
setenv("PWD", path, TRUE);
|
||||||
|
sched_unlock();
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
errno = err;
|
||||||
|
return ERROR;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
#endif /* CONFIG_NFILE_DESCRIPTORS && !CONFIG_DISABLE_ENVIRON */
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* lib/lib_cwdsem.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
|
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
|
||||||
*
|
|
||||||
* 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 <unistd.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <semaphore.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Variables
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
|
||||||
static sem_t g_cwdsem = { 1 };
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: cwd_semtake
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void cwd_semtake(void)
|
|
||||||
{
|
|
||||||
/* Take the semaphore (perhaps waiting) */
|
|
||||||
|
|
||||||
while (sem_wait(&g_cwdsem) != 0)
|
|
||||||
{
|
|
||||||
/* The only case that an error should occr here is if the wait was
|
|
||||||
* awakened by a signal.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ASSERT(errno == EINTR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: cwd_semgive
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void cwd_semgive(void)
|
|
||||||
{
|
|
||||||
/* Give the semaphore */
|
|
||||||
|
|
||||||
(void)sem_post(&g_cwdsem);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
|
@ -40,12 +40,15 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "lib_internal.h"
|
#include "lib_internal.h"
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Definitions
|
* Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -90,50 +93,38 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
|
||||||
FAR char *getcwd(FAR char *buf, size_t size)
|
FAR char *getcwd(FAR char *buf, size_t size)
|
||||||
{
|
{
|
||||||
const char *ptr;
|
char *pwd;
|
||||||
int err;
|
|
||||||
|
|
||||||
/* Verify input parameters */
|
/* Verify input parameters */
|
||||||
|
|
||||||
if (!buf || !size)
|
if (!buf || !size)
|
||||||
{
|
{
|
||||||
err = EINVAL;
|
errno = EINVAL;
|
||||||
goto errout;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no working directory is defined, then default to the home directory */
|
/* If no working directory is defined, then default to the home directory */
|
||||||
|
|
||||||
cwd_semtake();
|
pwd = getenv("PWD");
|
||||||
if (g_cwd)
|
if (!pwd)
|
||||||
{
|
{
|
||||||
ptr = g_cwd;
|
pwd = CONFIG_LIB_HOMEDIR;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr = CONFIG_LIB_HOMEDIR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that the cwd will fit into the user-provided buffer */
|
/* Verify that the cwd will fit into the user-provided buffer */
|
||||||
|
|
||||||
if (strlen(ptr) + 1 > size)
|
if (strlen(pwd) + 1 > size)
|
||||||
{
|
{
|
||||||
err = ERANGE;
|
errno = ERANGE;
|
||||||
goto errout_with_sem;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the cwd to the user buffer */
|
/* Copy the cwd to the user buffer */
|
||||||
|
|
||||||
strcpy(buf, ptr);
|
strcpy(buf, pwd);
|
||||||
cwd_semgive();
|
sched_unlock();
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
errout_with_sem:
|
|
||||||
cwd_semgive();
|
|
||||||
errout:
|
|
||||||
errno = err;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
#endif /* CONFIG_NFILE_DESCRIPTORS && !CONFIG_DISABLE_ENVIRON */
|
||||||
|
@ -102,11 +102,6 @@ struct lib_rawstream_s
|
|||||||
* Public Variables
|
* Public Variables
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
|
||||||
extern char *g_cwd; /* Defined in lib_chdir.c */
|
|
||||||
extern char *g_prevcwd; /* Defined in lib_chdir.c */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -193,9 +188,4 @@ extern void lib_give_semaphore(FAR struct file_struct *stream);
|
|||||||
|
|
||||||
extern int lib_getbase(const char *nptr, const char **endptr);
|
extern int lib_getbase(const char *nptr, const char **endptr);
|
||||||
|
|
||||||
/* Defined in lib_cwdsem.c */
|
|
||||||
|
|
||||||
extern void cwd_semtake(void);
|
|
||||||
extern void cwd_semgive(void);
|
|
||||||
|
|
||||||
#endif /* __LIB_INTERNAL_H */
|
#endif /* __LIB_INTERNAL_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user