aboutsummaryrefslogtreecommitdiffstats
path: root/tests/sys_stat_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sys_stat_test.cpp')
-rw-r--r--tests/sys_stat_test.cpp124
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);
+}