As reported on the git mailing list[1], find(1) should exit with non-zero 
status when a non-existent path is given which I think is also the intent 
of the find(1) code.

[1] http://marc.info/?l=git&m=126186443524638

For example:

        # find /no-such-path
        find: fts_open: No such file or directory
        # echo $?
        0
        ^^^ <--- should be something non-zero.

Looking at the code for find, we have the following in 
/usr/src/usr.bin/find/find.c, line 153:

        if (!(tree = fts_open(paths, ftsoptions, NULL)))
                err(1, "fts_open");

This looks right and fts_open(1) says:

        If an error occurs, fts_open() returns NULL and sets
        errno appropriately.

Debugging, it seems like errno comes back as ENOENT but the variable 
"tree" is not set to null...

Debugging a bit more it seems like "fts_open" calls "fts_stat" which 
returns FTS_NS but the code path for fts_open doesn't go into the error 
path at this point. Therefore, I propose the patch below.

With the patch applied I get:

        # find /no-such-path
        find: fts_open: No such file or directory
        # echo $?
        1

Index: fts.c
===================================================================
RCS file: /usr/cvs/src/lib/libc/gen/fts.c,v
retrieving revision 1.43
diff -u -r1.43 fts.c
--- fts.c       27 Aug 2009 16:19:27 -0000      1.43
+++ fts.c       28 Jan 2010 06:48:11 -0000
@@ -117,6 +117,10 @@
                p->fts_accpath = p->fts_name;
                p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
 
+               /* stat(2) failed, so fts_open should error. */
+               if (p->fts_info == FTS_NS)
+                       goto mem3;
+
                /* Command-line "." and ".." are real directories. */
                if (p->fts_info == FTS_DOT)
                        p->fts_info = FTS_D;

Reply via email to