9
0
Fork 0

Added cp command

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@303 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2007-07-01 18:23:03 +00:00
parent 0f7b6e65be
commit 616b119907
8 changed files with 218 additions and 34 deletions

View File

@ -183,7 +183,7 @@
* tools/zipme.sh: Force directory name to be nuttx-xx.yy.zz
* fs/fs_opendir.c: Correct errors in semaphore usage that can cause deadlock.
* lib/lib_getopt.c: Added getopt() support
* examples/nsh: NSH now supports cat, mount, umount, and mkdir. ls supports
* examples/nsh/: NSH now supports cat, mount, umount, and mkdir. ls supports
-l -s, and -R
* Added basic OS support to manage environment variables: environment
storage, cloning on task creation, sharing on pthread creation, destruction
@ -193,6 +193,9 @@
* Correct an error in realloc() when the block is extended "down" in memory.
In this case, the old memory contents need to be copied to the new location
and an allocated bit was not being set.
* examples/ostest: Added an environment variable test.
* examples/ostest/: Added an environment variable test.
* examples/nsh/: Break into several files.
* lib/: Added strrchr, basename, dirname
* examples/nsh/: Add cp command
* Started m68322

View File

@ -614,7 +614,7 @@ Other memory:
0.2.8 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
* tools/Makefile.mkconfig: Under Cygwin, executable has a different name
* tools/mkdeps.sh & arch/arm/src/Makefile: Corrected a problem makeing dependencies
* tools/mkdeps.sh & arch/arm/src/Makefile: Corrected a problem making dependencies
* tools/zipme.sh: Force directory name to be nuttx-xx.yy.zz
* fs/fs_opendir.c: Correct errors in semaphore usage that can cause deadlock.
* lib/lib_getopt.c: Added getopt() support
@ -631,6 +631,9 @@ Other memory:
In this case, the old memory contents need to be copied to the new location
and an allocated bit was not being set.
* examples/ostest: Added an environment variable test.
* examples/nsh/: Break into several files.
* lib/: Added strrchr, basename, dirname
* examples/nsh/: Add cp command
* Started m68322
</pre></ul>

View File

@ -1,23 +1,49 @@
examples
^^^^^^^^
examples/ostest
The examples directory contains several sample applications that
can be linked with nuttx. The specific example is selected in the
configs/<board-name>/defconfig file via the CONFIG_EXAMPLE setting.
For example,
This is the NuttX 'qualification' suite. It attempts to exercise
a broad set of OS functionality. Its coverage is not very extensive
as of this writing, but it is used to qualify each NuttX release.
CONFIG_EXAMPLE=ostest
Selects the examples/ostest example.
examples/ostest
^^^^^^^^^^^^^^^
This is the NuttX 'qualification' suite. It attempts to exercise
a broad set of OS functionality. Its coverage is not very extensive
as of this writing, but it is used to qualify each NuttX release.
The behavior of the ostest can be modified with the following
settings in the configs/<board-name>/defconfig file:
* CONFIG_OSTEST_STACKSIZE
Used to create the ostest task. Default is 8192.
examples/nsh
^^^^^^^^^^^^
This directory containst the NuttShell (NSH). This is a primitive
shell-like application. With some additional development, NSH will
someday be a great NuttX application debugger.
This directory containst the NuttShell (NSH). This is a primitive
shell-like application. With some additional development, NSH will
someday be a great NuttX application debugger.
The behavior of NSH can be modified with the following settings in
the configs/<board-name>/defconfig file:
* CONFIG_NSH_IOBUFFERSIZE
Size of a static I/O buffer used for file access (ignored if
there is no filesystem).
examples/mount
^^^^^^^^^^^^^^
This contains a simple test of filesystem mountpoints.
This contains a simple test of filesystem mountpoints.
examples/null
^^^^^^^^^^^^^
This is the do nothing application. It is only used for bringing
up new NuttX architectures
This is the do nothing application. It is only used for bringing
up new NuttX architectures

View File

