[klibc] [PATCH] simple rm command

Olaf Hering olh at suse.de
Sun Sep 5 21:16:20 PDT 2004


'rm -rf /' for klibc
Doesnt comply to the standard, but does the job.
http://www.opengroup.org/onlinepubs/009695399/utilities/rm.html


diff -p -purN klibc-0.172/utils/Makefile klibc-0.172.rm/utils/Makefile
--- klibc-0.172/utils/Makefile	2004-08-14 00:24:20.000000000 +0200
+++ klibc-0.172.rm/utils/Makefile	2004-09-05 20:11:14.109062216 +0200
@@ -6,7 +6,7 @@ MAKEDEPS     = -Wp,-MD,.$(subst /,-,$*).
 CFLAGS       = $(MAKEDEPS) $(OPTFLAGS) $(REQFLAGS) -W -Wall
 LIBS         = $(KLIBC) $(LIBGCC)
 PROGS       := chroot dd fstype mkdir mkfifo mount pivot_root umount \
-	       true false sleep ln nuke minips run-init printf
+	       true false sleep ln nuke minips run-init printf rm
 STATICPROGS := $(patsubst %,static/%,$(PROGS))
 SHAREDPROGS := $(patsubst %,shared/%,$(PROGS))
 LIBOBJS	     = file_mode.o
diff -p -purN klibc-0.172/utils/rm.c klibc-0.172.rm/utils/rm.c
--- klibc-0.172/utils/rm.c	1970-01-01 01:00:00.000000000 +0100
+++ klibc-0.172.rm/utils/rm.c	2004-09-05 20:03:37.483695000 +0200
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <linux/limits.h>
+
+static char *progname;
+static int f_opt, r_opt;
+
+static int recursive_rm(const char *path);
+
+static int unlink_direntry(const char *p)
+{
+	struct stat sb;
+	int ret;
+
+	if (lstat(p, &sb) < 0) {
+		ret = 1;
+		if (!f_opt)
+			perror(p);
+		goto out;
+	}
+
+	if (S_ISDIR(sb.st_mode) && r_opt)
+		ret = recursive_rm(p);
+	else {
+		if (unlink(p) < 0) {
+			ret = 1;
+			if (!f_opt)
+				perror(p);
+		} else
+			ret = 0;
+	}
+
+      out:
+	return ret;
+}
+static int recursive_rm(const char *p)
+{
+	DIR *d;
+	struct dirent *de;
+	char path[PATH_MAX];
+	int i, ret;
+
+	d = opendir(p);
+	if (!d)
+		return 1;
+	ret = 0;
+	while ((de = readdir(d)) != NULL) {
+		if (de->d_name[0] == '.' &&
+		    (de->d_name[1] == '\0' ||
+		     (de->d_name[1] == '.' && de->d_name[2] == '\0')))
+			continue;
+		i = snprintf(path, PATH_MAX - 1, "%s/%s", p, de->d_name);
+		if (i >= PATH_MAX - 1) {
+			fprintf(stderr, "%s/%s: pathname too long (%d/%d)\n",
+				p, de->d_name, PATH_MAX, i);
+			ret = 1;
+			continue;
+		}
+		path[i] = '\0';
+		ret |= unlink_direntry(path);
+	}
+	closedir(d);
+	if (rmdir(p) < 0) {
+		ret = 1;
+		if (!f_opt)
+			perror(p);
+	}
+	return ret;
+}
+
+int main(int argc, char *argv[])
+{
+	int c, ret;
+	const char *p;
+
+	progname = argv[0];
+	ret = 0;
+	do {
+		c = getopt(argc, argv, "rf");
+		if (c == EOF)
+			break;
+
+		switch (c) {
+
+		case 'r':
+			r_opt = 1;
+			break;
+		case 'f':
+			f_opt = 1;
+			break;
+		case '?':
+			fprintf(stderr, "%s: invalid option -%c\n",
+				progname, optopt);
+			return 1;
+		}
+
+	} while (1);
+
+	if (optind == argc) {
+		fprintf(stderr, "Usage: %s [-r] [-f] target\n", progname);
+		return 1;
+	}
+
+	for (c = optind; c < argc; c++) {
+		p = argv[c];
+		ret |= unlink_direntry(p);
+	}
+
+	return f_opt ? 0 : !!ret;
+}
-- 
USB is for mice, FireWire is for men!

sUse lINUX ag, nÜRNBERG



More information about the klibc mailing list