From aaf4e9d480397627f54ca37dd93cd0f054b2883a Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Mon, 4 Mar 2024 14:47:30 +0800 Subject: [PATCH] nshlib: Support "-f" option for command "rm" In below two cases "rm" command with "-f" option will return 0: a. Bad arguments b. File not exists Following "rm" of GNU coreutils 8.32 GNU coreutils $ rm --version rm (GNU coreutils) 8.32 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Paul Rubin, David MacKenzie, Richard M. Stallman, and Jim Meyering. $ rm /FILE_NOT_EXISTS rm: cannot remove '/FILE_NOT_EXISTS': No such file or directory $ echo $? 1 $ rm -f $ echo $? 0 $ rm -f /FILE_NOT_EXISTS $ echo $? 0 Without this patch nsh> rm nsh: rm: missing required argument(s) nsh> rm /FILE_NOT_EXISTS nsh: rm: unlink failed: 2 nsh> echo $? 1 With this patch nsh> rm -f nsh> echo $? 0 nsh> rm -f /FILE_NOT_EXISTS nsh> echo $? 0 Signed-off-by: wangjianyu3 --- nshlib/nsh_command.c | 2 +- nshlib/nsh_fscmds.c | 43 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index d15b15a2c..dce82ef0c 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -505,7 +505,7 @@ static const struct cmdmap_s g_cmdmap[] = #ifdef NSH_HAVE_DIROPTS # ifndef CONFIG_NSH_DISABLE_RM - CMD_MAP("rm", cmd_rm, 2, 3, "[-r] "), + CMD_MAP("rm", cmd_rm, 2, 3, "[-rf] "), # endif #endif diff --git a/nshlib/nsh_fscmds.c b/nshlib/nsh_fscmds.c index e9adaaa45..e435ef310 100644 --- a/nshlib/nsh_fscmds.c +++ b/nshlib/nsh_fscmds.c @@ -2178,20 +2178,48 @@ static int unlink_recursive(FAR char *path, FAR struct stat *stat) int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { - bool recursive = (strcmp(argv[1], "-r") == 0); + bool recursive = false; + bool force = false; FAR char *fullpath; char buf[PATH_MAX]; struct stat stat; int ret = ERROR; + int c; - if (recursive && argc == 2) + while ((c = getopt(argc, argv, "rf")) != ERROR) { - nsh_error(vtbl, g_fmtargrequired, argv[0]); + switch (c) + { + case 'r': + recursive = true; + break; + case 'f': + force = true; + break; + case '?': + nsh_output(vtbl, "Unknown option 0x%x\n", optopt); + return ret; + default: + nsh_error(vtbl, g_fmtargrequired, argv[0]); + return ret; + } + } + + if (optind >= argc) + { + if (force) + { + ret = OK; + } + else + { + nsh_error(vtbl, g_fmtargrequired, argv[0]); + } + return ret; } - fullpath = nsh_getfullpath(vtbl, recursive ? argv[2] : argv[1]); - + fullpath = nsh_getfullpath(vtbl, argv[optind]); if (fullpath != NULL) { if (recursive) @@ -2204,6 +2232,11 @@ int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) ret = unlink(fullpath); } + if (force && errno == ENOENT) + { + ret = 0; + } + if (ret < 0) { nsh_error(vtbl, g_fmtcmdfailed, argv[0], "unlink", NSH_ERRNO);