1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <fcntl.h>
17 #include <sys/stat.h>
18 #include <sys/time.h>
19 #include "test.h"
20
21 const char *path = "/data";
22
23 extern int __futimesat_time64(int, const char *, const struct timeval [2]);
24
25 /**
26 * @tc.name : futimesat_0100
27 * @tc.desc : Change timestamps of a file relative to a directory file descriptor
28 * @tc.level : Level 0
29 */
futimesat_0100(void)30 void futimesat_0100(void)
31 {
32 int dir_fd = open(path, O_RDONLY | O_DIRECTORY);
33 if (dir_fd < 0) {
34 t_error("%s open failed\n", __func__);
35 }
36
37 int fd = openat(dir_fd, "test.txt", O_CREAT | O_RDWR | O_EXCL, 0666);
38 if (fd < 0) {
39 t_error("%s openat failed\n", __func__);
40 }
41
42 write(fd, "helloworld", 5);
43
44 struct stat st1;
45 if (fstat(fd, &st1) != 0) {
46 t_error("%s fstat failed\n", __func__);
47 }
48 close(fd);
49
50 struct timeval tv[2];
51 tv[0].tv_sec = st1.st_atime + 1;
52 tv[0].tv_usec = 0;
53 tv[1].tv_sec = st1.st_mtime + 1;
54 tv[1].tv_usec = 0;
55
56 int result = futimesat(dir_fd, "test.txt", tv);
57 if (result != 0) {
58 t_error("%s futimesat failed\n", __func__);
59 }
60
61 struct stat st2;
62 if (fstatat(dir_fd, "test.txt", &st2, 0) != 0) {
63 t_error("%s fstatat failed\n", __func__);
64 }
65
66 if (st2.st_mtime != tv[1].tv_sec) {
67 t_error("%s stat shows different mtime\n", __func__);
68 }
69
70 if (unlinkat(dir_fd, "test.txt", 0) != 0) {
71 t_error("%s unlinkat failed\n", __func__);
72 }
73
74 close(dir_fd);
75 }
76
77 /**
78 * @tc.name : futimesat_0200
79 * @tc.desc : Test the return value of the function when timeval is NULL
80 * @tc.level : Level 1
81 */
futimesat_0200(void)82 void futimesat_0200(void)
83 {
84 int dir_fd = open(path, O_RDONLY | O_DIRECTORY);
85 if (dir_fd < 0) {
86 t_error("%s open failed\n", __func__);
87 }
88
89 int fd = openat(dir_fd, "test.txt", O_CREAT | O_RDWR | O_EXCL, 0666);
90 if (fd < 0) {
91 t_error("%s openat failed\n", __func__);
92 }
93
94 int result = futimesat(dir_fd, "test.txt", NULL);
95 if (result != 0) {
96 t_error("%s futimesat failed\n", __func__);
97 }
98
99 if (unlinkat(dir_fd, "test.txt", 0) != 0) {
100 t_error("%s unlinkat failed\n", __func__);
101 }
102
103 close(dir_fd);
104 }
105
106 /**
107 * @tc.name : futimesat_0300
108 * @tc.desc : Test the return value of the function when dirfd is invalid
109 * @tc.level : Level 2
110 */
futimesat_0300(void)111 void futimesat_0300(void)
112 {
113 int result = futimesat(-1, "test.txt", NULL);
114 if (result != -1) {
115 t_error("%s futimesat should be failed\n", __func__);
116 }
117 }
118
119 /**
120 * @tc.name : futimesat_0400
121 * @tc.desc : Test the return value of the function when pathname is invalid
122 * @tc.level : Level 2
123 */
futimesat_0400(void)124 void futimesat_0400(void)
125 {
126 int result = futimesat(AT_FDCWD, NULL, NULL);
127 if (result != -1) {
128 t_error("%s futimesat should be failed\n", __func__);
129 }
130 }
131
132 /**
133 * @tc.name : futimesat_time64_0200
134 * @tc.desc : Test the return value of the function when timeval is NULL
135 * @tc.level : Level 1
136 */
futimesat_time64_0200(void)137 void futimesat_time64_0200(void)
138 {
139 int dir_fd = open(path, O_RDONLY | O_DIRECTORY);
140 if (dir_fd < 0) {
141 t_error("%s open failed\n", __func__);
142 }
143
144 int fd = openat(dir_fd, "test.txt", O_CREAT | O_RDWR | O_EXCL, 0666);
145 if (fd < 0) {
146 t_error("%s openat failed\n", __func__);
147 }
148
149 int result = __futimesat_time64(dir_fd, "test.txt", NULL);
150 if (result != 0) {
151 t_error("%s __futimesat_time64 failed\n", __func__);
152 }
153
154 if (unlinkat(dir_fd, "test.txt", 0) != 0) {
155 t_error("%s unlinkat failed\n", __func__);
156 }
157
158 close(dir_fd);
159 }
160
main(int argc,char * argv[])161 int main(int argc, char *argv[])
162 {
163 futimesat_0100();
164 futimesat_0200();
165 futimesat_0300();
166 futimesat_0400();
167 futimesat_time64_0200();
168 return t_status;
169 }