diff options
Diffstat (limited to 'tests/sys_stat_test.cpp')
-rw-r--r-- | tests/sys_stat_test.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/tests/sys_stat_test.cpp b/tests/sys_stat_test.cpp index e46577469..7bbb7c665 100644 --- a/tests/sys_stat_test.cpp +++ b/tests/sys_stat_test.cpp @@ -95,3 +95,127 @@ TEST(sys_stat, stat64_lstat64_fstat64) { ASSERT_EQ(0, fstat64(fd, &sb)); close(fd); } + +TEST(sys_stat, fchmodat_EFAULT_file) { + ASSERT_EQ(-1, fchmodat(AT_FDCWD, (char *) 0x1, 0751, 0)); + ASSERT_EQ(EFAULT, errno); +} + +TEST(sys_stat, fchmodat_AT_SYMLINK_NOFOLLOW_EFAULT_file) { + ASSERT_EQ(-1, fchmodat(AT_FDCWD, (char *) 0x1, 0751, AT_SYMLINK_NOFOLLOW)); +#if defined(__BIONIC__) + ASSERT_EQ(EFAULT, errno); +#else + // glibc 2.19 does not implement AT_SYMLINK_NOFOLLOW and always + // returns ENOTSUP + ASSERT_EQ(ENOTSUP, errno); +#endif +} + +TEST(sys_stat, fchmodat_bad_flags) { + ASSERT_EQ(-1, fchmodat(AT_FDCWD, "/blah", 0751, ~AT_SYMLINK_NOFOLLOW)); + ASSERT_EQ(EINVAL, errno); +} + +TEST(sys_stat, fchmodat_bad_flags_ALL) { + ASSERT_EQ(-1, fchmodat(AT_FDCWD, "/blah", 0751, ~0)); + ASSERT_EQ(EINVAL, errno); +} + +TEST(sys_stat, fchmodat_nonexistant_file) { + ASSERT_EQ(-1, fchmodat(AT_FDCWD, "/blah", 0751, 0)); + ASSERT_EQ(ENOENT, errno); +} + +TEST(sys_stat, fchmodat_AT_SYMLINK_NOFOLLOW_nonexistant_file) { + ASSERT_EQ(-1, fchmodat(AT_FDCWD, "/blah", 0751, AT_SYMLINK_NOFOLLOW)); +#if defined(__BIONIC__) + ASSERT_EQ(ENOENT, errno); +#else + // glibc 2.19 does not implement AT_SYMLINK_NOFOLLOW and always + // returns ENOTSUP + ASSERT_EQ(ENOTSUP, errno); +#endif +} + +TEST(sys_stat, fchmodat_file) { + TemporaryFile tf; + struct stat sb; + + ASSERT_EQ(0, fchmodat(AT_FDCWD, tf.filename, 0751, 0)); + ASSERT_EQ(0, fstat(tf.fd, &sb)); + ASSERT_TRUE(0751 == (sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))); +} + +TEST(sys_stat, fchmodat_AT_SYMLINK_NOFOLLOW_file) { + TemporaryFile tf; + errno = 0; + int result = fchmodat(AT_FDCWD, tf.filename, 0751, AT_SYMLINK_NOFOLLOW); + +#if defined(__BIONIC__) + struct stat sb; + ASSERT_EQ(0, result); + ASSERT_EQ(0, errno); + ASSERT_EQ(0, fstat(tf.fd, &sb)); + ASSERT_TRUE(0751 == (sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))); +#else + // glibc 2.19 does not implement AT_SYMLINK_NOFOLLOW and always + // returns ENOTSUP + ASSERT_EQ(-1, result); + ASSERT_EQ(ENOTSUP, errno); +#endif +} + +TEST(sys_stat, fchmodat_symlink) { + TemporaryFile tf; + char linkname[255]; + struct stat sb; + + snprintf(linkname, sizeof(linkname), "%s.link", tf.filename); + + ASSERT_EQ(0, symlink(tf.filename, linkname)); + ASSERT_EQ(0, fchmodat(AT_FDCWD, linkname, 0751, 0)); + ASSERT_EQ(0, fstat(tf.fd, &sb)); + ASSERT_TRUE(0751 == (sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))); + unlink(linkname); +} + +TEST(sys_stat, fchmodat_dangling_symlink) { + TemporaryFile tf; + char linkname[255]; + char target[255]; + + snprintf(linkname, sizeof(linkname), "%s.link", tf.filename); + snprintf(target, sizeof(target), "%s.doesnotexist", tf.filename); + + ASSERT_EQ(0, symlink(target, linkname)); + ASSERT_EQ(-1, fchmodat(AT_FDCWD, linkname, 0751, 0)); + ASSERT_EQ(ENOENT, errno); + unlink(linkname); +} + +TEST(sys_stat, fchmodat_AT_SYMLINK_NOFOLLOW_with_symlink) { + TemporaryFile tf; + char linkname[255]; + + snprintf(linkname, sizeof(linkname), "%s.link", tf.filename); + + ASSERT_EQ(0, symlink(tf.filename, linkname)); + ASSERT_EQ(-1, fchmodat(AT_FDCWD, linkname, 0751, AT_SYMLINK_NOFOLLOW)); + ASSERT_EQ(ENOTSUP, errno); + unlink(linkname); +} + +TEST(sys_stat, fchmodat_AT_SYMLINK_NOFOLLOW_with_dangling_symlink) { + TemporaryFile tf; + char linkname[255]; + char target[255]; + + snprintf(linkname, sizeof(linkname), "%s.link", tf.filename); + snprintf(target, sizeof(target), "%s.doesnotexist", tf.filename); + + ASSERT_EQ(0, symlink(target, linkname)); + ASSERT_EQ(-1, fchmodat(AT_FDCWD, linkname, 0751, AT_SYMLINK_NOFOLLOW)); + ASSERT_EQ(ENOTSUP, errno); + unlink(linkname); +} |