log-writes: Add support to output human readable flags
[xfstests-dev.git] / src / t_truncate_cmtime.c
1 /*
2  * Test ctime and mtime are updated on truncate(2) and ftruncate(2)
3  *
4  * Copyright (c) 2013 Red Hat, Inc.  All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it would be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write the Free Software Foundation,
17  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26
27 #define TEST_MSG "this is a test string"
28
29 int do_test(const char *file, int is_ftrunc)
30 {
31         int ret;
32         int fd;
33         struct stat statbuf1;
34         struct stat statbuf2;
35
36         ret = 0;
37         fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644);
38         if (fd == -1) {
39                 perror("open(2) failed");
40                 exit(EXIT_FAILURE);
41         }
42
43         ret = write(fd, TEST_MSG, sizeof(TEST_MSG));
44         if (ret == -1) {
45                 perror("write(2) failed");
46                 exit(EXIT_FAILURE);
47         }
48
49         /* Get timestamps before [f]truncate(2) */
50         ret = fstat(fd, &statbuf1);
51         if (ret == -1) {
52                 perror("fstat(2) failed");
53                 exit(EXIT_FAILURE);
54         }
55
56         /* Test [f]truncate(2) down */
57         sleep(1);
58         if (is_ftrunc) {
59                 ret = ftruncate(fd, 0);
60                 if (ret == -1) {
61                         perror("ftruncate(2) down failed");
62                         exit(EXIT_FAILURE);
63                 }
64         } else {
65                 ret = truncate(file, 0);
66                 if (ret == -1) {
67                         perror("truncate(2) down failed");
68                         exit(EXIT_FAILURE);
69                 }
70         }
71
72         /* Get timestamps after [f]truncate(2) */
73         ret = fstat(fd, &statbuf2);
74         if (ret == -1) {
75                 perror("fstat(2) failed");
76                 exit(EXIT_FAILURE);
77         }
78
79         /* Check whether timestamps got updated on [f]truncate(2) down */
80         if (statbuf1.st_ctime == statbuf2.st_ctime) {
81                 fprintf(stderr, "ctime not updated after %s\n",
82                         is_ftrunc ? "ftruncate" : "truncate" " down");
83                 ret++;
84         }
85         if (statbuf1.st_mtime == statbuf2.st_mtime) {
86                 fprintf(stderr, "mtime not updated after %s\n",
87                         is_ftrunc ? "ftruncate" : "truncate" " down");
88                 ret++;
89         }
90
91         /* Test [f]truncate(2) up */
92         sleep(1);
93         if (is_ftrunc) {
94                 ret = ftruncate(fd, 123);
95                 if (ret == -1) {
96                         perror("ftruncate(2) up failed");
97                         exit(EXIT_FAILURE);
98                 }
99         } else {
100                 ret = truncate(file, 123);
101                 if (ret == -1) {
102                         perror("truncate(2) up failed");
103                         exit(EXIT_FAILURE);
104                 }
105         }
106         ret = fstat(fd, &statbuf1);
107         if (ret == -1) {
108                 perror("fstat(2) failed");
109                 exit(EXIT_FAILURE);
110         }
111         /* Check whether timestamps got updated on [f]truncate(2) up */
112         if (statbuf1.st_ctime == statbuf2.st_ctime) {
113                 fprintf(stderr, "ctime not updated after %s\n",
114                         is_ftrunc ? "ftruncate" : "truncate" " up");
115                 ret++;
116         }
117         if (statbuf1.st_mtime == statbuf2.st_mtime) {
118                 fprintf(stderr, "mtime not updated after %s\n",
119                         is_ftrunc ? "ftruncate" : "truncate" " up");
120                 ret++;
121         }
122
123         close(fd);
124         return ret;
125 }
126
127 int main(int argc, char *argv[])
128 {
129         int ret;
130         char *testfile;
131
132         ret = 0;
133         if (argc != 2) {
134                 fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
135                 exit(EXIT_FAILURE);
136         }
137         testfile = argv[1];
138
139         ret = do_test(testfile, 0);
140         ret += do_test(testfile, 1);
141
142         exit(ret);
143 }