@ -65,6 +65,7 @@ extern const char g_fmtcmdnotimpl[];
extern const char g_fmtnosuch[];
extern const char g_fmttoomanyargs[];
extern const char g_fmtcmdfailed[];
extern const char g_fmtcmdoutofmemory[];
/****************************************************************************
* Public Function Prototypes
@ -72,6 +73,7 @@ extern const char g_fmtcmdfailed[];
#if CONFIG_NFILE_DESCRIPTORS > 0
void cmd_cat(int argc, char **argv);
void cmd_cp(int argc, char **argv);
#endif
void cmd_exec(int argc, char **argv);
#if CONFIG_NFILE_DESCRIPTORS > 0

View File

@ -53,11 +53,9 @@
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#if 0
#include <limits.h>
#include <sched.h>
#endif
#include <libgen.h>
#include <errno.h>
#include "nsh.h"
@ -69,6 +67,25 @@
#define LSFLAGS_LONG 2
#define LSFLAGS_RECURSIVE 4
/* The size of the I/O buffer may be specified in the
* configs/<board-name>defconfig file -- provided that it is at least as
* large as PATH_MAX.
*/
#if CONFIG_NFILE_DESCRIPTORS > 0
# ifdef CONFIG_NSH_IOBUFFERSIZE
# if CONFIG_NSH_IOBUFFERSIZE > (PATH_MAX + 1)
# define IOBUFFERSIZE CONFIG_NSH_IOBUFFERSIZE
# else
# define IOBUFFERSIZE (PATH_MAX + 1)
# endif
# else
# define IOBUFFERSIZE 1024
# endif
# else
# define IOBUFFERSIZE (PATH_MAX + 1)
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@ -83,6 +100,8 @@ typedef int (*direntry_handler_t)(const char *, struct dirent *, void *);
* Private Data
****************************************************************************/
static char g_iobuffer[IOBUFFERSIZE];
/****************************************************************************
* Public Data
****************************************************************************/
@ -95,10 +114,9 @@ typedef int (*direntry_handler_t)(const char *, struct dirent *, void *);
* Name: trim_dir
****************************************************************************/
#ifdef CONFIG_FULL_PATH
static void trim_dir(char *arg)
{
/* Skip any '/' characters white space */
/* Skip any trailing '/' characters (unless it is also the leading '/') */
int len = strlen(arg) - 1;
while (len > 0 && arg[len] == '/')
@ -107,7 +125,6 @@ static void trim_dir(char *arg)
len--;
}
}
#endif
/****************************************************************************
* Name: getdirpath
@ -115,18 +132,19 @@ static void trim_dir(char *arg)
static char *getdirpath(const char *path, const char *file)
{
char buffer[PATH_MAX+1];
/* Handle the case where all that is left is '/' */
if (strcmp(path, "/") == 0)
{
sprintf(buffer, "/%s", file);
sprintf(g_iobuffer, "/%s", file);
}
else
{
sprintf(buffer, "%s/%s", path, file);
sprintf(g_iobuffer, "%s/%s", path, file);
}
buffer[PATH_MAX] = '\0';
return strdup(buffer);
g_iobuffer[PATH_MAX] = '\0';
return strdup(g_iobuffer);
}
/****************************************************************************
@ -410,6 +428,130 @@ void cmd_cat(int argc, char **argv)
}
#endif
/****************************************************************************
* Name: cmd_cp
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0
void cmd_cp(int argc, char **argv)
{
struct stat buf;
char *fullpath = NULL;
const char *wrpath = argv[2];
int oflags = O_WRONLY|O_CREAT|O_TRUNC;
int rdfd;
int wrfd;
int ret;
/* Open the source file for reading */
rdfd = open(argv[1], O_RDONLY);
if (rdfd < 0)
{
printf(g_fmtcmdfailed, argv[0], "open", strerror(errno));
return;
}
/* Check if the destination is a directory */
ret = stat(wrpath, &buf);
if (ret == 0)
{
/* Something exists here... is it a directory? */
if (S_ISDIR(buf.st_mode))
{
/* Yes, it is a directory. Remove any trailing '/' characters from the path */
trim_dir(argv[2]);
/* Construct the full path to the new file */
fullpath = getdirpath(argv[2], basename(argv[1]) );
if (!fullpath)
{
printf(g_fmtcmdoutofmemory, argv[0]);
goto out_with_rdfd;
}
/* Open then fullpath for writing */
wrpath = fullpath;
}
else if (!S_ISREG(buf.st_mode))
{
/* Maybe it is a driver? */
oflags = O_WRONLY;
}
}
/* Now open the destination */
wrfd = open(wrpath, oflags, 0666);
if (wrfd < 0)
{
printf(g_fmtcmdfailed, argv[0], "open", strerror(errno));
goto out_with_fullpath;
}
/* Now copy the file */
for (;;)
{
int nbytesread;
int nbyteswritten;
do
{
nbytesread = read(rdfd, g_iobuffer, IOBUFFERSIZE);
if (nbytesread == 0)
{
/* End of file */
goto out_with_wrfd;
}
else if (nbytesread < 0 && errno != EINTR)
{
/* Read error */
printf(g_fmtcmdfailed, argv[0], "read", strerror(errno));
goto out_with_wrfd;
}
}
while (nbytesread <= 0);
do
{
nbyteswritten = write(wrfd, g_iobuffer, nbytesread);
if (nbyteswritten >= 0)
{
nbytesread -= nbyteswritten;
}
else if (errno != EINTR)
{
/* Read error */
printf(g_fmtcmdfailed, argv[0], "write", strerror(errno));
goto out_with_wrfd;
}
}
while (nbytesread > 0);
}
out_with_wrfd:
close(wrfd);
out_with_fullpath:
if (fullpath)
{
free(fullpath);
}
out_with_rdfd:
close(rdfd);
}
#endif
/****************************************************************************
* Name: cmd_ls
****************************************************************************/

