static void lstat_symlink(const atf_tc_t *tc, const char *mp) { const char *src, *dst; int res; struct stat st; USES_SYMLINKS; if (FSTYPE_V7FS(tc)) atf_tc_expect_fail("PR kern/48864"); FSTEST_ENTER(); src = "source"; dst = "destination"; res = rump_sys_symlink(src, dst); ATF_REQUIRE(res != -1); res = rump_sys_lstat(dst, &st); ATF_REQUIRE(res != -1); ATF_CHECK(S_ISLNK(st.st_mode) != 0); ATF_CHECK(st.st_size == (off_t)strlen(src)); FSTEST_EXIT(); }
static void attrs(const atf_tc_t *tc, const char *mp) { struct stat sb, sb2; struct timeval tv[2]; int fd; FSTEST_ENTER(); RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755)); RL(rump_sys_close(fd)); RL(rump_sys_stat(TESTFILE, &sb)); if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) { RL(rump_sys_chown(TESTFILE, 1, 2)); sb.st_uid = 1; sb.st_gid = 2; RL(rump_sys_chmod(TESTFILE, 0123)); sb.st_mode = (sb.st_mode & ~ACCESSPERMS) | 0123; } tv[0].tv_sec = 1000000000; /* need something >1980 for msdosfs */ tv[0].tv_usec = 1; tv[1].tv_sec = 1000000002; /* need even seconds for msdosfs */ tv[1].tv_usec = 3; RL(rump_sys_utimes(TESTFILE, tv)); RL(rump_sys_utimes(TESTFILE, tv)); /* XXX: utimes & birthtime */ sb.st_atimespec.tv_sec = 1000000000; sb.st_atimespec.tv_nsec = 1000; sb.st_mtimespec.tv_sec = 1000000002; sb.st_mtimespec.tv_nsec = 3000; RL(rump_sys_stat(TESTFILE, &sb2)); #define CHECK(a) ATF_REQUIRE_EQ(sb.a, sb2.a) if (FSTYPE_ZFS(tc)) atf_tc_expect_fail("PR kern/47656: Test known to be broken"); if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) { CHECK(st_uid); CHECK(st_gid); CHECK(st_mode); } if (!FSTYPE_MSDOS(tc)) { /* msdosfs has only access date, not time */ CHECK(st_atimespec.tv_sec); } CHECK(st_mtimespec.tv_sec); if (!(FSTYPE_EXT2FS(tc) || FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc) || FSTYPE_V7FS(tc))) { CHECK(st_atimespec.tv_nsec); CHECK(st_mtimespec.tv_nsec); } #undef CHECK FSTEST_EXIT(); }