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:
parent
1efb0053e4
commit
7a79617cc1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=264387
@ -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;
|
||||||
|
@ -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 ) .
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user