svn commit: trunk/busybox/coreutils

aldot at busybox.net aldot at busybox.net
Wed Apr 4 14:01:24 UTC 2007


Author: aldot
Date: 2007-04-04 07:01:23 -0700 (Wed, 04 Apr 2007)
New Revision: 18322

Log:
- remove bss users. Shrinkage while at it. See XXX for further, pre-existing bugs
   text    data     bss     dec     hex filename
   1969       0      32    2001     7d1 dd.o.oorig
   1941       0       0    1941     795 dd.o


Modified:
   trunk/busybox/coreutils/dd.c


Changeset:
Modified: trunk/busybox/coreutils/dd.c
===================================================================
--- trunk/busybox/coreutils/dd.c	2007-04-04 13:59:49 UTC (rev 18321)
+++ trunk/busybox/coreutils/dd.c	2007-04-04 14:01:23 UTC (rev 18322)
@@ -17,7 +17,7 @@
 	{ "b", 512 },
 	{ "kD", 1000 },
 	{ "k", 1024 },
-	{ "K", 1024 },	// compat with coreutils dd
+	{ "K", 1024 },	/* compat with coreutils dd */
 	{ "MD", 1000000 },
 	{ "M", 1048576 },
 	{ "GD", 1000000000 },
@@ -25,18 +25,21 @@
 	{ NULL, 0 }
 };
 
-static off_t out_full, out_part, in_full, in_part;
+struct globals {
+	off_t out_full, out_part, in_full, in_part;
+};
+#define G (*(struct globals*)&bb_common_bufsiz1)
 
 static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
 {
 	fprintf(stderr, "%"OFF_FMT"d+%"OFF_FMT"d records in\n"
 			"%"OFF_FMT"d+%"OFF_FMT"d records out\n",
-			in_full, in_part,
-			out_full, out_part);
+			G.in_full, G.in_part,
+			G.out_full, G.out_part);
 }
 
 static ssize_t full_write_or_warn(int fd, const void *buf, size_t len,
-		const char* filename)
+	const char * const filename)
 {
 	ssize_t n = full_write(fd, buf, len);
 	if (n < 0)
@@ -44,6 +47,19 @@
 	return n;
 }
 
+static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs,
+	const char * const filename)
+{
+	ssize_t n = full_write_or_warn(fd, buf, len, filename);
+	if (n < 0)
+		return 1;
+	if (n == obs)
+		G.out_full++;
+	else if (n > 0)
+		G.out_part++;
+	return 0;
+}
+
 #if ENABLE_LFS
 #define XATOU_SFX xatoull_sfx
 #else
@@ -59,11 +75,31 @@
 		trunc_flag   = 1 << 2,
 		twobufs_flag = 1 << 3,
 	};
+	const char * const keywords[] = {
+		"bs=", "count=", "seek=", "skip=", "if=", "of=",
+#if ENABLE_FEATURE_DD_IBS_OBS
+		"ibs=", "obs=", "conv=", "notrunc", "sync", "noerror",
+#endif
+		NULL
+	};
+#define OP_bs		0 + 1
+#define OP_count	OP_bs + 1
+#define OP_seek		OP_count + 1
+#define OP_skip		OP_seek + 1
+#define OP_if		OP_skip + 1
+#define OP_of		OP_if + 1
+#define OP_ibs		OP_of + ENABLE_FEATURE_DD_IBS_OBS
+#define OP_obs		OP_ibs + ENABLE_FEATURE_DD_IBS_OBS
+#define OP_conv		OP_obs + ENABLE_FEATURE_DD_IBS_OBS
+#define OP_conv_notrunc	OP_conv + ENABLE_FEATURE_DD_IBS_OBS
+#define OP_conv_sync	OP_conv_notrunc + ENABLE_FEATURE_DD_IBS_OBS
+#define OP_conv_noerror	OP_conv_sync + ENABLE_FEATURE_DD_IBS_OBS
+
 	int flags = trunc_flag;
 	size_t oc = 0, ibs = 512, obs = 512;
 	ssize_t n, w;
 	off_t seek = 0, skip = 0, count = OFF_T_MAX;
