]>
git.proxmox.com Git - wasi-libc.git/blob - libc-top-half/musl/src/misc/nftw.c
8 #if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
14 struct history
*chain
;
22 #define dirfd(d) (*(int *)d)
24 static int do_nftw(char *path
, int (*fn
)(const char *, const struct stat
*, int, struct FTW
*), int fd_limit
, int flags
, struct history
*h
)
26 size_t l
= strlen(path
), j
= l
&& path
[l
-1]=='/' ? l
-1 : l
;
33 if ((flags
& FTW_PHYS
) ? lstat(path
, &st
) : stat(path
, &st
) < 0) {
34 if (!(flags
& FTW_PHYS
) && errno
==ENOENT
&& !lstat(path
, &st
))
36 else if (errno
!= EACCES
) return -1;
38 } else if (S_ISDIR(st
.st_mode
)) {
39 if (access(path
, R_OK
) < 0) type
= FTW_DNR
;
40 else if (flags
& FTW_DEPTH
) type
= FTW_DP
;
42 } else if (S_ISLNK(st
.st_mode
)) {
43 if (flags
& FTW_PHYS
) type
= FTW_SL
;
49 if ((flags
& FTW_MOUNT
) && h
&& st
.st_dev
!= h
->dev
)
55 new.level
= h
? h
->level
+1 : 0;
58 lev
.level
= new.level
;
63 for (k
=j
; k
&& path
[k
]=='/'; k
--);
64 for (; k
&& path
[k
-1]!='/'; k
--);
68 if (!(flags
& FTW_DEPTH
) && (r
=fn(path
, &st
, type
, &lev
)))
71 for (; h
; h
= h
->chain
)
72 if (h
->dev
== st
.st_dev
&& h
->ino
== st
.st_ino
)
75 if ((type
== FTW_D
|| type
== FTW_DP
) && fd_limit
) {
76 DIR *d
= opendir(path
);
79 while ((de
= readdir(d
))) {
80 if (de
->d_name
[0] == '.'
82 || (de
->d_name
[1]=='.'
83 && !de
->d_name
[2]))) continue;
84 if (strlen(de
->d_name
) >= PATH_MAX
-l
) {
90 strcpy(path
+j
+1, de
->d_name
);
91 if ((r
=do_nftw(path
, fn
, fd_limit
-1, flags
, &new))) {
97 } else if (errno
!= EACCES
) {
103 if ((flags
& FTW_DEPTH
) && (r
=fn(path
, &st
, type
, &lev
)))
109 int nftw(const char *path
, int (*fn
)(const char *, const struct stat
*, int, struct FTW
*), int fd_limit
, int flags
)
113 char pathbuf
[PATH_MAX
+1];
115 if (fd_limit
<= 0) return 0;
119 errno
= ENAMETOOLONG
;
122 memcpy(pathbuf
, path
, l
+1);
124 #if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
125 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &cs
);
127 r
= do_nftw(pathbuf
, fn
, fd_limit
, flags
, NULL
);
128 #if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
129 pthread_setcancelstate(cs
, 0);
134 weak_alias(nftw
, nftw64
);