diff --git a/nshlib/Kconfig b/nshlib/Kconfig index c4795d107..90a5ffeeb 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -491,6 +491,10 @@ config NSH_DISABLE_TELNETD default n if !NSH_NETLOCAL default y if NSH_NETLOCAL +config NSH_DISABLE_TRUNCATE + bool "Disable truncate" + default y + config NSH_DISABLE_UMOUNT bool "Disable umount" default n diff --git a/nshlib/README.txt b/nshlib/README.txt index 1acf2e490..afa6285ec 100644 --- a/nshlib/README.txt +++ b/nshlib/README.txt @@ -1145,6 +1145,34 @@ o time "" nsh> 2.0100 sec +o truncate -s + + Shrink or extend the size of the regular file at to the + specified . + + A argument that does not exist is created. The + option is NOT optional. + + If a is larger than the specified size, the extra data is + lost. If a is shorter, it is extended and the extended part + reads as zero bytes. + +o umount + + Un-mount the file system at mount point . The umount command + can only be used to un-mount volumes previously mounted using mount + command. + + Example: + nsh> ls /mnt/fs + /mnt/fs: + TESTDIR/ + nsh> umount /mnt/fs + nsh> ls /mnt/fs + /mnt/fs: + nsh: ls: no such directory: /mnt/fs + nsh> + o unset Remove the value associated with the environment variable @@ -1330,6 +1358,7 @@ Command Dependencies on Configuration Settings test !CONFIG_NSH_DISABLESCRIPT telnetd CONFIG_NSH_TELNET && !CONFIG_NSH_DISABLE_TELNETD time --- + truncate !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 umount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_READABLE uname !CONFIG_NSH_DISABLE_UNAME unset !CONFIG_DISABLE_ENVIRON @@ -1374,9 +1403,10 @@ also allow it to squeeze into very small memory footprints. CONFIG_NSH_DISABLE_RM, CONFIG_NSH_DISABLE_RMDIR, CONFIG_NSH_DISABLE_ROUTE, CONFIG_NSH_DISABLE_SET, CONFIG_NSH_DISABLE_SH, CONFIG_NSH_DISABLE_SHUTDOWN, CONFIG_NSH_DISABLE_SLEEP, CONFIG_NSH_DISABLE_TEST, CONFIG_NSH_DIABLE_TIME, - CONFIG_NSH_DISABLE_UMOUNT, CONFIG_NSH_DISABLE_UNSET, CONFIG_NSH_DISABLE_URLDECODE, - CONFIG_NSH_DISABLE_URLENCODE, CONFIG_NSH_DISABLE_USERADD, CONFIG_NSH_DISABLE_USERDEL, - CONFIG_NSH_DISABLE_USLEEP, CONFIG_NSH_DISABLE_WGET, CONFIG_NSH_DISABLE_XD + CONFIG_NSH_DISABLE_TRUNCATE, CONFIG_NSH_DISABLE_UMOUNT, CONFIG_NSH_DISABLE_UNSET, + CONFIG_NSH_DISABLE_URLDECODE, CONFIG_NSH_DISABLE_URLENCODE, CONFIG_NSH_DISABLE_USERADD, + CONFIG_NSH_DISABLE_USERDEL, CONFIG_NSH_DISABLE_USLEEP, CONFIG_NSH_DISABLE_WGET, + CONFIG_NSH_DISABLE_XD Verbose help output can be suppressed by defining CONFIG_NSH_HELP_TERSE. In that case, the help command is still available but will be slightly smaller. diff --git a/nshlib/nsh.h b/nshlib/nsh.h index acbdeb8a4..c09313034 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh.h * - * Copyright (C) 2007-2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -1141,6 +1141,9 @@ int cmd_lsmod(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); int cmd_mksmartfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); # endif # endif /* CONFIG_FS_SMARTFS */ +# ifndef CONFIG_NSH_DISABLE_TRUNCATE + int cmd_truncate(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +# endif # if defined(CONFIG_NSH_LOGIN_PASSWD) && defined(CONFIG_FS_WRITABLE) && \ !defined(CONFIG_FSUTILS_PASSWD_READONLY) # ifndef CONFIG_NSH_DISABLE_USERADD diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 07e003bb8..f9d3ac559 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh_command.c * - * Copyright (C) 2007-2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -489,6 +489,12 @@ static const struct cmdmap_s g_cmdmap[] = { "true", cmd_true, 1, 1, NULL }, #endif +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 +# ifndef CONFIG_NSH_DISABLE_TRUNCATE + { "truncate", cmd_truncate, 4, 4, "-s " }, +# endif +#endif + #ifndef CONFIG_NSH_DISABLE_UNAME #ifdef CONFIG_NET { "uname", cmd_uname, 1, 7, "[-a | -imnoprsv]" }, diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index 662e4a52c..fe60d9d75 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -1,7 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_fscmds.c * - * Copyright (C) 2007-2009, 2011-2014, 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2014, 2017-2018 Gregory Nutt. All rights + * reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -1776,3 +1777,95 @@ errout: } #endif #endif + +/**************************************************************************** + * Name: cmd_truncate + ****************************************************************************/ + +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 +#ifndef CONFIG_NSH_DISABLE_TRUNCATE +int cmd_truncate(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + FAR char *fullpath; + FAR char *endptr; + struct stat buf; + unsigned long length; + int ret; + + /* truncate -s */ + + if (strcmp(argv[1], "-s") != 0) + { + nsh_output(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + length = strtoul(argv[2], &endptr, 0); + if (*endptr != '\0') + { + nsh_output(vtbl, g_fmtarginvalid, argv[0]); + return ERROR; + } + + /* Get the full path to the file */ + + fullpath = nsh_getfullpath(vtbl, argv[3]); + if (fullpath == NULL) + { + nsh_output(vtbl, g_fmtcmdoutofmemory, argv[0]); + return ERROR; + } + + /* stat the file */ + + ret = stat(fullpath, &buf); + if (ret < 0) + { + int errval = errno; + + /* If stat() failed because the file does not exist, then try to + * create it. + */ + + if (errval == ENOENT) + { + int fd = creat(fullpath, 0666); + if (fd < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "stat", NSH_ERRNO); + ret = ERROR; + goto errout_with_fullpath; + } + + close(fd); + } + else + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "stat", + NSH_ERRNO_OF(errval)); + ret = ERROR; + goto errout_with_fullpath; + } + } + else if (!S_ISREG(buf.st_mode)) + { + nsh_output(vtbl, g_fmtarginvalid, argv[0]); + ret = ERROR; + goto errout_with_fullpath; + } + + /* Everything looks good... perform the truncation */ + + ret = truncate(fullpath, length); + if (ret < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "truncate", NSH_ERRNO); + } + +errout_with_fullpath: + nsh_freefullpath(fullpath); + return ret; +} +#endif +#endif +