]> git.saurik.com Git - apple/libc.git/blobdiff - gen/fts.c
Libc-498.1.1.tar.gz
[apple/libc.git] / gen / fts.c
index 75576d74bc78efdb1b55b269c3ceb748f5f42063..b8630c87f0c520d88f812a3c293e783059b2b33d 100644 (file)
--- a/gen/fts.c
+++ b/gen/fts.c
@@ -3,19 +3,20 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 #include <string.h>
 #include <unistd.h>
 
-static FTSENT  *fts_alloc __P((FTS *, char *, int));
-static FTSENT  *fts_build __P((FTS *, int));
-static void     fts_lfree __P((FTSENT *));
-static void     fts_load __P((FTS *, FTSENT *));
-static size_t   fts_maxarglen __P((char * const *));
-static void     fts_padjust __P((FTS *, void *));
-static int      fts_palloc __P((FTS *, size_t));
-static FTSENT  *fts_sort __P((FTS *, FTSENT *, int));
-static u_short  fts_stat __P((FTS *, FTSENT *, int));
+static FTSENT  *fts_alloc(FTS *, char *, int);
+static FTSENT  *fts_build(FTS *, int);
+static void     fts_lfree(FTSENT *);
+static void     fts_load(FTS *, FTSENT *);
+static size_t   fts_maxarglen(char * const *);
+static void     fts_padjust(FTS *, void *);
+static int      fts_palloc(FTS *, size_t);
+static FTSENT  *fts_sort(FTS *, FTSENT *, int);
+static u_short  fts_stat(FTS *, FTSENT *, int);
 
 #define        ISDOT(a)        (a[0] == '.' && (!a[1] || a[1] == '.' && !a[2]))
 
@@ -140,7 +141,7 @@ fts_open(argv, options, compar)
                p->fts_level = FTS_ROOTLEVEL;
                p->fts_parent = parent;
                p->fts_accpath = p->fts_name;
-               p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
+               p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOWDIR) ? -1 : ISSET(FTS_COMFOLLOW));
 
                /* Command-line "." and ".." are real directories. */
                if (p->fts_info == FTS_DOT)
@@ -828,12 +829,24 @@ fts_stat(sp, p, follow)
                if (stat(p->fts_accpath, sbp)) {
                        saved_errno = errno;
                        if (!lstat(p->fts_accpath, sbp)) {
+                               if (saved_errno == ELOOP)
+                                       p->fts_errno = ELOOP;
                                errno = 0;
                                return (FTS_SLNONE);
                        } 
                        p->fts_errno = saved_errno;
                        goto err;
                }
+               /*
+                * For FTS_COMFOLLOWDIR, drop back to lstat unless we have
+                * a directory
+                */
+               if (follow == -1 && !S_ISDIR(sbp->st_mode)) {
+                       if (lstat(p->fts_accpath, sbp)) {
+                               p->fts_errno = errno;
+                               goto err;
+                       }
+               }
        } else if (lstat(p->fts_accpath, sbp)) {
                p->fts_errno = errno;
 err:           memset(sbp, 0, sizeof(struct stat));