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:
patacongo
2008-08-23 15:16:10 +00:00
parent c7419e57d3
commit 3f2dfbb298
12 changed files with 593 additions and 264 deletions
+2
View File
@@ -420,5 +420,7 @@
* 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.
+5 -1
View File
@@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<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>
</tr>
</table>
@@ -1052,6 +1052,10 @@ nuttx-0.3.13 2008-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* NSH now supports commands to inspect and modify memory
* NSH cat command now supports multiple files on command line
* 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 &lt;spudmonkey@racsa.co.cr&gt;
+2
View File
@@ -38,6 +38,7 @@ examples/nsh
Command Depends on Configuration
---------- --------------------------
cat CONFIG_NFILE_DESCRIPTORS > 0
cd !CONFIG_DISABLE_ENVIRON && CONFIG_NFILE_DESCRIPTORS > 0
cp CONFIG_NFILE_DESCRIPTORS > 0
echo --
exec --
@@ -51,6 +52,7 @@ examples/nsh
mkfifo !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0
mount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_FAT
ps --
pwd !CONFIG_DISABLE_ENVIRON && CONFIG_NFILE_DESCRIPTORS > 0
set !CONFIG_DISABLE_ENVIRON
sleep !CONFIG_DISABLE_SIGNALS
sh CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
+25
View File
@@ -100,6 +100,12 @@
#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER
#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_addref(v) (v)->addref(v)
#define nsh_release(v) (v)->release(v)
@@ -116,6 +122,13 @@
#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
****************************************************************************/
@@ -211,6 +224,14 @@ extern int nsh_consolemain(int argc, char *argv[]);
extern int nsh_telnetmain(int argc, char *argv[]);
#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 */
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);
# endif /* CONFIG_FS_FAT */
# 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 */
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+198
View File
@@ -42,7 +42,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libgen.h>
#include <errno.h>
#include "nsh.h"
@@ -63,6 +65,12 @@
* 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
****************************************************************************/
@@ -71,10 +79,188 @@
* 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
****************************************************************************/
/****************************************************************************
* 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
****************************************************************************/
@@ -95,6 +281,18 @@ int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
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
****************************************************************************/
+246 -107
View File
File diff suppressed because it is too large Load Diff
+13 -4
View File
@@ -91,6 +91,9 @@ static const struct cmdmap_s g_cmdmap[] =
{
#if CONFIG_NFILE_DESCRIPTORS > 0
{ "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>" },
#endif
#ifndef CONFIG_DISABLE_ENVIRON
@@ -105,7 +108,7 @@ static const struct cmdmap_s g_cmdmap[] =
{ "ifconfig", cmd_ifconfig, 1, 1, NULL },
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0
{ "ls", cmd_ls, 2, 5, "[-lRs] <dir-path>" },
{ "ls", cmd_ls, 1, 5, "[-lRs] <dir-path>" },
#endif
{ "mb", cmd_mb, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
@@ -123,6 +126,9 @@ static const struct cmdmap_s g_cmdmap[] =
#endif
{ "mw", cmd_mw, 2, 3, "<hex-address>[=<hex-value>][ <hex-byte-count>]" },
{ "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
{ "set", cmd_set, 3, 3, "<name> <value>" },
#endif
@@ -132,7 +138,7 @@ static const struct cmdmap_s g_cmdmap[] =
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
{ "sh", cmd_sh, 2, 2, "<script-path>" },
# endif /* CONFIG_NFILE_STREAMS */
#endif /* CONFIG_NFILE_DESCRIPTORS && CONFIG_NFILE_STREAMS */
#ifndef CONFIG_DISABLE_SIGNALS
{ "sleep", cmd_sleep, 2, 2, "<sec>" },
#endif /* CONFIG_DISABLE_SIGNALS */
@@ -847,7 +853,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
{
vtbl->np.np_redirect = TRUE;
oflags = O_WRONLY|O_CREAT|O_TRUNC;
redirfile = argv[argc-1];
redirfile = nsh_getfullpath(vtbl, argv[argc-1]);
argc -= 2;
}
@@ -857,7 +863,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
{
vtbl->np.np_redirect = TRUE;
oflags = O_WRONLY|O_CREAT|O_APPEND;
redirfile = argv[argc-1];
redirfile = nsh_getfullpath(vtbl, argv[argc-1]);
argc -= 2;
}
}
@@ -873,6 +879,9 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
*/
fd = open(redirfile, oflags, 0666);
nsh_freefullpath(redirfile);
redirfile = NULL;
if (fd < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO);
+6 -1
View File
@@ -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
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)
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 \
@@ -72,6 +72,11 @@ STDLIB_SRCS = lib_rand.c
MATH_SRCS = lib_rint.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
+69 -19
View File
@@ -40,6 +40,8 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -47,13 +49,35 @@
#include "lib_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
/****************************************************************************
* Public Variables
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
char *g_cwd = NULL;
char *g_prevcwd = NULL;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* 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
@@ -94,38 +118,64 @@ char *g_prevcwd = NULL;
int chdir(FAR const char *path)
{
char *duppath;
struct stat buf;
char *oldpwd;
char *alloc;
int err;
int ret;
/* Verify the input parameters */
if (!path)
{
errno = ENOENT;
return ERROR;
err = ENOENT;
goto errout;
}
/* 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
* is to support 'cd -' in NSH
if (!S_ISDIR(buf.st_mode))
{
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();
if (g_prevcwd)
sched_lock();
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;
cwd_semgive();
/* Set the cwd to the input 'path' */
setenv("PWD", path, TRUE);
sched_unlock();
return OK;
errout:
errno = err;
return ERROR;
}
#endif /* CONFIG_NFILE_DESCRIPTORS */
#endif /* CONFIG_NFILE_DESCRIPTORS && !CONFIG_DISABLE_ENVIRON */
-86
View File
@@ -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 */
+27 -36
View File
@@ -40,12 +40,15 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "lib_internal.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
/****************************************************************************
* Definitions
****************************************************************************/
@@ -90,50 +93,38 @@
*
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
FAR char *getcwd(FAR char *buf, size_t size)
{
const char *ptr;
int err;
char *pwd;
/* Verify input parameters */
/* Verify input parameters */
if (!buf || !size)
{
err = EINVAL;
goto errout;
}
if (!buf || !size)
{
errno = EINVAL;
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();
if (g_cwd)
{
ptr = g_cwd;
}
else
{
ptr = CONFIG_LIB_HOMEDIR;
}
pwd = getenv("PWD");
if (!pwd)
{
pwd = 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)
{
err = ERANGE;
goto errout_with_sem;
}
if (strlen(pwd) + 1 > size)
{
errno = ERANGE;
return NULL;
}
/* Copy the cwd to the user buffer */
/* Copy the cwd to the user buffer */
strcpy(buf, ptr);
cwd_semgive();
return buf;
errout_with_sem:
cwd_semgive();
errout:
errno = err;
return NULL;
strcpy(buf, pwd);
sched_unlock();
return buf;
}
#endif /* CONFIG_NFILE_DESCRIPTORS */
#endif /* CONFIG_NFILE_DESCRIPTORS && !CONFIG_DISABLE_ENVIRON */
-10
View File
@@ -102,11 +102,6 @@ struct lib_rawstream_s
* 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
****************************************************************************/
@@ -193,9 +188,4 @@ extern void lib_give_semaphore(FAR struct file_struct *stream);
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 */