blob: 4c5d3c01b9f4c426277ec0b78551a38d4a399ffb [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Test ctime and mtime are updated on truncate(2) and ftruncate(2)
* Copyright (c) 2013 Red Hat, Inc. All Rights Reserved.
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define TEST_MSG "this is a test string"
int do_test(const char *file, int is_ftrunc)
{
int ret;
int fd;
struct stat statbuf1;
struct stat statbuf2;
ret = 0;
fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open(2) failed");
exit(EXIT_FAILURE);
}
ret = write(fd, TEST_MSG, sizeof(TEST_MSG));
if (ret == -1) {
perror("write(2) failed");
exit(EXIT_FAILURE);
}
/* Get timestamps before [f]truncate(2) */
ret = fstat(fd, &statbuf1);
if (ret == -1) {
perror("fstat(2) failed");
exit(EXIT_FAILURE);
}
/* Test [f]truncate(2) down */
sleep(1);
if (is_ftrunc) {
ret = ftruncate(fd, 0);
if (ret == -1) {
perror("ftruncate(2) down failed");
exit(EXIT_FAILURE);
}
} else {
ret = truncate(file, 0);
if (ret == -1) {
perror("truncate(2) down failed");
exit(EXIT_FAILURE);
}
}
/* Get timestamps after [f]truncate(2) */
ret = fstat(fd, &statbuf2);
if (ret == -1) {
perror("fstat(2) failed");
exit(EXIT_FAILURE);
}
/* Check whether timestamps got updated on [f]truncate(2) down */
if (statbuf1.st_ctime == statbuf2.st_ctime) {
fprintf(stderr, "ctime not updated after %s\n",
is_ftrunc ? "ftruncate" : "truncate" " down");
ret++;
}
if (statbuf1.st_mtime == statbuf2.st_mtime) {
fprintf(stderr, "mtime not updated after %s\n",
is_ftrunc ? "ftruncate" : "truncate" " down");
ret++;
}
/* Test [f]truncate(2) up */
sleep(1);
if (is_ftrunc) {
ret = ftruncate(fd, 123);
if (ret == -1) {
perror("ftruncate(2) up failed");
exit(EXIT_FAILURE);
}
} else {
ret = truncate(file, 123);
if (ret == -1) {
perror("truncate(2) up failed");
exit(EXIT_FAILURE);
}
}
ret = fstat(fd, &statbuf1);
if (ret == -1) {
perror("fstat(2) failed");
exit(EXIT_FAILURE);
}
/* Check whether timestamps got updated on [f]truncate(2) up */
if (statbuf1.st_ctime == statbuf2.st_ctime) {
fprintf(stderr, "ctime not updated after %s\n",
is_ftrunc ? "ftruncate" : "truncate" " up");
ret++;
}
if (statbuf1.st_mtime == statbuf2.st_mtime) {
fprintf(stderr, "mtime not updated after %s\n",
is_ftrunc ? "ftruncate" : "truncate" " up");
ret++;
}
close(fd);
return ret;
}
int main(int argc, char *argv[])
{
int ret;
char *testfile;
ret = 0;
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
exit(EXIT_FAILURE);
}
testfile = argv[1];
ret = do_test(testfile, 0);
ret += do_test(testfile, 1);
exit(ret);
}