diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-07-01 18:23:03 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-07-01 18:23:03 +0000 |
commit | 5f2d898113f8991a6894c4db2133115cfbbe3c05 (patch) | |
tree | 347f2a879c2b5d4f85cf6e72487fd6747a337051 /nuttx/examples/nsh | |
parent | 11b7dc40770900fc7ddf42cac56822108aea571c (diff) | |
download | px4-nuttx-5f2d898113f8991a6894c4db2133115cfbbe3c05.tar.gz px4-nuttx-5f2d898113f8991a6894c4db2133115cfbbe3c05.tar.bz2 px4-nuttx-5f2d898113f8991a6894c4db2133115cfbbe3c05.zip |
Added cp command
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@303 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/examples/nsh')
-rw-r--r-- | nuttx/examples/nsh/nsh.h | 2 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_fscmds.c | 166 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_main.c | 16 |
3 files changed, 165 insertions, 19 deletions
diff --git a/nuttx/examples/nsh/nsh.h b/nuttx/examples/nsh/nsh.h index 09f58e8bb..521a935fe 100644 --- a/nuttx/examples/nsh/nsh.h +++ b/nuttx/examples/nsh/nsh.h @@ -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 diff --git a/nuttx/examples/nsh/nsh_fscmds.c b/nuttx/examples/nsh/nsh_fscmds.c index c95b3e121..f8f95d39c 100644 --- a/nuttx/examples/nsh/nsh_fscmds.c +++ b/nuttx/examples/nsh/nsh_fscmds.c @@ -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); } /**************************************************************************** @@ -411,6 +429,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 ****************************************************************************/ diff --git a/nuttx/examples/nsh/nsh_main.c b/nuttx/examples/nsh/nsh_main.c index 4ddb91ece..774a7d368 100644 --- a/nuttx/examples/nsh/nsh_main.c +++ b/nuttx/examples/nsh/nsh_main.c @@ -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 |