From 740b528199ddd94db22ba287f41a784b4b3d7fac Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 13 Feb 2017 14:08:19 -0600 Subject: [PATCH] apps/examples/stat: Add a simple test for stat(), fstat(), and statfs(). --- examples/README.txt | 6 ++ examples/stat/.gitignore | 11 ++ examples/stat/Kconfig | 30 ++++++ examples/stat/Make.defs | 39 +++++++ examples/stat/Makefile | 56 ++++++++++ examples/stat/stat_main.c | 209 ++++++++++++++++++++++++++++++++++++++ nshlib/nsh_fscmds.c | 4 +- 7 files changed, 353 insertions(+), 2 deletions(-) create mode 100644 examples/stat/.gitignore create mode 100644 examples/stat/Kconfig create mode 100644 examples/stat/Make.defs create mode 100644 examples/stat/Makefile create mode 100644 examples/stat/stat_main.c diff --git a/examples/README.txt b/examples/README.txt index f5e8febe5..e5e48b20a 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1915,6 +1915,12 @@ examples/sotest LDMODULEFLAGS = -r -e module_initialize -T$(TOPDIR)/libc/modlib/gnu-elf.ld +examples/stat +^^^^^^^^^^^^^ + + A simple test of stat(), fstat(), and statfs(). This is useful primarily for + bringing up a new file system and verifying the correctness of these operations. + examples/system ^^^^^^^^^^^^^^^ diff --git a/examples/stat/.gitignore b/examples/stat/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/examples/stat/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/examples/stat/Kconfig b/examples/stat/Kconfig new file mode 100644 index 000000000..a3364fc01 --- /dev/null +++ b/examples/stat/Kconfig @@ -0,0 +1,30 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_STAT + bool "Test of stat(), fstat(), and statfs()" + default n + ---help--- + Enable the test of stat(), fstat(), and statfs(). + +if EXAMPLES_STAT + +config EXAMPLES_STAT_PROGNAME + string "Program name" + default "stat" + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +config EXAMPLES_STAT_PRIORITY + int "Stat task priority" + default 100 + +config EXAMPLES_STAT_STACKSIZE + int "Stat stack size" + default 2048 + +endif diff --git a/examples/stat/Make.defs b/examples/stat/Make.defs new file mode 100644 index 000000000..8deb74e67 --- /dev/null +++ b/examples/stat/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/stat/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +ifeq ($(CONFIG_EXAMPLES_STAT),y) +CONFIGURED_APPS += examples/stat +endif diff --git a/examples/stat/Makefile b/examples/stat/Makefile new file mode 100644 index 000000000..34a6f4465 --- /dev/null +++ b/examples/stat/Makefile @@ -0,0 +1,56 @@ +############################################################################ +# apps/examples/stat/Makefile +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +# Stat built-in application info + +CONFIG_EXAMPLES_STAT_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_EXAMPLES_STAT_STACKSIZE ?= 2048 + +APPNAME = stat +PRIORITY = $(CONFIG_EXAMPLES_STAT_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_STAT_STACKSIZE) + +# Stat test + +ASRCS = +CSRCS = +MAINSRC = stat_main.c + +CONFIG_EXAMPLES_STAT_PROGNAME ?= stat$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_STAT_PROGNAME) + +include $(APPDIR)/Application.mk diff --git a/examples/stat/stat_main.c b/examples/stat/stat_main.c new file mode 100644 index 000000000..98518be36 --- /dev/null +++ b/examples/stat/stat_main.c @@ -0,0 +1,209 @@ +/**************************************************************************** + * examples/stat/stat_main.c + * + * Copyright (C) 2008, 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void dump_stat(FAR struct stat *buf) +{ + FAR const char *typename; + + if (S_ISLNK(buf->st_mode)) + { + typename = "Link"; + } + else if (S_ISCHR(buf->st_mode)) + { + typename = "Character driver"; + } + else if (S_ISDIR(buf->st_mode)) + { + typename = "Directory"; + } + else if (S_ISBLK(buf->st_mode)) + { + typename = "Block driver"; + } + else if (S_ISREG(buf->st_mode)) + { + typename = "Regular file"; + } + else if (S_ISMQ(buf->st_mode)) + { + typename = "Message queue"; + } + else if (S_ISSEM(buf->st_mode)) + { + typename = "Named semaphore"; + } + else if (S_ISSHM(buf->st_mode)) + { + typename = "Shared memory"; + } + else + { + typename = "Unknown file type"; + } + + printf("stat:\n"); + printf(" st_mode: %04x\n", buf->st_mode); + printf(" %s\n", typename); + printf(" st_size: %llu\n", (unsigned long long)buf->st_size); + printf(" st_blksize: %lu\n", (unsigned long)buf->st_blksize); + printf(" st_blocks: %lu\n", (unsigned long)buf->st_blocks); + printf(" st_atime: %08lx\n", (unsigned long)buf->st_atime); + printf(" st_mtime: %08lx\n", (unsigned long)buf->st_mtime); + printf(" st_ctime: %08lx\n", (unsigned long)buf->st_ctime); +} + +static void dump_statfs(FAR struct statfs *buf) +{ + printf("statfs:\n"); + printf(" f_type: %lu\n", (unsigned long)buf->f_type); + printf(" f_namelen: %lu\n", (unsigned long)buf->f_namelen); + printf(" f_bsize: %lu\n", (unsigned long)buf->f_bsize); + printf(" f_blocks: %llu\n", (unsigned long long)buf->f_blocks); + printf(" f_bfree: %llu\n", (unsigned long long)buf->f_bfree); + printf(" f_bavail: %llu\n", (unsigned long long)buf->f_bavail); + printf(" f_files: %llu\n", (unsigned long long)buf->f_files); + printf(" f_ffree: %llu\n", (unsigned long long)buf->f_ffree); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * stat_main + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int stat_main(int argc, char *argv[]) +#endif +{ + FAR const char *path; + struct stat statbuf; + struct statfs statfsbuf; + bool isreg; + int ret; + + /* Argument is expected... the path to the file to test */ + + if (argc != 2) + { + fprintf(stderr, + "ERROR: Invalid number of arguments: %d (expected 2)\n", + argc); + return EXIT_FAILURE; + } + + path = argv[1]; + printf("Testing path: \"%s\"\n", path); + + /* Try stat first */ + + ret = stat(path, &statbuf); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, + "ERROR: stat(%s) failed: %d\n", + path, errcode); + return EXIT_FAILURE; + } + + dump_stat(&statbuf); + isreg = S_ISREG(statbuf.st_mode); + + /* Try statfs */ + + ret = statfs(path, &statfsbuf); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, + "ERROR: statfs(%s) failed: %d\n", + path, errcode); + } + + dump_statfs(&statfsbuf); + + /* Try fstat (only if it is a regular file) */ + + if (isreg) + { + int fd = open(path, O_RDONLY); + if (fd < 0) + { + int errcode = errno; + fprintf(stderr, + "ERROR: open(%s) failed: %d\n", + path, errcode); + return EXIT_FAILURE; + } + + ret = fstat(fd, &statbuf); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, + "ERROR: statfs(%s) failed: %d\n", + path, errcode); + } + else + { + dump_stat(&statbuf); + } + + close(fd); + } + + return 0; +} diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index a175c60ac..1d9d55c8a 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -530,11 +530,11 @@ int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { /* Yes, it is a directory. Remove any trailing '/' characters from the path */ - nsh_trimdir(argv[2]); + nsh_trimdir(destpath); /* Construct the full path to the new file */ - allocpath = nsh_getdirpath(vtbl, argv[2], basename(argv[1]) ); + allocpath = nsh_getdirpath(vtbl, destpath, basename(argv[1]) ); if (!allocpath) { nsh_output(vtbl, g_fmtcmdoutofmemory, argv[0]);