Subject: Re: making find(1) return immediately when finding a file
To: None <tech-userlevel@NetBSD.org>
From: Jan Schaumann <jschauma@netmeister.org>
List: tech-userlevel
Date: 02/18/2006 12:53:38
--GRPZ8SYKNexpdSJ7
Content-Type: multipart/mixed; boundary="Qxx1br4bt0+wmkIi"
Content-Disposition: inline


--Qxx1br4bt0+wmkIi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Tim Rightnour <root@garbled.net> wrote:
>=20
> On 17-Feb-2006 Matt Thomas wrote:
> > How about '-exit value'?
>=20
> If value is optional and defaults to something reasonable.  I'd say add i=
t.=20
> Sounds useful.

Here's a patch that uses '-exit value', with value being optional and
defaulting to '0'.  Does that look alright?

-Jan

--=20
The Internet interprets censorship as damage and routes around it.
	-- John Gilmore

--Qxx1br4bt0+wmkIi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="find.diff"
Content-Transfer-Encoding: quoted-printable

Index: extern.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/find/extern.h,v
retrieving revision 1.22
diff -b -u -r1.22 extern.h
--- extern.h	9 Nov 2005 00:47:16 -0000	1.22
+++ extern.h	18 Feb 2006 17:45:49 -0000
@@ -56,6 +56,7 @@
 PLAN	*c_empty __P((char ***, int));
 PLAN	*c_exec __P((char ***, int));
 PLAN	*c_execdir __P((char ***, int));
+PLAN	*c_exit __P((char ***, int));
 PLAN	*c_false __P((char ***, int));
 PLAN	*c_flags __P((char ***, int));
 PLAN	*c_follow __P((char ***, int));
Index: find.1
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/find/find.1,v
retrieving revision 1.55
diff -b -u -r1.55 find.1
--- find.1	9 Nov 2005 00:47:16 -0000	1.55
+++ find.1	18 Feb 2006 17:45:49 -0000
@@ -32,7 +32,7 @@
 .\"
 .\"	from: @(#)find.1	8.7 (Berkeley) 5/9/95
 .\"
-.Dd November 8, 2005
+.Dd February 18, 2006
 .Dt FIND 1
 .Os
 .Sh NAME
@@ -232,6 +232,14 @@
 The filename substituted for the string
 .Dq {}
 is not qualified.
+.It Ic -exit Op Ar n
+This primary causes
+.Nm
+to stop traversing the filesystem and exit immediately if a
+previous condition was met.
+If no value is specified, the exit value will be 0, else
+.Ar n .
+Note that other primaries will be evaluated and acted upon before exiting.
 .It Ic -false
 This primary always evaluates to false.
 This can be used following a primary that caused the
@@ -611,6 +619,16 @@
 .Dq wnj
 or that are newer than
 .Dq ttt .
+.It Li "find  /  \e(  -newer  ttt  -or  -user wnj  \e)  -exit 1"
+Return immediately with a value of 1 if any files are found that are either
+owned by
+.Dq wnj
+or that are newer than
+.Dq ttt ,
+but do not print them.
+.It Li "find  /  \e(  -newer  ttt  -or  -user wnj  \e)  -ls -exit 1"
+Same as above, but list the first file matching the criteria before exiting
+with a value of 1.
 .El
 .Sh SEE ALSO
 .Xr chflags 1 ,
Index: find.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/find/find.c,v
retrieving revision 1.20
diff -b -u -r1.20 find.c
--- find.c	12 Oct 2005 20:03:59 -0000	1.20
+++ find.c	18 Feb 2006 17:45:49 -0000
@@ -98,9 +98,9 @@
 	}