View File

@ -85,6 +85,7 @@ static const struct cmdmap_s g_cmdmap[] =
{
#if CONFIG_NFILE_DESCRIPTORS > 0
{ "cat", cmd_cat, 2, 2, "<path>" },
{ "cp", cmd_cp, 3, 3, "<source-path> <dest-path>" },
#endif
{ "echo", cmd_echo, 2, 2, "<string>" },
{ "exec", cmd_exec, 2, 3, "<hex-address>" },
@ -107,13 +108,14 @@ static const struct cmdmap_s g_cmdmap[] =
* Public Data
****************************************************************************/
const char g_fmtargrequired[] = "nsh: %s: missing required argument(s)\n";
const char g_fmtarginvalid[] = "nsh: %s: argument invalid\n";
const char g_fmtcmdnotfound[] = "nsh: %s: command not found\n";
const char g_fmtcmdnotimpl[] = "nsh: %s: command not implemented\n";
const char g_fmtnosuch[] = "nsh: %s: no such %s: %s\n";
const char g_fmttoomanyargs[] = "nsh: %s: too many arguments\n";
const char g_fmtcmdfailed[] = "nsh: %s: %s failed: %s\n";
const char g_fmtargrequired[] = "nsh: %s: missing required argument(s)\n";
const char g_fmtarginvalid[] = "nsh: %s: argument invalid\n";
const char g_fmtcmdnotfound[] = "nsh: %s: command not found\n";
const char g_fmtcmdnotimpl[] = "nsh: %s: command not implemented\n";
const char g_fmtnosuch[] = "nsh: %s: no such %s: %s\n";
const char g_fmttoomanyargs[] = "nsh: %s: too many arguments\n";
const char g_fmtcmdfailed[] = "nsh: %s: %s failed: %s\n";
const char g_fmtcmdoutofmemory[] = "nsh: %s: out of memory\n";
/****************************************************************************
* Private Functions

View File

@ -55,9 +55,15 @@
************************************************************/
#define PRIORITY 100
#define STACKSIZE 8192
#define NARGS 4
/* The task_create task size can be specified in the defconfig file */
#ifdef CONFIG_OSTEST_STACKSIZE
# define STACKSIZE CONFIG_OSTEST_STACKSIZE
#else
# define STACKSIZE 8192
#endif
/************************************************************
* Private Data
************************************************************/

View File

@ -55,7 +55,7 @@ extern "C" {
#define EXTERN extern
#endif
EXTERN char *dirname(char *path);
EXTERN char *basename(char *path);
EXTERN char *dirname(char *path);
#undef EXTERN