On 17/11/14(Mon) 17:00, enh wrote:
> Sony sent us (Android) a patch to use fstatat instead of lstat in fts.
> Sadly our copy of fts.c is already a little diverged from yours
> (because we have to use strlen to get the length of the d_name, not
> having a d_namlen field) but i thought i'd forward this your way
> anyway to reduce the need for further divergence...
> 
> https://android-review.googlesource.com/#/c/113415/

Here's the diff inline to facilitate review:

Index: gen/fts.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/fts.c,v
retrieving revision 1.47
diff -u -p -r1.47 fts.c
--- gen/fts.c   8 Oct 2014 04:36:23 -0000       1.47
+++ gen/fts.c   18 Nov 2014 14:17:07 -0000
@@ -49,7 +49,7 @@ static size_t  fts_maxarglen(char * cons
 static void     fts_padjust(FTS *, FTSENT *);
 static int      fts_palloc(FTS *, size_t);
 static FTSENT  *fts_sort(FTS *, FTSENT *, int);
-static u_short  fts_stat(FTS *, FTSENT *, int);
+static u_short  fts_stat(FTS *, FTSENT *, int, DIR *);
 static int      fts_safe_changedir(FTS *, FTSENT *, int, char *);
 
 #define        ISDOT(a)        (a[0] == '.' && (!a[1] || (a[1] == '.' && 
!a[2])))
@@ -116,7 +116,7 @@ fts_open(char * const *argv, int options
                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_COMFOLLOW), NULL);
 
                /* Command-line "." and ".." are real directories. */
                if (p->fts_info == FTS_DOT)
@@ -270,7 +270,7 @@ fts_read(FTS *sp)
 
        /* Any type of file may be re-visited; re-stat and re-turn. */
        if (instr == FTS_AGAIN) {
-               p->fts_info = fts_stat(sp, p, 0);
+               p->fts_info = fts_stat(sp, p, 0, NULL);
                return (p);
        }
 
@@ -282,7 +282,7 @@ fts_read(FTS *sp)
         */
        if (instr == FTS_FOLLOW &&
            (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
-               p->fts_info = fts_stat(sp, p, 1);
+               p->fts_info = fts_stat(sp, p, 1, NULL);
                if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
                        if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
                                p->fts_errno = errno;
@@ -371,7 +371,7 @@ next:       tmp = p;
                if (p->fts_instr == FTS_SKIP)
                        goto next;
                if (p->fts_instr == FTS_FOLLOW) {
-                       p->fts_info = fts_stat(sp, p, 1);
+                       p->fts_info = fts_stat(sp, p, 1, NULL);
                        if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
                                if ((p->fts_symfd =
                                    open(".", O_RDONLY, 0)) < 0) {
@@ -719,7 +719,7 @@ mem1:                               saved_errno = errno;
                        } else
                                p->fts_accpath = p->fts_name;
                        /* Stat it. */
-                       p->fts_info = fts_stat(sp, p, 0);
+                       p->fts_info = fts_stat(sp, p, 0, dirp);
 
                        /* Decrement link count if applicable. */
                        if (nlinks > 0 && (p->fts_info == FTS_D ||
@@ -786,7 +786,7 @@ mem1:                               saved_errno = errno;
 }
 
 static u_short
-fts_stat(FTS *sp, FTSENT *p, int follow)
+fts_stat(FTS *sp, FTSENT *p, int follow, DIR *dirp)
 {
        FTSENT *t;
        dev_t dev;
@@ -810,6 +810,11 @@ fts_stat(FTS *sp, FTSENT *p, int follow)
                                return (FTS_SLNONE);
                        }
                        p->fts_errno = saved_errno;
+                       goto err;
+               }
+       } else if (dirp) {
+               if (fstatat(dirfd(dirp), p->fts_name, sbp, 
AT_SYMLINK_NOFOLLOW)) {
+                       p->fts_errno = errno;
                        goto err;
                }
        } else if (lstat(p->fts_accpath, sbp)) {

Reply via email to