find(1) uses ARG_MAX to compute the maximum space it can pass to
execve(2). This doesn't fly if userland and the kernel don't agree, as
noticed by some after the recent ARG_MAX bump.
--8<--
ritchie /usr/src/usr.bin/find$ obj/find /usr/src/ -type f -exec true {} +
find: true: Argument list too long
find: true: Argument list too long
find: true: Argument list too long
^C
-->8--
While having the kernel and userland out of sync is not a good idea,
making find(1) more robust by using sysconf(3) is easy. This is what
xargs(1) already does.
ok?
PS: a followup diff will take into account the space taken by the
environment
Index: function.c
===================================================================
RCS file: /d/cvs/src/usr.bin/find/function.c,v
retrieving revision 1.47
diff -u -p -p -u -r1.47 function.c
--- function.c 28 Jun 2019 13:35:01 -0000 1.47
+++ function.c 9 Apr 2020 01:36:14 -0000
@@ -538,7 +538,7 @@ run_f_exec(PLAN *plan)
*
* If -exec ... {} +, use only the first array, but make it large
* enough to hold 5000 args (cf. src/usr.bin/xargs/xargs.c for a
- * discussion), and then allocate ARG_MAX - 4K of space for args.
+ * discussion), and then allocate space for args.
*/
PLAN *
c_exec(char *unused, char ***argvp, int isok)
@@ -587,6 +587,7 @@ c_exec(char *unused, char ***argvp, int
errx(1, "-ok: terminating \"+\" not permitted.");
if (new->flags & F_PLUSSET) {
+ long arg_max;
u_int c, bufsize;
cnt = ap - *argvp - 1; /* units are words */
@@ -599,6 +600,14 @@ c_exec(char *unused, char ***argvp, int
new->ep_narg = 0;
/*
+ * Compute the maximum space we can use for arguments
+ * passed to execve(2).
+ */
+ arg_max = sysconf(_SC_ARG_MAX);
+ if (arg_max == -1)
+ err(1, "sysconf(_SC_ARG_MAX) failed");
+
+ /*
* Count up the space of the user's arguments, and
* subtract that from what we allocate.
*/
@@ -608,8 +617,7 @@ c_exec(char *unused, char ***argvp, int
c += strlen(*argv) + 1;
new->e_argv[cnt] = *argv;
}
- bufsize = ARG_MAX - 4 * 1024 - c;
-
+ bufsize = arg_max - 4 * 1024 - c;
/*
* Allocate, and then initialize current, base, and
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE