find: Correctly propagate -exec/-execdir ... {} + exit status.

As per POSIX, the -exec ... {} + primary always returns true, but a non-zero
exit status causes find to return a non-zero exit status itself. GNU does
the same, and also for -execdir ... {} +.

It does not make much sense to return false from the primary only when the
child process happens to be run.

The behaviour for -exec/-execdir ... ; remains unchanged: the primary
returns true or false depending on the exit status, and find's exit status
is unaffected.
This commit is contained in:
Jilles Tjoelker 2014-04-12 22:36:26 +00:00
parent 1efb0053e4
commit 7a79617cc1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=264387
5 changed files with 28 additions and 7 deletions

View File

@ -118,6 +118,7 @@ extern int ftsoptions, ignore_readdir_race, isdeprecated, isdepth, isoutput;
extern int issort, isxargs; extern int issort, isxargs;
extern int mindepth, maxdepth; extern int mindepth, maxdepth;
extern int regexp_flags; extern int regexp_flags;
extern int exitstatus;
extern time_t now; extern time_t now;
extern int dotfd; extern int dotfd;
extern FTS *tree; extern FTS *tree;

View File

@ -31,7 +31,7 @@
.\" @(#)find.1 8.7 (Berkeley) 5/9/95 .\" @(#)find.1 8.7 (Berkeley) 5/9/95
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 5, 2014 .Dd April 12, 2014
.Dt FIND 1 .Dt FIND 1
.Os .Os
.Sh NAME .Sh NAME
@ -384,6 +384,12 @@ is replaced with as many pathnames as possible for each invocation of
.Ar utility . .Ar utility .
This behaviour is similar to that of This behaviour is similar to that of
.Xr xargs 1 . .Xr xargs 1 .
The primary always returns true;
if at least one invocation of
.Ar utility
returns a non-zero exit status,
.Nm
will return a non-zero exit status.
.It Ic -execdir Ar utility Oo Ar argument ... Oc Li \&; .It Ic -execdir Ar utility Oo Ar argument ... Oc Li \&;
The The
.Ic -execdir .Ic -execdir
@ -406,6 +412,12 @@ is replaced with as many pathnames as possible for each invocation of
.Ar utility . .Ar utility .
This behaviour is similar to that of This behaviour is similar to that of
.Xr xargs 1 . .Xr xargs 1 .
The primary always returns true;
if at least one invocation of
.Ar utility
returns a non-zero exit status,
.Nm
will return a non-zero exit status.
.It Ic -flags Oo Cm - Ns | Ns Cm + Oc Ns Ar flags , Ns Ar notflags .It Ic -flags Oo Cm - Ns | Ns Cm + Oc Ns Ar flags , Ns Ar notflags
The flags are specified using symbolic names (see The flags are specified using symbolic names (see
.Xr chflags 1 ) . .Xr chflags 1 ) .

View File

@ -175,13 +175,14 @@ find_execute(PLAN *plan, char *paths[])
{ {
FTSENT *entry; FTSENT *entry;
PLAN *p; PLAN *p;
int e, rval; int e;
tree = fts_open(paths, ftsoptions, (issort ? find_compare : NULL)); tree = fts_open(paths, ftsoptions, (issort ? find_compare : NULL));
if (tree == NULL) if (tree == NULL)
err(1, "ftsopen"); err(1, "ftsopen");
for (rval = 0; errno = 0, (entry = fts_read(tree)) != NULL;) { exitstatus = 0;
while (errno = 0, (entry = fts_read(tree)) != NULL) {
if (maxdepth != -1 && entry->fts_level >= maxdepth) { if (maxdepth != -1 && entry->fts_level >= maxdepth) {
if (fts_set(tree, entry, FTS_SKIP)) if (fts_set(tree, entry, FTS_SKIP))
err(1, "%s", entry->fts_path); err(1, "%s", entry->fts_path);
@ -206,7 +207,7 @@ find_execute(PLAN *plan, char *paths[])
(void)fflush(stdout); (void)fflush(stdout);
warnx("%s: %s", warnx("%s: %s",
entry->fts_path, strerror(entry->fts_errno)); entry->fts_path, strerror(entry->fts_errno));
rval = 1; exitstatus = 1;
continue; continue;
#ifdef FTS_W #ifdef FTS_W
case FTS_W: case FTS_W:
@ -217,7 +218,7 @@ find_execute(PLAN *plan, char *paths[])
if (isxargs && strpbrk(entry->fts_path, BADCH)) { if (isxargs && strpbrk(entry->fts_path, BADCH)) {
(void)fflush(stdout); (void)fflush(stdout);
warnx("%s: illegal path", entry->fts_path); warnx("%s: illegal path", entry->fts_path);
rval = 1; exitstatus = 1;
continue; continue;
} }
@ -235,5 +236,5 @@ find_execute(PLAN *plan, char *paths[])
finish_execplus(); finish_execplus();
if (e && (!ignore_readdir_race || e != ENOENT)) if (e && (!ignore_readdir_race || e != ENOENT))
errc(1, e, "fts_read"); errc(1, e, "fts_read");
return (rval); return (exitstatus);
} }

View File

@ -671,7 +671,13 @@ doexec: if ((plan->flags & F_NEEDOK) && !queryuser(plan->e_argv))
plan->e_psize = plan->e_pbsize; plan->e_psize = plan->e_pbsize;
} }
pid = waitpid(pid, &status, 0); pid = waitpid(pid, &status, 0);
return (pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status)); if (pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status))
return (1);
if (plan->flags & F_EXECPLUS) {
exitstatus = 1;
return (1);
}
return (0);
} }
/* /*

View File

@ -72,6 +72,7 @@ int issort; /* do hierarchies in lexicographical order */
int isxargs; /* don't permit xargs delimiting chars */ int isxargs; /* don't permit xargs delimiting chars */
int mindepth = -1, maxdepth = -1; /* minimum and maximum depth */ int mindepth = -1, maxdepth = -1; /* minimum and maximum depth */
int regexp_flags = REG_BASIC; /* use the "basic" regexp by default*/ int regexp_flags = REG_BASIC; /* use the "basic" regexp by default*/
int exitstatus;
static void usage(void); static void usage(void);