/* Test whether a basic utimensat invocation works. */ #include #include #include #include #include #include "../basic.h" static const char* temporary; static void cleanup(void) { if ( temporary ) unlink(temporary); } int main(void) { if ( atexit(cleanup) ) err(1, "atexit"); const char* tmpdir = getenv("TMPDIR"); if ( !tmpdir ) tmpdir = "/tmp"; size_t template_len = strlen(tmpdir) + strlen("/os-test.XXXXXX"); char* template = malloc(template_len + 1); if ( !template ) err(1, "malloc"); strcpy(template, tmpdir); strcat(template, "/os-test.XXXXXX"); int fd = mkstemp(template); if ( fd < 0 ) err(1, "mkstemp"); temporary = template; char* basename = strrchr(template, '/') + 1; int dirfd = open(tmpdir, O_RDONLY | O_DIRECTORY); if ( dirfd < 0 ) err(1, "open: tmpdir"); struct timespec times[2] = { { .tv_sec = 2025, .tv_nsec = 1 }, { .tv_sec = 2026, .tv_nsec = 2 }, }; if ( utimensat(dirfd, basename, times, AT_SYMLINK_NOFOLLOW) < 0 ) err(1, "utimensat"); struct stat st; if ( fstat(fd, &st) < 0 ) err(1, "fstat"); if ( st.st_atim.tv_sec != times[0].tv_sec ) errx(1, "futimens did not set atim"); if ( st.st_mtim.tv_sec != times[1].tv_sec ) errx(1, "futimens did not set mtim"); return 0; }