diff options
author | Tanguy Pruvot <tanguy.pruvot@gmail.com> | 2012-05-04 11:17:11 +0200 |
---|---|---|
committer | Tanguy Pruvot <tanguy.pruvot@gmail.com> | 2012-05-06 02:36:00 +0200 |
commit | 0ffc5b37e553f4514121d2775879a153e6ea5ecc (patch) | |
tree | e844e11ccec0969d09416b0078de65b8bc87f0e7 /toolbox | |
parent | 09a96bef654d58d5100353a1aa7239aae12d9bf3 (diff) | |
download | system_core-0ffc5b37e553f4514121d2775879a153e6ea5ecc.zip system_core-0ffc5b37e553f4514121d2775879a153e6ea5ecc.tar.gz system_core-0ffc5b37e553f4514121d2775879a153e6ea5ecc.tar.bz2 |
toolbox: implement rm -f flag
this prevent compatibility errors in scripts (file "-f" not found)
The force flag will not return an error if the file doesnt exist.
Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
Change-Id: I3267963284ee247629da5ab299e900c6e4a4ac68
Diffstat (limited to 'toolbox')
-rw-r--r-- | toolbox/rm.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/toolbox/rm.c b/toolbox/rm.c index bd66311..3a24bec 100644 --- a/toolbox/rm.c +++ b/toolbox/rm.c @@ -7,14 +7,17 @@ #include <sys/stat.h> #include <sys/types.h> +#define OPT_RECURSIVE 1 +#define OPT_FORCE 2 + static int usage() { - fprintf(stderr,"rm [-rR] <target>\n"); + fprintf(stderr,"Usage: rm [-rR] [-f] <target>\n"); return -1; } /* return -1 on failure, with errno set to the first error */ -static int unlink_recursive(const char* name) +static int unlink_recursive(const char* name, int flags) { struct stat st; DIR *dir; @@ -23,7 +26,7 @@ static int unlink_recursive(const char* name) /* is it a file or directory? */ if (lstat(name, &st) < 0) - return -1; + return ((flags & OPT_FORCE) && errno == ENOENT) ? 0 : -1; /* a file, so unlink it */ if (!S_ISDIR(st.st_mode)) @@ -41,7 +44,7 @@ static int unlink_recursive(const char* name) if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) continue; sprintf(dn, "%s/%s", name, de->d_name); - if (unlink_recursive(dn) < 0) { + if (unlink_recursive(dn, flags) < 0) { fail = 1; break; } @@ -66,21 +69,45 @@ static int unlink_recursive(const char* name) int rm_main(int argc, char *argv[]) { int ret; - int i = 1; - int recursive = 0; + int i, c; + int flags = 0; if (argc < 2) return usage(); - /* check if recursive */ - if (argc >=2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "-R"))) { - recursive = 1; - i = 2; + /* check flags */ + do { + c = getopt(argc, argv, "frR"); + if (c == EOF) + break; + switch (c) { + case 'f': + flags |= OPT_FORCE; + break; + case 'r': + case 'R': + flags |= OPT_RECURSIVE; + break; + } + } while (1); + + if (optind < 1 || optind >= argc) { + usage(); + return -1; } - + /* loop over the file/directory args */ - for (; i < argc; i++) { - int ret = recursive ? unlink_recursive(argv[i]) : unlink(argv[i]); + for (i = optind; i < argc; i++) { + + if (flags & OPT_RECURSIVE) { + ret = unlink_recursive(argv[i], flags); + } else { + ret = unlink(argv[i]); + if (errno == ENOENT && (flags & OPT_FORCE)) { + return 0; + } + } + if (ret < 0) { fprintf(stderr, "rm failed for %s, %s\n", argv[i], strerror(errno)); return -1; |