Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Apr 2014 22:36:27 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r264387 - head/usr.bin/find
Message-ID:  <201404122236.s3CMaRae081682@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404122236.s3CMaRae081682>