-	int oflag, ifd, ofd;
+	int ifd, ofd;
 	const char *infile = NULL, *outfile = NULL;
 	char *ibuf, *obuf;
 
@@ -78,63 +114,96 @@
 	}
 
 	for (n = 1; n < argc; n++) {
+		smalluint key_len, what;
+		char *key;
 		char *arg = argv[n];
+
+//XXX:FIXME: we reject plain "dd --" This would cost ~20 bytes, so..
+//if (*arg == '-' && *++arg == '-' && !*++arg) continue;
+		key = strstr(arg, "=");
+		if (key == NULL)
+			bb_show_usage();
+		key_len = key - arg + 1;
+		key = xstrndup(arg, key_len);
+		what = index_in_str_array(keywords, key) + 1;
+		if (ENABLE_FEATURE_CLEAN_UP)
+			free(key);
+		if (what == 0)
+			bb_show_usage();
+		arg += key_len;
 		/* Must fit into positive ssize_t */
-		if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", arg, 4))
-			ibs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes);
-		else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", arg, 4))
-			obs = xatoul_range_sfx(arg+4, 0, ((size_t)-1L)/2, dd_suffixes);
-		else if (!strncmp("bs=", arg, 3))
-			ibs = obs = xatoul_range_sfx(arg+3, 0, ((size_t)-1L)/2, dd_suffixes);
-		/* These can be large: */
-		else if (!strncmp("count=", arg, 6))
-			count = XATOU_SFX(arg+6, dd_suffixes);
-		else if (!strncmp("seek=", arg, 5))
-			seek = XATOU_SFX(arg+5, dd_suffixes);
-		else if (!strncmp("skip=", arg, 5))
-			skip = XATOU_SFX(arg+5, dd_suffixes);
-
-		else if (!strncmp("if=", arg, 3))
-			infile = arg+3;
-		else if (!strncmp("of=", arg, 3))
-			outfile = arg+3;
-		else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", arg, 5)) {
-			arg += 5;
-			while (1) {
-				if (!strncmp("notrunc", arg, 7)) {
-					flags &= ~trunc_flag;
-					arg += 7;
-				} else if (!strncmp("sync", arg, 4)) {
-					flags |= sync_flag;
-					arg += 4;
-				} else if (!strncmp("noerror", arg, 7)) {
-					flags |= noerror;
-					arg += 7;
-				} else {
-					bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
+		if (ENABLE_FEATURE_DD_IBS_OBS) {
+			if (what == OP_ibs) {
+				ibs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes);
+				continue;
+			}
+			if (what == OP_obs) {
+				obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes);
+				continue;
+			}
+			if (what == OP_conv) {
+				while (1) {
+					/* find ',', replace them with nil so we can use arg for
+					 * index_in_str_array without copying.
+					 * We rely on arg being non-null, else strstr would fault.
+					 */
+					key = strstr(arg, ",");
+					if (key)
+						*key = '\0';
+					what = index_in_str_array(keywords, arg) + 1;
+					if (what < OP_conv_notrunc)
+						bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
+					if (what == OP_conv_notrunc)
+						flags &= ~trunc_flag;
+					if (what == OP_conv_sync)
+						flags |= sync_flag;
+					if (what == OP_conv_noerror)
+						flags |= noerror;
+					if (!key) /* no ',' left, so this was the last specifier */
+						break;
+					arg += key - arg + 1; /* skip this keyword plus ',' */
 				}
-				if (arg[0] == '\0') break;
-				if (*arg++ != ',') bb_show_usage();
+				continue;
 			}
-		} else
-			bb_show_usage();
+		}
+		if (what == OP_bs) {
+			ibs = obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes);
+			continue;
+		}
+		/* These can be large: */
+		if (what == OP_count) {
+			count = XATOU_SFX(arg, dd_suffixes);
+			continue;
+		}
+		if (what == OP_seek) {
+			seek = XATOU_SFX(arg, dd_suffixes);
+			continue;
+		}
+		if (what == skip) {
+			skip = XATOU_SFX(arg, dd_suffixes);
+			continue;
+		}
+		if (what == OP_if) {
+			infile = arg;
+			continue;
+		}
+		if (what == OP_of)
+			outfile = arg;
 	}
