[Toybox] dirtree: add DIRTREE_NOSTAT flag
Mark Salyzyn
salyzyn at android.com
Wed Oct 26 13:12:55 PDT 2016
>From the AOSP gerrit fixing internal bug 32399196
( https://android-review.googlesource.com/#/c/295731 )
Change subject: dirtree: add DIRTREE_NOSTAT flag
Prevents a superfluous attribute request. Flag returned on callbacks,
subsequent recursive callbacks have a responsibility to issue:
fstatat(dirtree_parentfd(dirtree), dirtree->name, &dirtree->st,
AT_SYMLINK_NOFOLLOW);
to fill in stat details on file name entries of interests. This
allows for precise control over which file(s) get stat() information.
Test: manual in combination with 'ps: only stat() /proc/<pid>'
looking for selinux getattr violations for /proc/iomem
or /proc/sysrq-trigger.
Change-Id: I1aa5f2104b7ddd5587ee9608012530aab46a0f66
---
lib/dirtree.c | 20 +++++++++++---------
lib/lib.h | 3 +++
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/lib/dirtree.c b/lib/dirtree.c
index 8f235ed..81559d6 100644
--- a/lib/dirtree.c
+++ b/lib/dirtree.c
@@ -31,21 +31,23 @@ struct dirtree *dirtree_add_node(struct dirtree *parent, char *name, int flags)
int len = 0, linklen = 0;
if (name) {
- // open code this because haven't got node to call dirtree_parentfd() on yet
- int fd = parent ? parent->dirfd : AT_FDCWD;
-
- if (fstatat(fd, name, &st, AT_SYMLINK_NOFOLLOW*!(flags&DIRTREE_SYMFOLLOW)))
- goto error;
- if (S_ISLNK(st.st_mode)) {
- if (0>(linklen = readlinkat(fd, name, libbuf, 4095))) goto error;
- libbuf[linklen++]=0;
+ if (!(flags & DIRTREE_NOSTAT)) {
+ // open code this because haven't got node to call dirtree_parentfd() on yet
+ int fd = parent ? parent->dirfd : AT_FDCWD;
+
+ if (fstatat(fd, name, &st, AT_SYMLINK_NOFOLLOW*!(flags&DIRTREE_SYMFOLLOW)))
+ goto error;
+ if (S_ISLNK(st.st_mode)) {
+ if (0>(linklen = readlinkat(fd, name, libbuf, 4095))) goto error;
+ libbuf[linklen++]=0;
+ }
}
len = strlen(name);
}
dt = xzalloc((len = sizeof(struct dirtree)+len+1)+linklen);
dt->parent = parent;
if (name) {
- memcpy(&(dt->st), &st, sizeof(struct stat));
+ if (!(flags & DIRTREE_NOSTAT)) memcpy(&(dt->st), &st, sizeof(struct stat));
strcpy(dt->name, name);
if (linklen) dt->symlink = memcpy(len+(char *)dt, libbuf, linklen);
diff --git a/lib/lib.h b/lib/lib.h
index 2afe558..06393fb 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -73,6 +73,9 @@ void get_optflags(void);
#define DIRTREE_SHUTUP 16
// Breadth first traversal, conserves filehandles at the expense of memory
#define DIRTREE_BREADTH 32
+// Do not stat the files. st and symlink on a recurse pass will be all zero.
+// Callback can fill in these fields afterwards, likely after filename checking.
+#define DIRTREE_NOSTAT 64
// Don't look at any more files in this directory.
#define DIRTREE_ABORT 256
More information about the Toybox
mailing list