svn commit: r204761 - in head: tools/regression/usr.bin tools/regression/usr.bin/apply usr.bin/apply

Jaakko Heinonen jh at FreeBSD.org
Fri Mar 5 15:23:02 UTC 2010


Author: jh
Date: Fri Mar  5 15:23:01 2010
New Revision: 204761
URL: http://svn.freebsd.org/changeset/base/204761

Log:
  - Use errx(3) instead of err(3) when checking if snprintf(3) succeeded.
    snprintf(3) doesn't set errno in the tested cases.
  - If the same argument reference (for example %1) was specified more than
    once, the command didn't necessarily fit to the final command buffer. Fix
    this using a dynamic sbuf buffer. Add a few regression tests for the case.
  
  PR:		bin/95079
  No objections:	freebsd-hackers

Added:
  head/tools/regression/usr.bin/apply/
  head/tools/regression/usr.bin/apply/Makefile   (contents, props changed)
  head/tools/regression/usr.bin/apply/regress.00.in   (contents, props changed)
  head/tools/regression/usr.bin/apply/regress.00.out   (contents, props changed)
  head/tools/regression/usr.bin/apply/regress.01.out   (contents, props changed)
  head/tools/regression/usr.bin/apply/regress.01.sh   (contents, props changed)
  head/tools/regression/usr.bin/apply/regress.sh   (contents, props changed)
  head/tools/regression/usr.bin/apply/regress.t   (contents, props changed)
Modified:
  head/tools/regression/usr.bin/Makefile
  head/usr.bin/apply/Makefile
  head/usr.bin/apply/apply.c

Modified: head/tools/regression/usr.bin/Makefile
==============================================================================
--- head/tools/regression/usr.bin/Makefile	Fri Mar  5 15:19:53 2010	(r204760)
+++ head/tools/regression/usr.bin/Makefile	Fri Mar  5 15:23:01 2010	(r204761)
@@ -1,6 +1,7 @@
 # $FreeBSD$
 
-SUBDIR=	calendar comm file2c join jot m4 printf sed tr uudecode uuencode xargs
+SUBDIR=	apply calendar comm file2c join jot m4 printf sed tr	\
+	uudecode uuencode xargs
 .if !defined(AUTOMATED)
 SUBDIR+= lastcomm
 .endif

Added: head/tools/regression/usr.bin/apply/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/usr.bin/apply/Makefile	Fri Mar  5 15:23:01 2010	(r204761)
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+all:
+	@m4 ${.CURDIR}/../regress.m4 ${.CURDIR}/regress.sh | sh /dev/stdin ${.CURDIR}

Added: head/tools/regression/usr.bin/apply/regress.00.in
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/usr.bin/apply/regress.00.in	Fri Mar  5 15:23:01 2010	(r204761)
@@ -0,0 +1 @@
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012

Added: head/tools/regression/usr.bin/apply/regress.00.out
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/usr.bin/apply/regress.00.out	Fri Mar  5 15:23:01 2010	(r204761)
@@ -0,0 +1 @@
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
 789012345678901234567890123456789012 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
 012345678901234567890123456789012345678901234567890123456789!
 0123456789012

Added: head/tools/regression/usr.bin/apply/regress.01.out
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/usr.bin/apply/regress.01.out	Fri Mar  5 15:23:01 2010	(r204761)
@@ -0,0 +1 @@
+apply: Argument list too long

Added: head/tools/regression/usr.bin/apply/regress.01.sh
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/usr.bin/apply/regress.01.sh	Fri Mar  5 15:23:01 2010	(r204761)
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD$
+
+SHELL=/bin/sh; export SHELL
+
+ARG_MAX=$(getconf ARG_MAX)
+ARG_MAX_HALF=$((ARG_MAX / 2))
+
+apply 'echo %1 %1 %1' $(jot $ARG_MAX_HALF 1 1 | tr -d '\n') 2>&1
+
+if [ $? -eq 0 ]; then
+	return 1
+else
+	return 0
+fi