=20
 	/*
-	 * if the user didn't specify one of -print, -ok, -fprint, or -exec,
-	 * then -print is assumed so we bracket the current expression with
-	 * parens, if necessary, and add a -print node on the end.
+	 * if the user didn't specify one of -print, -ok, -fprint, -exec, or
+	 * -exit, then -print is assumed so we bracket the current expression
+	 * with parens, if necessary, and add a -print node on the end.
 	 */
 	if (!isoutput) {
 		if (plan =3D=3D NULL) {
@@ -189,14 +189,16 @@
 	char **paths;		/* array of pathnames to traverse */
 {
 	PLAN *p;
-	int rval;
+	int rval, cval;
 	sigset_t s;
=20
+	cval =3D 1;
+
 	if (!(tree =3D fts_open(paths, ftsoptions, issort ? ftscompare : NULL)))
 		err(1, "ftsopen");
=20
 	sig_lock(&s);
-	for (rval =3D 0; (g_entry =3D fts_read(tree)) !=3D NULL; sig_lock(&s)) {
+	for (rval =3D 0; cval && (g_entry =3D fts_read(tree)) !=3D NULL; sig_lock=
(&s)) {
 		sig_unlock(&s);
 		switch (g_entry->fts_info) {
 		case FTS_D:
@@ -230,8 +232,12 @@
 		 * the work specified by the user on the command line.
 		 */
 		for (p =3D plan; p && (p->eval)(p, g_entry); p =3D p->next)
-			;
+			if (p->type =3D=3D N_EXIT) {
+				rval =3D p->exit_val;
+				cval =3D 0;
+			}
 	}
+
 	sig_unlock(&s);
 	if (errno)
 		err(1, "fts_read");
Index: find.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/find/find.h,v
retrieving revision 1.20
diff -b -u -r1.20 find.h
--- find.h	9 Nov 2005 00:47:16 -0000	1.20
+++ find.h	18 Feb 2006 17:45:50 -0000
@@ -40,7 +40,7 @@
 enum ntype {
 	N_AND =3D 1, 				/* must start > 0 */
 	N_AMIN, N_ANEWER, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CNEWER, N_CTIME,
-	N_DEPTH, N_EMPTY, N_EXEC, N_EXECDIR, N_EXPR, N_FALSE, N_FLAGS,
+	N_DEPTH, N_EMPTY, N_EXEC, N_EXECDIR, N_EXIT, N_EXPR, N_FALSE, N_FLAGS,
 	N_FOLLOW, N_FPRINT, N_FSTYPE, N_GROUP,
 	N_INAME, N_INUM, N_IREGEX, N_LINKS, N_LS, N_MINDEPTH, N_MAXDEPTH,
 	N_MMIN, N_MTIME, N_NAME, N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK,
@@ -80,6 +80,7 @@
 		} ex;
 		char *_a_data[2];		/* array of char pointers */
 		char *_c_data;			/* char pointer */
+		int _exit_val;			/* exit value */
 		int _max_data;			/* tree depth */
 		int _min_data;			/* tree depth */
 		regex_t _regexp_data;		/* compiled regexp */
@@ -101,6 +102,7 @@
 #define	e_argv		p_un.ex._e_argv
 #define	e_orig		p_un.ex._e_orig
 #define	e_len		p_un.ex._e_len
+#define	exit_val	p_un._exit_val
 #define	max_data	p_un._max_data
 #define	min_data	p_un._min_data
 #define	regexp_data	p_un._regexp_data
Index: function.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/find/function.c,v
retrieving revision 1.52
diff -b -u -r1.52 function.c
--- function.c	9 Nov 2005 00:47:16 -0000	1.52
+++ function.c	18 Feb 2006 17:45:50 -0000
@@ -648,6 +648,29 @@
 	return (new);
 }
=20
+PLAN *
+c_exit(argvp, isok)
+	char ***argvp;
+	int isok;
+{
+	char *arg =3D **argvp;
+	PLAN *new;
+
+	/* not technically true, but otherwise '-print' is implied */
+	isoutput =3D 1;
+
+	new =3D palloc(N_EXIT, f_always_true);
+
+	if (arg) {
+		(*argvp)++;
+		new->exit_val =3D find_parsenum(new, "-exit", arg, NULL);
+	} else
+		new->exit_val =3D 0;
+
+	return (new);
+}
+
+
 /*
  * -false function
  */
Index: option.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/find/option.c,v
retrieving revision 1.22
diff -b -u -r1.22 option.c
--- option.c	9 Nov 2005 00:47:16 -0000	1.22
+++ option.c	18 Feb 2006 17:45:50 -0000
@@ -72,6 +72,7 @@
 	{ "-empty",	N_EMPTY,	c_empty,	0 },
 	{ "-exec",	N_EXEC,		c_exec,		1 },
 	{ "-execdir",	N_EXECDIR,	c_execdir,	1 },
+	{ "-exit",	N_EXIT,		c_exit,		0 },
 	{ "-false",	N_FALSE,	c_false,	0 },
 	{ "-flags",	N_FLAGS,	c_flags,	1 },
 	{ "-follow",	N_FOLLOW,	c_follow,	0 },

--Qxx1br4bt0+wmkIi--

--GRPZ8SYKNexpdSJ7
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (NetBSD)

iD8DBQFD918ifFtkr68iakwRAuqJAJ9OdWbkSoKoA+Kf+bKQ/WaWiGXZ7gCfT7Cg
7ij7/L5419BxTqwCQ4g9t3Y=
=RTL4
-----END PGP SIGNATURE-----

--GRPZ8SYKNexpdSJ7--