Skip to content

Commit

Permalink
Enhanced __fxstata to handle AT_SYMLINK_NOFOLLOW
Browse files Browse the repository at this point in the history
This patch also effectively makes unmodified coreutils
find work as expected:

./scripts/manifest_from_host.sh -w find && ./scripts/build fs=rofs --append-manifest
./scripts/run.py -e '/find / -ls'

Signed-off-by: Waldemar Kozaczuk <jwkozaczuk@gmail.com>
Message-Id: <20190519230604.11837-1-jwkozaczuk@gmail.com>
  • Loading branch information
wkozaczuk authored and nyh committed May 20, 2019
1 parent c4c155c commit edcf259
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
11 changes: 6 additions & 5 deletions fs/vfs/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -592,10 +592,6 @@ extern "C"
int __fxstatat(int ver, int dirfd, const char *pathname, struct stat *st,
int flags)
{
if (flags & AT_SYMLINK_NOFOLLOW) {
UNIMPLEMENTED("fstatat() with AT_SYMLINK_NOFOLLOW");
}

if (pathname[0] == '/' || dirfd == AT_FDCWD) {
return stat(pathname, st);
}
Expand Down Expand Up @@ -623,7 +619,12 @@ int __fxstatat(int ver, int dirfd, const char *pathname, struct stat *st,
strlcat(p, "/", PATH_MAX);
strlcat(p, pathname, PATH_MAX);

error = stat(p, st);
if (flags & AT_SYMLINK_NOFOLLOW) {
error = lstat(p, st);
}
else {
error = stat(p, st);
}

vn_unlock(vp);
fdrop(fp);
Expand Down
12 changes: 11 additions & 1 deletion tests/tst-fstatat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ int main(int argc, char **argv)
expect(fstatat(-1, "/tmp/f1", &st, 0), 0);
expect(st.st_size, (off_t)0);
expect_errno(fstatat(-1, "/tmp/f2", &st, 0), ENOENT);
expect_errno(fstatat(-1, "/tmp/f2", &st, AT_SYMLINK_NOFOLLOW), ENOENT);

// test paths relative to cwd:
char* oldwd = getcwd(NULL, 0);
Expand All @@ -54,6 +55,7 @@ int main(int argc, char **argv)
expect(fstatat(AT_FDCWD, "f1", &st, 0), 0);
expect(st.st_size, (off_t)0);
expect_errno(fstatat(AT_FDCWD, "f2", &st, 0), ENOENT);
expect_errno(fstatat(AT_FDCWD, "f2", &st, AT_SYMLINK_NOFOLLOW), ENOENT);

// test paths relative to open directory:
chdir("/");
Expand All @@ -63,17 +65,25 @@ int main(int argc, char **argv)
expect(fstatat(dir, "f1", &st, 0), 0);
expect(st.st_size, (off_t)0);
expect_errno(fstatat(dir, "f2", &st, 0), ENOENT);
expect_errno(fstatat(dir, "f2", &st, AT_SYMLINK_NOFOLLOW), ENOENT);
close(dir);

// test operating on an open file itself (not a directory)
expect((dir = open("/tmp/f1", 0, O_PATH)) >= 0, true);
st.st_size = 123;
expect(fstatat(dir, "", &st, AT_EMPTY_PATH), 0);
expect(st.st_size, (off_t)0);
close(dir);

// test AT_SYMLINK_NOFOLLOW with actual symlink
expect(symlink("/tmp/f1", "/tmp/symlink"), 0);
expect((dir = open("/tmp", 0, O_DIRECTORY)) >= 0, true);
expect(fstatat(dir, "symlink", &st, AT_SYMLINK_NOFOLLOW), 0);
expect(S_ISLNK(st.st_mode) != 0, true);

close(dir);
chdir(oldwd);
free(oldwd);
remove("/tmp/symlink");
remove("/tmp/f1");

std::cout << "SUMMARY: " << tests << " tests, " << fails << " failures\n";
Expand Down

0 comments on commit edcf259

Please sign in to comment.