Added: head/tools/regression/usr.bin/apply/regress.sh
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/usr.bin/apply/regress.sh	Fri Mar  5 15:23:01 2010	(r204761)
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+echo 1..2
+
+REGRESSION_START($1)
+
+REGRESSION_TEST(`00', `apply "echo %1 %1 %1 %1" $(cat regress.00.in)')
+REGRESSION_TEST(`01', `sh regress.01.sh')
+
+REGRESSION_END()

Added: head/tools/regression/usr.bin/apply/regress.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/regression/usr.bin/apply/regress.t	Fri Mar  5 15:23:01 2010	(r204761)
@@ -0,0 +1,6 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+m4 ../regress.m4 regress.sh | sh

Modified: head/usr.bin/apply/Makefile
==============================================================================
--- head/usr.bin/apply/Makefile	Fri Mar  5 15:19:53 2010	(r204760)
+++ head/usr.bin/apply/Makefile	Fri Mar  5 15:23:01 2010	(r204761)
@@ -2,5 +2,7 @@
 # $FreeBSD$
 
 PROG=	apply
+DPADD=	${LIBSBUF}
+LDADD=	-lsbuf
 
 .include <bsd.prog.mk>

Modified: head/usr.bin/apply/apply.c
==============================================================================
--- head/usr.bin/apply/apply.c	Fri Mar  5 15:19:53 2010	(r204760)
+++ head/usr.bin/apply/apply.c	Fri Mar  5 15:23:01 2010	(r204761)
@@ -44,10 +44,12 @@ static char sccsid[] = "@(#)apply.c	8.4 
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
+#include <sys/sbuf.h>
 #include <sys/wait.h>
 
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <paths.h>
 #include <signal.h>
 #include <stdio.h>
@@ -61,10 +63,13 @@ static int	exec_shell(const char *, char
 static void	usage(void);
 
 int
-main(int argc, char *argv[]) {
+main(int argc, char *argv[])
+{
+	struct sbuf *cmdbuf;
+	long arg_max;
 	int ch, debug, i, magic, n, nargs, offset, rval;
-	size_t clen, cmdsize, l;
-	char *c, *cmd, *name, *p, *q, *shell, *slashp, *tmpshell;
+	size_t cmdsize;
+	char *cmd, *name, *p, *shell, *slashp, *tmpshell;
 
 	debug = 0;
 	magic = '%';		/* Default magic char is `%'. */
@@ -144,13 +149,13 @@ main(int argc, char *argv[]) {
 		p = cmd;
 		offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
 		if ((size_t)offset >= cmdsize)
-			err(1, "snprintf() failed");
+			errx(1, "snprintf() failed");
 		p += offset;
 		cmdsize -= offset;
 		for (i = 1; i <= nargs; i++) {
 			offset = snprintf(p, cmdsize, " %c%d", magic, i);
 			if ((size_t)offset >= cmdsize)
-				err(1, "snprintf() failed");
+				errx(1, "snprintf() failed");
 			p += offset;
 			cmdsize -= offset;
 		}
@@ -164,61 +169,53 @@ main(int argc, char *argv[]) {
 	} else {
 		offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]);
 		if ((size_t)offset >= cmdsize)
-			err(1, "snprintf() failed");
+			errx(1, "snprintf() failed");
 		nargs = n;
 	}
 
-	/*
-	 * Grab some space in which to build the command.  Allocate
-	 * as necessary later, but no reason to build it up slowly
-	 * for the normal case.
-	 */
-	if ((c = malloc(clen = 1024)) == NULL)
+	cmdbuf = sbuf_new(NULL, NULL, 1024, SBUF_AUTOEXTEND);
+	if (cmdbuf == NULL)
 		err(1, NULL);
 
+	arg_max = sysconf(_SC_ARG_MAX);
+
 	/*
 	 * (argc) and (argv) are still offset by one to make it simpler to
 	 * expand %digit references.  At the end of the loop check for (argc)
 	 * equals 1 means that all the (argv) has been consumed.
 	 */
 	for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) {
-		/*
-		 * Find a max value for the command length, and ensure
-		 * there's enough space to build it.
-		 */
-		for (l = strlen(cmd), i = 0; i < nargs; i++)
-			l += strlen(argv[i+1]);
-		if (l > clen && (c = realloc(c, clen = l)) == NULL)
-			err(1, NULL);
-
+		sbuf_clear(cmdbuf);
 		/* Expand command argv references. */
-		for (p = cmd, q = c; *p != '\0'; ++p)
+		for (p = cmd; *p != '\0'; ++p) {
 			if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
-				offset = snprintf(q, l, "%s",
-				    argv[(++p)[0] - '0']);
-				if ((size_t)offset >= l)
-					err(1, "snprintf() failed");
-				q += offset;
-				l -= offset;
-			} else
-				*q++ = *p;
+				if (sbuf_cat(cmdbuf, argv[(++p)[0] - '0'])
+				    == -1)
+					errc(1, ENOMEM, "sbuf");
+			} else {
+				if (sbuf_putc(cmdbuf, *p) == -1)
+					errc(1, ENOMEM, "sbuf");
+			}
+			if (sbuf_len(cmdbuf) > arg_max)
+				errc(1, E2BIG, NULL);
+		}
 
 		/* Terminate the command string. */
-		*q = '\0';
+		sbuf_finish(cmdbuf);
 
 		/* Run the command. */
 		if (debug)
-			(void)printf("%s\n", c);
+			(void)printf("%s\n", sbuf_data(cmdbuf));
 		else
-			if (exec_shell(c, shell, name))
+			if (exec_shell(sbuf_data(cmdbuf), shell, name))
 				rval = 1;
 	}
 
 	if (argc != 1)
 		errx(1, "expecting additional argument%s after \"%s\"",
-	    (nargs - argc) ? "s" : "", argv[argc - 1]);
+		    (nargs - argc) ? "s" : "", argv[argc - 1]);
 	free(cmd);
-	free(c);
+	sbuf_delete(cmdbuf);
 	free(shell);
 	exit(rval);
 }


More information about the svn-src-head mailing list