OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / system / core / toolbox / rm.c
diff --git a/system/core/toolbox/rm.c b/system/core/toolbox/rm.c
new file mode 100644 (file)
index 0000000..bd66311
--- /dev/null
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+static int usage()
+{
+    fprintf(stderr,"rm [-rR] <target>\n");
+    return -1;
+}
+
+/* return -1 on failure, with errno set to the first error */
+static int unlink_recursive(const char* name)
+{
+    struct stat st;
+    DIR *dir;
+    struct dirent *de;
+    int fail = 0;
+
+    /* is it a file or directory? */
+    if (lstat(name, &st) < 0)
+        return -1;
+
+    /* a file, so unlink it */
+    if (!S_ISDIR(st.st_mode))
+        return unlink(name);
+
+    /* a directory, so open handle */
+    dir = opendir(name);
+    if (dir == NULL)
+        return -1;
+
+    /* recurse over components */
+    errno = 0;
+    while ((de = readdir(dir)) != NULL) {
+        char dn[PATH_MAX];
+        if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, "."))
+            continue;
+        sprintf(dn, "%s/%s", name, de->d_name);
+        if (unlink_recursive(dn) < 0) {
+            fail = 1;
+            break;
+        }
+        errno = 0;
+    }
+    /* in case readdir or unlink_recursive failed */
+    if (fail || errno < 0) {
+        int save = errno;
+        closedir(dir);
+        errno = save;
+        return -1;
+    }
+
+    /* close directory handle */
+    if (closedir(dir) < 0)
+        return -1;
+
+    /* delete target directory */
+    return rmdir(name);
+}
+
+int rm_main(int argc, char *argv[])
+{
+    int ret;
+    int i = 1;
+    int recursive = 0;
+
+    if (argc < 2)
+        return usage();
+
+    /* check if recursive */
+    if (argc >=2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "-R"))) {
+        recursive = 1;
+        i = 2;
+    }
+    
+    /* loop over the file/directory args */
+    for (; i < argc; i++) {
+        int ret = recursive ? unlink_recursive(argv[i]) : unlink(argv[i]);
+        if (ret < 0) {
+            fprintf(stderr, "rm failed for %s, %s\n", argv[i], strerror(errno));
+            return -1;
+        }
+    }
+
+    return 0;
+}
+