| #include "../../unity/unity.h" |
|
|
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <errno.h> |
| #include <stdio.h> |
|
|
| |
| |
| |
|
|
| |
| extern bool force_silent; |
|
|
| |
| static mode_t get_mode(const char *path) { |
| struct stat st; |
| TEST_ASSERT_EQUAL_INT_MESSAGE(0, stat(path, &st), "stat on temp file failed"); |
| return st.st_mode; |
| } |
|
|
| static void make_temp_path(char *buf, size_t buflen) { |
| |
| snprintf(buf, buflen, "/tmp/chmod_mode_changed_%ld_XXXXXX", (long)getpid()); |
| } |
|
|
| static void create_temp_file(char *path_buf, size_t buflen) { |
| make_temp_path(path_buf, buflen); |
| int fd = mkstemp(path_buf); |
| TEST_ASSERT_MESSAGE(fd >= 0, "mkstemp failed"); |
| |
| close(fd); |
| } |
|
|
| static void remove_temp_file(const char *path) { |
| |
| unlink(path); |
| } |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| void test_mode_changed_no_special_no_change(void) { |
| char path[256]; |
| create_temp_file(path, sizeof(path)); |
|
|
| mode_t old_mode = get_mode(path); |
| mode_t new_mode = old_mode; |
|
|
| bool changed = mode_changed(AT_FDCWD, path, path, old_mode, new_mode); |
| TEST_ASSERT_FALSE(changed); |
|
|
| remove_temp_file(path); |
| } |
|
|
| |
| void test_mode_changed_no_special_with_change(void) { |
| char path[256]; |
| create_temp_file(path, sizeof(path)); |
|
|
| mode_t old_mode = get_mode(path); |
| |
| mode_t new_mode = old_mode ^ S_IXUSR; |
|
|
| bool changed = mode_changed(AT_FDCWD, path, path, old_mode, new_mode); |
| TEST_ASSERT_TRUE(changed); |
|
|
| remove_temp_file(path); |
| } |
|
|
| |
| void test_mode_changed_special_fstatat_failure(void) { |
| |
| bool prev_silent = force_silent; |
| force_silent = true; |
|
|
| const char *missing = "/this/path/does/not/exist/___definitely___"; |
| mode_t old_mode = 0; |
| |
| mode_t new_mode = old_mode | S_ISUID; |
|
|
| bool changed = mode_changed(AT_FDCWD, missing, missing, old_mode, new_mode); |
| TEST_ASSERT_FALSE(changed); |
|
|
| force_silent = prev_silent; |
| } |
|
|
| |
| void test_mode_changed_special_no_actual_change(void) { |
| char path[256]; |
| create_temp_file(path, sizeof(path)); |
|
|
| mode_t old_mode = get_mode(path); |
| |
| mode_t new_mode = old_mode | S_ISUID; |
|
|
| bool changed = mode_changed(AT_FDCWD, path, path, old_mode, new_mode); |
| TEST_ASSERT_FALSE(changed); |
|
|
| remove_temp_file(path); |
| } |
|
|
| |
| void test_mode_changed_special_actual_change(void) { |
| char path[256]; |
| create_temp_file(path, sizeof(path)); |
|
|
| mode_t old_mode = get_mode(path); |
| |
| mode_t changed_perm = (old_mode ^ S_IXUSR) & 07777; |
| int rc = chmod(path, changed_perm); |
| TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "chmod to alter file mode failed"); |
|
|
| |
| mode_t new_mode_param = old_mode | S_ISUID; |
|
|
| bool changed = mode_changed(AT_FDCWD, path, path, old_mode, new_mode_param); |
| TEST_ASSERT_TRUE(changed); |
|
|
| |
| chmod(path, old_mode & 07777); |
| remove_temp_file(path); |
| } |
|
|
| |
| void test_mode_changed_ignores_file_type_bits(void) { |
| |
| mode_t old_mode = S_IFREG | 0644; |
| mode_t new_mode = S_IFDIR | 0644; |
|
|
| bool changed = mode_changed(AT_FDCWD, "unused", "unused", old_mode, new_mode); |
| TEST_ASSERT_FALSE(changed); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
|
|
| RUN_TEST(test_mode_changed_no_special_no_change); |
| RUN_TEST(test_mode_changed_no_special_with_change); |
| RUN_TEST(test_mode_changed_special_fstatat_failure); |
| RUN_TEST(test_mode_changed_special_no_actual_change); |
| RUN_TEST(test_mode_changed_special_actual_change); |
| RUN_TEST(test_mode_changed_ignores_file_type_bits); |
|
|
| return UNITY_END(); |
| } |