Lines 610-615
__fts_set_clientptr_44bsd(FTS *sp, void *clientptr)
Link Here
|
610 |
sp->fts_clientptr = clientptr; |
610 |
sp->fts_clientptr = clientptr; |
611 |
} |
611 |
} |
612 |
|
612 |
|
|
|
613 |
static struct dirent * |
614 |
fts_safe_readdir(DIR *dirp, int *readdir_errno) |
615 |
{ |
616 |
errno = 0; |
617 |
if (!dirp) |
618 |
return (NULL); |
619 |
struct dirent *ret = freebsd11_readdir(dirp); |
620 |
*readdir_errno = errno; |
621 |
return (ret); |
622 |
} |
623 |
|
613 |
/* |
624 |
/* |
614 |
* This is the tricky part -- do not casually change *anything* in here. The |
625 |
* This is the tricky part -- do not casually change *anything* in here. The |
615 |
* idea is to build the linked list of entries that are used by fts_children |
626 |
* idea is to build the linked list of entries that are used by fts_children |
Lines 634-640
fts_build(FTS *sp, int type)
Link Here
|
634 |
DIR *dirp; |
645 |
DIR *dirp; |
635 |
void *oldaddr; |
646 |
void *oldaddr; |
636 |
int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno, |
647 |
int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno, |
637 |
nostat, doadjust, dnamlen; |
648 |
nostat, doadjust, dnamlen, readdir_errno; |
638 |
char *cp; |
649 |
char *cp; |
639 |
|
650 |
|
640 |
/* Set current node pointer. */ |
651 |
/* Set current node pointer. */ |
Lines 738-745
fts_build(FTS *sp, int type)
Link Here
|
738 |
|
749 |
|
739 |
/* Read the directory, attaching each entry to the `link' pointer. */ |
750 |
/* Read the directory, attaching each entry to the `link' pointer. */ |
740 |
doadjust = 0; |
751 |
doadjust = 0; |
|
|
752 |
readdir_errno = 0; |
741 |
for (head = tail = NULL, nitems = 0; |
753 |
for (head = tail = NULL, nitems = 0; |
742 |
dirp && (dp = freebsd11_readdir(dirp));) { |
754 |
(dp = fts_safe_readdir(dirp, &readdir_errno));) { |
743 |
dnamlen = dp->d_namlen; |
755 |
dnamlen = dp->d_namlen; |
744 |
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) |
756 |
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) |
745 |
continue; |
757 |
continue; |
Lines 839-844
mem1: saved_errno = errno;
Link Here
|
839 |
} |
851 |
} |
840 |
++nitems; |
852 |
++nitems; |
841 |
} |
853 |
} |
|
|
854 |
|
855 |
/* |
856 |
* The only way to distinguish between "no more files" and readdir |
857 |
* error is checking errno when readdir() returns NULL. |
858 |
*/ |
859 |
if (readdir_errno) { |
860 |
cur->fts_errno = readdir_errno; |
861 |
/* |
862 |
* If we've not read any items yet, treat |
863 |
* the error as if we can't access the dir. |
864 |
*/ |
865 |
cur->fts_info = nitems ? FTS_ERR : FTS_DNR; |
866 |
} |
867 |
|
842 |
if (dirp) |
868 |
if (dirp) |
843 |
(void)closedir(dirp); |
869 |
(void)closedir(dirp); |
844 |
|
870 |
|
Lines 877-883
mem1: saved_errno = errno;
Link Here
|
877 |
|
903 |
|
878 |
/* If didn't find anything, return NULL. */ |
904 |
/* If didn't find anything, return NULL. */ |
879 |
if (!nitems) { |
905 |
if (!nitems) { |
880 |
if (type == BREAD) |
906 |
if (type == BREAD && |
|
|
907 |
cur->fts_info != FTS_DNR && cur->fts_info != FTS_ERR) |
881 |
cur->fts_info = FTS_DP; |
908 |
cur->fts_info = FTS_DP; |
882 |
return (NULL); |
909 |
return (NULL); |
883 |
} |
910 |
} |