Skip to content
Snippets Groups Projects
Commit b4be0a80 authored by Theodore Dubois's avatar Theodore Dubois Committed by CQ bot account: commit-bot@chromium.org
Browse files

[libc] Delete ftw/nftw header files and implementation

The implementations weren't being compiled in, so why have the headers.

Change-Id: I58f8980e943aad253e65514998bac42c6c64058a
parent e5de6c1f
No related branches found
No related tags found
No related merge requests found
......@@ -177,7 +177,6 @@ library("c") {
"float.h",
"fmtmsg.h",
"fnmatch.h",
"ftw.h",
"getopt.h",
"glob.h",
"grp.h",
......
#ifndef SYSROOT_FTW_H_
#define SYSROOT_FTW_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <features.h>
#include <sys/stat.h>
#define FTW_F 1
#define FTW_D 2
#define FTW_DNR 3
#define FTW_NS 4
#define FTW_SL 5
#define FTW_DP 6
#define FTW_SLN 7
#define FTW_PHYS 1
#define FTW_MOUNT 2
#define FTW_CHDIR 4
#define FTW_DEPTH 8
struct FTW {
int base;
int level;
};
int ftw(const char*, int (*)(const char*, const struct stat*, int), int);
int nftw(const char*, int (*)(const char*, const struct stat*, int, struct FTW*), int, int);
#ifdef __cplusplus
}
#endif
#endif // SYSROOT_FTW_H_
#include <ftw.h>
int ftw(const char* path, int (*fn)(const char*, const struct stat*, int), int fd_limit) {
/* The following cast assumes that calling a function with one
* argument more than it needs behaves as expected. This is
* actually undefined, but works on all real-world machines. */
return nftw(path, (int (*)(const char*, const struct stat*, int, struct FTW*))fn, fd_limit, FTW_PHYS);
}
#include <dirent.h>
#include <errno.h>
#include <ftw.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
struct history {
struct history* chain;
dev_t dev;
ino_t ino;
int level;
int base;
};
#undef dirfd
#define dirfd(d) (*(int*)d)
static int do_nftw(char* path, int (*fn)(const char*, const struct stat*, int, struct FTW*),
int fd_limit, int flags, struct history* h) {
size_t l = strlen(path), j = l && path[l - 1] == '/' ? l - 1 : l;
struct stat st;
struct history new;
int type;
int r;
struct FTW lev;
char* name;
if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {
if (!(flags & FTW_PHYS) && errno == ENOENT && !lstat(path, &st))
type = FTW_SLN;
else if (errno != EACCES)
return -1;
else
type = FTW_NS;
} else if (S_ISDIR(st.st_mode)) {
if (access(path, R_OK) < 0)
type = FTW_DNR;
else if (flags & FTW_DEPTH)
type = FTW_DP;
else
type = FTW_D;
} else if (S_ISLNK(st.st_mode)) {
if (flags & FTW_PHYS)
type = FTW_SL;
else
type = FTW_SLN;
} else {
type = FTW_F;
}
if ((flags & FTW_MOUNT) && h && st.st_dev != h->dev)
return 0;
new.chain = h;
new.dev = st.st_dev;
new.ino = st.st_ino;
new.level = h ? h->level + 1 : 0;
new.base = l + 1;
lev.level = new.level;
lev.base = h ? h->base : (name = strrchr(path, '/')) ? name - path : 0;
if (!(flags & FTW_DEPTH) && (r = fn(path, &st, type, &lev)))
return r;
for (; h; h = h->chain)
if (h->dev == st.st_dev && h->ino == st.st_ino)
return 0;
if ((type == FTW_D || type == FTW_DP) && fd_limit) {
DIR* d = opendir(path);
if (d) {
struct dirent* de;
while ((de = readdir(d))) {
if (de->d_name[0] == '.' &&
(!de->d_name[1] || (de->d_name[1] == '.' && !de->d_name[2])))
continue;
if (strlen(de->d_name) >= PATH_MAX - l) {
errno = ENAMETOOLONG;
closedir(d);
return -1;
}
path[j] = '/';
strcpy(path + j + 1, de->d_name);
if ((r = do_nftw(path, fn, fd_limit - 1, flags, &new))) {
closedir(d);
return r;
}
}
closedir(d);
} else if (errno != EACCES) {
return -1;
}
}
path[l] = 0;
if ((flags & FTW_DEPTH) && (r = fn(path, &st, type, &lev)))
return r;
return 0;
}
int nftw(const char* path, int (*fn)(const char*, const struct stat*, int, struct FTW*),
int fd_limit, int flags) {
size_t l;
char pathbuf[PATH_MAX + 1];
if (fd_limit <= 0)
return 0;
l = strlen(path);
if (l > PATH_MAX) {
errno = ENAMETOOLONG;
return -1;
}
memcpy(pathbuf, path, l + 1);
return do_nftw(pathbuf, fn, fd_limit, flags, NULL);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment