xfs: skip tests that rely on allocation behaviors of the data device
[xfstests-dev.git] / src / t_truncate_cmtime.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Test ctime and mtime are updated on truncate(2) and ftruncate(2)
4  * Copyright (c) 2013 Red Hat, Inc.  All Rights Reserved.
5  */
6
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13
14 #define TEST_MSG "this is a test string"
15
16 int do_test(const char *file, int is_ftrunc)
17 {
18         int ret;
19         int fd;
20         struct stat statbuf1;
21         struct stat statbuf2;
22
23         ret = 0;
24         fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644);
25         if (fd == -1) {
26                 perror("open(2) failed");
27                 exit(EXIT_FAILURE);
28         }
29
30         ret = write(fd, TEST_MSG, sizeof(TEST_MSG));
31         if (ret == -1) {
32                 perror("write(2) failed");
33                 exit(EXIT_FAILURE);
34         }
35
36         /* Get timestamps before [f]truncate(2) */
37         ret = fstat(fd, &statbuf1);
38         if (ret == -1) {
39                 perror("fstat(2) failed");
40                 exit(EXIT_FAILURE);
41         }
42
43         /* Test [f]truncate(2) down */
44         sleep(1);
45         if (is_ftrunc) {
46                 ret = ftruncate(fd, 0);
47                 if (ret == -1) {
48                         perror("ftruncate(2) down failed");
49                         exit(EXIT_FAILURE);
50                 }
51         } else {
52                 ret = truncate(file, 0);
53                 if (ret == -1) {
54                         perror("truncate(2) down failed");
55                         exit(EXIT_FAILURE);
56                 }
57         }
58
59         /* Get timestamps after [f]truncate(2) */
60         ret = fstat(fd, &statbuf2);
61         if (ret == -1) {
62                 perror("fstat(2) failed");
63                 exit(EXIT_FAILURE);
64         }
65
66         /* Check whether timestamps got updated on [f]truncate(2) down */
67         if (statbuf1.st_ctime == statbuf2.st_ctime) {
68                 fprintf(stderr, "ctime not updated after %s\n",
69                         is_ftrunc ? "ftruncate" : "truncate" " down");
70                 ret++;
71         }
72         if (statbuf1.st_mtime == statbuf2.st_mtime) {
73                 fprintf(stderr, "mtime not updated after %s\n",
74                         is_ftrunc ? "ftruncate" : "truncate" " down");
75                 ret++;
76         }
77
78         /* Test [f]truncate(2) up */
79         sleep(1);
80         if (is_ftrunc) {
81                 ret = ftruncate(fd, 123);
82                 if (ret == -1) {
83                         perror("ftruncate(2) up failed");
84                         exit(EXIT_FAILURE);
85                 }
86         } else {
87                 ret = truncate(file, 123);
88                 if (ret == -1) {
89                         perror("truncate(2) up failed");
90                         exit(EXIT_FAILURE);
91                 }
92         }
93         ret = fstat(fd, &statbuf1);
94         if (ret == -1) {
95                 perror("fstat(2) failed");
96                 exit(EXIT_FAILURE);
97         }
98         /* Check whether timestamps got updated on [f]truncate(2) up */
99         if (statbuf1.st_ctime == statbuf2.st_ctime) {
100                 fprintf(stderr, "ctime not updated after %s\n",
101                         is_ftrunc ? "ftruncate" : "truncate" " up");
102                 ret++;
103         }
104         if (statbuf1.st_mtime == statbuf2.st_mtime) {
105                 fprintf(stderr, "mtime not updated after %s\n",
106                         is_ftrunc ? "ftruncate" : "truncate" " up");
107                 ret++;
108         }
109
110         close(fd);
111         return ret;
112 }
113
114 int main(int argc, char *argv[])
115 {
116         int ret;
117         char *testfile;
118
119         ret = 0;
120         if (argc != 2) {
121                 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
122                 exit(EXIT_FAILURE);
123         }
124         testfile = argv[1];
125
126         ret = do_test(testfile, 0);
127         ret += do_test(testfile, 1);
128
129         exit(ret);
130 }