-
+//XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever
 	ibuf = obuf = xmalloc(ibs);
 	if (ibs != obs) {
 		flags |= twobufs_flag;
 		obuf = xmalloc(obs);
 	}
-
 	if (infile != NULL)
 		ifd = xopen(infile, O_RDONLY);
 	else {
 		ifd = STDIN_FILENO;
 		infile = bb_msg_standard_input;
 	}
-
 	if (outfile != NULL) {
-		oflag = O_WRONLY | O_CREAT;
+		int oflag = O_WRONLY | O_CREAT;
 
 		if (!seek && (flags & trunc_flag))
 			oflag |= O_TRUNC;
@@ -154,30 +223,25 @@
 		ofd = STDOUT_FILENO;
 		outfile = bb_msg_standard_output;
 	}
-
 	if (skip) {
 		if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
 			while (skip-- > 0) {
 				n = safe_read(ifd, ibuf, ibs);
 				if (n < 0)
-					bb_perror_msg_and_die("%s", infile);
+					goto die_infile;
 				if (n == 0)
 					break;
 			}
 		}
 	}
-
 	if (seek) {
 		if (lseek(ofd, seek * obs, SEEK_CUR) < 0)
 			goto die_outfile;
 	}
 
-	while (in_full + in_part != count) {
-		if (flags & noerror) {
-			/* Pre-zero the buffer when doing the noerror thing */
+	while (G.in_full + G.in_part != count) {
+		if (flags & noerror) /* Pre-zero the buffer when for noerror */
 			memset(ibuf, '\0', ibs);
-		}
-
 		n = safe_read(ifd, ibuf, ibs);
 		if (n == 0)
 			break;
@@ -186,12 +250,12 @@
 				n = ibs;
 				bb_perror_msg("%s", infile);
 			} else
-				bb_perror_msg_and_die("%s", infile);
+				goto die_infile;
 		}
 		if ((size_t)n == ibs)
-			in_full++;
+			G.in_full++;
 		else {
-			in_part++;
+			G.in_part++;
 			if (flags & sync_flag) {
 				memset(ibuf + n, '\0', ibs - n);
 				n = ibs;
@@ -209,40 +273,32 @@
 				tmp += d;
 				oc += d;
 				if (oc == obs) {
-					w = full_write_or_warn(ofd, obuf, obs, outfile);
-					if (w < 0) goto out_status;
-					if (w == obs)
-						out_full++;
-					else if (w > 0)
-						out_part++;
+					if (write_and_stats(ofd, obuf, obs, obs, outfile))
+						goto out_status;
 					oc = 0;
 				}
 			}
-		} else {
-			w = full_write_or_warn(ofd, ibuf, n, outfile);
-			if (w < 0) goto out_status;
-			if (w == obs)
-				out_full++;
-			else if (w > 0)
-				out_part++;
-		}
+		} else
+			if (write_and_stats(ofd, ibuf, n, obs, outfile))
+				goto out_status;
 	}
 
 	if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
 		w = full_write_or_warn(ofd, obuf, oc, outfile);
 		if (w < 0) goto out_status;
 		if (w > 0)
-			out_part++;
+			G.out_part++;
 	}
 	if (close(ifd) < 0) {
+die_infile:
 		bb_perror_msg_and_die("%s", infile);
 	}
 
 	if (close(ofd) < 0) {
- die_outfile:
+die_outfile:
 		bb_perror_msg_and_die("%s", outfile);
 	}
- out_status:
+out_status:
 	dd_output_status(0);
 
 	return EXIT_SUCCESS;




More information about the busybox-cvs mailing list