Date: Fri, 30 Jul 2010 12:04:30 +0000 (UTC) From: Jaakko Heinonen <jh@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r210642 - in stable/8: tools/regression/usr.bin tools/regression/usr.bin/apply tools/regression/usr.bin/pkill usr.bin/apply Message-ID: <201007301204.o6UC4UrF055013@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jh Date: Fri Jul 30 12:04:29 2010 New Revision: 210642 URL: http://svn.freebsd.org/changeset/base/210642 Log: MFC r204761: - 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 Added: stable/8/tools/regression/usr.bin/apply/ - copied from r204761, head/tools/regression/usr.bin/apply/ Modified: stable/8/tools/regression/usr.bin/Makefile stable/8/usr.bin/apply/Makefile stable/8/usr.bin/apply/apply.c Directory Properties: stable/8/tools/regression/usr.bin/ (props changed) stable/8/tools/regression/usr.bin/pkill/pgrep-_g.t (props changed) stable/8/tools/regression/usr.bin/pkill/pgrep-_s.t (props changed) stable/8/tools/regression/usr.bin/pkill/pkill-_g.t (props changed) stable/8/tools/regression/usr.bin/sed/ (props changed) stable/8/usr.bin/apply/ (props changed) Modified: stable/8/tools/regression/usr.bin/Makefile ============================================================================== --- stable/8/tools/regression/usr.bin/Makefile Fri Jul 30 11:58:18 2010 (r210641) +++ stable/8/tools/regression/usr.bin/Makefile Fri Jul 30 12:04:29 2010 (r210642) @@ -1,5 +1,5 @@ # $FreeBSD$ -SUBDIR= calendar file2c join jot m4 printf sed tr uudecode uuencode xargs lastcomm +SUBDIR= apply calendar file2c join jot m4 printf sed tr uudecode uuencode xargs lastcomm .include <bsd.subdir.mk> Modified: stable/8/usr.bin/apply/Makefile ============================================================================== --- stable/8/usr.bin/apply/Makefile Fri Jul 30 11:58:18 2010 (r210641) +++ stable/8/usr.bin/apply/Makefile Fri Jul 30 12:04:29 2010 (r210642) @@ -3,5 +3,7 @@ PROG= apply WARNS?= 4 +DPADD= ${LIBSBUF} +LDADD= -lsbuf .include <bsd.prog.mk> Modified: stable/8/usr.bin/apply/apply.c ============================================================================== --- stable/8/usr.bin/apply/apply.c Fri Jul 30 11:58:18 2010 (r210641) +++ stable/8/usr.bin/apply/apply.c Fri Jul 30 12:04:29 2010 (r210642) @@ -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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007301204.o6UC4UrF055013>