#include #include #include #include #include #include #include #include #include "zdtmtst.h" const char *test_doc = "Check that attributes and content of an open, " "written to, and then unlinked file migrate " "correctly"; const char *test_author = "Roman Kagan "; char *filename; TEST_OPTION(filename, string, "file name", 1); #define DEF_PERMS 06604 /* -rwS--Sr--, really esoteric one */ unsigned int perms = DEF_PERMS; TEST_OPTION(perms, uint, "permissions to set on file " "(default " __stringify(DEF_PERMS) ")", 0); #define DEF_MTIME 123456 /* another really esoteric one */ unsigned int mtime = DEF_MTIME; TEST_OPTION(mtime, uint, "mtime to set on file " "(default " __stringify(DEF_MTIME) ")", 0); int main(int argc, char **argv) { int fd; struct utimbuf ut; uint32_t crc; struct stat st; uint8_t buf[1000000]; test_init(argc, argv); fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd < 0) { pr_perror("can't open %s", filename); exit(1); } crc = ~0; datagen(buf, sizeof(buf), &crc); if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { pr_perror("can't write to %s", filename); exit(1); } ut = (struct utimbuf){ .actime = 0, .modtime = mtime, }; if (utime(filename, &ut)) { pr_perror("can't set modtime %d on %s", mtime, filename); exit(1); } if (fchmod(fd, perms)) { pr_perror("can't set perms %o on %s", perms, filename); exit(1); } if (unlink(filename)) { pr_perror("can't unlink %s", filename); exit(1); } test_daemon(); test_waitsig(); if (lseek(fd, 0, SEEK_SET) < 0) { fail("lseeking to the beginning of file failed"); goto out; } if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { fail("can't read %s", filename); goto out; } crc = ~0; if (datachk(buf, sizeof(buf), &crc)) { fail("CRC mismatch"); goto out; } if (fstat(fd, &st) < 0) { fail("can't fstat %s", filename); goto out; } if ((st.st_mode & 07777) != perms) { fail("permissions have changed"); goto out; } if (st.st_mtime != mtime) { fail("modification time has changed"); goto out; } if (close(fd)) { fail("close failed"); goto out_noclose; } if (unlink(filename) != -1 || errno != ENOENT) { fail("file %s should have been deleted before migration: unlink", filename); goto out_noclose; } pass(); out: close(fd); out_noclose: return 0; }