summaryrefslogtreecommitdiffstats
path: root/bftw.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-02-04 23:12:08 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-02-04 23:12:08 -0500
commit0f91c5861cacaeb17729b7727d07260273345393 (patch)
tree8348044cc4697e2576a401fe81c2d5bca7dbc0eb /bftw.c
parentc9905877cb06f71c4523e4f4875bf549b6b54060 (diff)
downloadbfs-0f91c5861cacaeb17729b7727d07260273345393.tar.xz
Implement -P and -H.
Diffstat (limited to 'bftw.c')
-rw-r--r--bftw.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/bftw.c b/bftw.c
index 99e26e1..a49cbed 100644
--- a/bftw.c
+++ b/bftw.c
@@ -471,8 +471,8 @@ static void ftwbuf_use_dirent(struct BFTW *ftwbuf, const struct dirent *de) {
#endif
}
-static int ftwbuf_stat(struct BFTW *ftwbuf, struct stat *sb) {
- int ret = fstatat(ftwbuf->at_fd, ftwbuf->at_path, sb, AT_SYMLINK_NOFOLLOW);
+static int ftwbuf_stat(struct BFTW *ftwbuf, struct stat *sb, int flags) {
+ int ret = fstatat(ftwbuf->at_fd, ftwbuf->at_path, sb, flags);
if (ret != 0) {
return ret;
}
@@ -620,8 +620,18 @@ static void bftw_init_buffers(struct bftw_state *state, const struct dirent *de)
ftwbuf->typeflag = BFTW_UNKNOWN;
}
- if ((state->flags & BFTW_STAT) || ftwbuf->typeflag == BFTW_UNKNOWN) {
- if (ftwbuf_stat(ftwbuf, &state->statbuf) != 0) {
+ bool follow;
+ if (state->flags & BFTW_FOLLOW_ROOT) {
+ follow = !state->current;
+ } else {
+ follow = false;
+ }
+
+ if ((state->flags & BFTW_STAT)
+ || ftwbuf->typeflag == BFTW_UNKNOWN
+ || (ftwbuf->typeflag == BFTW_LNK && follow)) {
+ int flags = follow ? 0 : AT_SYMLINK_NOFOLLOW;
+ if (ftwbuf_stat(ftwbuf, &state->statbuf, flags) != 0) {
state->error = errno;
ftwbuf_set_error(ftwbuf, state->error);
}