Author: jilles
Date: Sat Apr 12 22:36:26 2014
New Revision: 264387
URL: http://svnweb.freebsd.org/changeset/base/264387

Log:
  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.

Modified:
  head/usr.bin/find/extern.h
  head/usr.bin/find/find.1
  head/usr.bin/find/find.c
  head/usr.bin/find/function.c
  head/usr.bin/find/main.c

Modified: head/usr.bin/find/extern.h
==============================================================================
--- head/usr.bin/find/extern.h  Sat Apr 12 22:05:03 2014        (r264386)
+++ head/usr.bin/find/extern.h  Sat Apr 12 22:36:26 2014        (r264387)
@@ -118,6 +118,7 @@ extern int ftsoptions, ignore_readdir_ra
 extern int issort, isxargs;
 extern int mindepth, maxdepth;
 extern int regexp_flags;
+extern int exitstatus;
 extern time_t now;
 extern int dotfd;
 extern FTS *tree;

Modified: head/usr.bin/find/find.1
==============================================================================
--- head/usr.bin/find/find.1    Sat Apr 12 22:05:03 2014        (r264386)
+++ head/usr.bin/find/find.1    Sat Apr 12 22:36:26 2014        (r264387)
@@ -31,7 +31,7 @@
 .\"    @(#)find.1      8.7 (Berkeley) 5/9/95
 .\" $FreeBSD$
 .\"
-.Dd January 5, 2014
+.Dd April 12, 2014
 .Dt FIND 1
 .Os
 .Sh NAME
@@ -384,6 +384,12 @@ is replaced with as many pathnames as po
 .Ar utility .
 This behaviour is similar to that of
 .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 \&;
 The
 .Ic -execdir
@@ -406,6 +412,12 @@ is replaced with as many pathnames as po
 .Ar utility .
 This behaviour is similar to that of
 .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
 The flags are specified using symbolic names (see
 .Xr chflags 1 ) .

Modified: head/usr.bin/find/find.c
==============================================================================
--- head/usr.bin/find/find.c    Sat Apr 12 22:05:03 2014        (r264386)
+++ head/usr.bin/find/find.c    Sat Apr 12 22:36:26 2014        (r264387)
@@ -175,13 +175,14 @@ find_execute(PLAN *plan, char *paths[])
 {
        FTSENT *entry;
        PLAN *p;
-       int e, rval;
+       int e;
 
        tree = fts_open(paths, ftsoptions, (issort ? find_compare : NULL));
        if (tree == NULL)
                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 (fts_set(tree, entry, FTS_SKIP))
                                err(1, "%s", entry->fts_path);
@@ -206,7 +207,7 @@ find_execute(PLAN *plan, char *paths[])
                        (void)fflush(stdout);
                        warnx("%s: %s",
                            entry->fts_path, strerror(entry->fts_errno));
-                       rval = 1;
+                       exitstatus = 1;
                        continue;
 #ifdef FTS_W
                case FTS_W:
@@ -217,7 +218,7 @@ find_execute(PLAN *plan, char *paths[])
                if (isxargs && strpbrk(entry->fts_path, BADCH)) {
                        (void)fflush(stdout);
                        warnx("%s: illegal path", entry->fts_path);
-                       rval = 1;
+                       exitstatus = 1;
                        continue;
                }
 
@@ -235,5 +236,5 @@ find_execute(PLAN *plan, char *paths[])
        finish_execplus();
        if (e && (!ignore_readdir_race || e != ENOENT))
                errc(1, e, "fts_read");
-       return (rval);
+       return (exitstatus);
 }

Modified: head/usr.bin/find/function.c
==============================================================================
--- head/usr.bin/find/function.c        Sat Apr 12 22:05:03 2014        
(r264386)
+++ head/usr.bin/find/function.c        Sat Apr 12 22:36:26 2014        
(r264387)
@@ -671,7 +671,13 @@ doexec:    if ((plan->flags & F_NEEDOK) && 
                plan->e_psize = plan->e_pbsize;
        }
        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);
 }
 
 /*

Modified: head/usr.bin/find/main.c
==============================================================================
--- head/usr.bin/find/main.c    Sat Apr 12 22:05:03 2014        (r264386)
+++ head/usr.bin/find/main.c    Sat Apr 12 22:36:26 2014        (r264387)
@@ -72,6 +72,7 @@ int issort;                   /* do hierarchies 
 int isxargs;                   /* don't permit xargs delimiting chars */
 int mindepth = -1, maxdepth = -1; /* minimum and maximum depth */
 int regexp_flags = REG_BASIC;  /* use the "basic" regexp by default*/
+int exitstatus;
 
 static void usage(void);
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to