1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *   http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci
16570af302Sopenharmony_ci#include <fcntl.h>
17570af302Sopenharmony_ci#include <sys/stat.h>
18570af302Sopenharmony_ci#include <sys/time.h>
19570af302Sopenharmony_ci#include "test.h"
20570af302Sopenharmony_ci
21570af302Sopenharmony_ciconst char *path = "/data";
22570af302Sopenharmony_ci
23570af302Sopenharmony_ciextern int __futimesat_time64(int, const char *, const struct timeval [2]);
24570af302Sopenharmony_ci
25570af302Sopenharmony_ci/**
26570af302Sopenharmony_ci * @tc.name      : futimesat_0100
27570af302Sopenharmony_ci * @tc.desc      : Change timestamps of a file relative to a directory file descriptor
28570af302Sopenharmony_ci * @tc.level     : Level 0
29570af302Sopenharmony_ci */
30570af302Sopenharmony_civoid futimesat_0100(void)
31570af302Sopenharmony_ci{
32570af302Sopenharmony_ci    int dir_fd = open(path, O_RDONLY | O_DIRECTORY);
33570af302Sopenharmony_ci    if (dir_fd < 0) {
34570af302Sopenharmony_ci        t_error("%s open failed\n", __func__);
35570af302Sopenharmony_ci    }
36570af302Sopenharmony_ci
37570af302Sopenharmony_ci    int fd = openat(dir_fd, "test.txt", O_CREAT | O_RDWR | O_EXCL, 0666);
38570af302Sopenharmony_ci    if (fd < 0) {
39570af302Sopenharmony_ci        t_error("%s openat failed\n", __func__);
40570af302Sopenharmony_ci    }
41570af302Sopenharmony_ci
42570af302Sopenharmony_ci    write(fd, "helloworld", 5);
43570af302Sopenharmony_ci
44570af302Sopenharmony_ci    struct stat st1;
45570af302Sopenharmony_ci    if (fstat(fd, &st1) != 0) {
46570af302Sopenharmony_ci        t_error("%s fstat failed\n", __func__);
47570af302Sopenharmony_ci    }
48570af302Sopenharmony_ci    close(fd);
49570af302Sopenharmony_ci
50570af302Sopenharmony_ci    struct timeval tv[2];
51570af302Sopenharmony_ci    tv[0].tv_sec = st1.st_atime + 1;
52570af302Sopenharmony_ci    tv[0].tv_usec = 0;
53570af302Sopenharmony_ci    tv[1].tv_sec = st1.st_mtime + 1;
54570af302Sopenharmony_ci    tv[1].tv_usec = 0;
55570af302Sopenharmony_ci
56570af302Sopenharmony_ci    int result = futimesat(dir_fd, "test.txt", tv);
57570af302Sopenharmony_ci    if (result != 0) {
58570af302Sopenharmony_ci        t_error("%s futimesat failed\n", __func__);
59570af302Sopenharmony_ci    }
60570af302Sopenharmony_ci
61570af302Sopenharmony_ci    struct stat st2;
62570af302Sopenharmony_ci    if (fstatat(dir_fd, "test.txt", &st2, 0) != 0) {
63570af302Sopenharmony_ci        t_error("%s fstatat failed\n", __func__);
64570af302Sopenharmony_ci    }
65570af302Sopenharmony_ci
66570af302Sopenharmony_ci    if (st2.st_mtime != tv[1].tv_sec) {
67570af302Sopenharmony_ci        t_error("%s stat shows different mtime\n", __func__);
68570af302Sopenharmony_ci    }
69570af302Sopenharmony_ci
70570af302Sopenharmony_ci    if (unlinkat(dir_fd, "test.txt", 0) != 0) {
71570af302Sopenharmony_ci        t_error("%s unlinkat failed\n", __func__);
72570af302Sopenharmony_ci    }
73570af302Sopenharmony_ci
74570af302Sopenharmony_ci    close(dir_fd);
75570af302Sopenharmony_ci}
76570af302Sopenharmony_ci
77570af302Sopenharmony_ci/**
78570af302Sopenharmony_ci * @tc.name      : futimesat_0200
79570af302Sopenharmony_ci * @tc.desc      : Test the return value of the function when timeval is NULL
80570af302Sopenharmony_ci * @tc.level     : Level 1
81570af302Sopenharmony_ci */
82570af302Sopenharmony_civoid futimesat_0200(void)
83570af302Sopenharmony_ci{
84570af302Sopenharmony_ci    int dir_fd = open(path, O_RDONLY | O_DIRECTORY);
85570af302Sopenharmony_ci    if (dir_fd < 0) {
86570af302Sopenharmony_ci        t_error("%s open failed\n", __func__);
87570af302Sopenharmony_ci    }
88570af302Sopenharmony_ci
89570af302Sopenharmony_ci    int fd = openat(dir_fd, "test.txt", O_CREAT | O_RDWR | O_EXCL, 0666);
90570af302Sopenharmony_ci    if (fd < 0) {
91570af302Sopenharmony_ci        t_error("%s openat failed\n", __func__);
92570af302Sopenharmony_ci    }
93570af302Sopenharmony_ci
94570af302Sopenharmony_ci    int result = futimesat(dir_fd, "test.txt", NULL);
95570af302Sopenharmony_ci    if (result != 0) {
96570af302Sopenharmony_ci        t_error("%s futimesat failed\n", __func__);
97570af302Sopenharmony_ci    }
98570af302Sopenharmony_ci
99570af302Sopenharmony_ci    if (unlinkat(dir_fd, "test.txt", 0) != 0) {
100570af302Sopenharmony_ci        t_error("%s unlinkat failed\n", __func__);
101570af302Sopenharmony_ci    }
102570af302Sopenharmony_ci
103570af302Sopenharmony_ci    close(dir_fd);
104570af302Sopenharmony_ci}
105570af302Sopenharmony_ci
106570af302Sopenharmony_ci/**
107570af302Sopenharmony_ci * @tc.name      : futimesat_0300
108570af302Sopenharmony_ci * @tc.desc      : Test the return value of the function when dirfd is invalid
109570af302Sopenharmony_ci * @tc.level     : Level 2
110570af302Sopenharmony_ci */
111570af302Sopenharmony_civoid futimesat_0300(void)
112570af302Sopenharmony_ci{
113570af302Sopenharmony_ci    int result = futimesat(-1, "test.txt", NULL);
114570af302Sopenharmony_ci    if (result != -1) {
115570af302Sopenharmony_ci        t_error("%s futimesat should be failed\n", __func__);
116570af302Sopenharmony_ci    }
117570af302Sopenharmony_ci}
118570af302Sopenharmony_ci
119570af302Sopenharmony_ci/**
120570af302Sopenharmony_ci * @tc.name      : futimesat_0400
121570af302Sopenharmony_ci * @tc.desc      : Test the return value of the function when pathname is invalid
122570af302Sopenharmony_ci * @tc.level     : Level 2
123570af302Sopenharmony_ci */
124570af302Sopenharmony_civoid futimesat_0400(void)
125570af302Sopenharmony_ci{
126570af302Sopenharmony_ci    int result = futimesat(AT_FDCWD, NULL, NULL);
127570af302Sopenharmony_ci    if (result != -1) {
128570af302Sopenharmony_ci        t_error("%s futimesat should be failed\n", __func__);
129570af302Sopenharmony_ci    }
130570af302Sopenharmony_ci}
131570af302Sopenharmony_ci
132570af302Sopenharmony_ci/**
133570af302Sopenharmony_ci * @tc.name      : futimesat_time64_0200
134570af302Sopenharmony_ci * @tc.desc      : Test the return value of the function when timeval is NULL
135570af302Sopenharmony_ci * @tc.level     : Level 1
136570af302Sopenharmony_ci */
137570af302Sopenharmony_civoid futimesat_time64_0200(void)
138570af302Sopenharmony_ci{
139570af302Sopenharmony_ci    int dir_fd = open(path, O_RDONLY | O_DIRECTORY);
140570af302Sopenharmony_ci    if (dir_fd < 0) {
141570af302Sopenharmony_ci        t_error("%s open failed\n", __func__);
142570af302Sopenharmony_ci    }
143570af302Sopenharmony_ci
144570af302Sopenharmony_ci    int fd = openat(dir_fd, "test.txt", O_CREAT | O_RDWR | O_EXCL, 0666);
145570af302Sopenharmony_ci    if (fd < 0) {
146570af302Sopenharmony_ci        t_error("%s openat failed\n", __func__);
147570af302Sopenharmony_ci    }
148570af302Sopenharmony_ci
149570af302Sopenharmony_ci    int result = __futimesat_time64(dir_fd, "test.txt", NULL);
150570af302Sopenharmony_ci    if (result != 0) {
151570af302Sopenharmony_ci        t_error("%s __futimesat_time64 failed\n", __func__);
152570af302Sopenharmony_ci    }
153570af302Sopenharmony_ci
154570af302Sopenharmony_ci    if (unlinkat(dir_fd, "test.txt", 0) != 0) {
155570af302Sopenharmony_ci        t_error("%s unlinkat failed\n", __func__);
156570af302Sopenharmony_ci    }
157570af302Sopenharmony_ci
158570af302Sopenharmony_ci    close(dir_fd);
159570af302Sopenharmony_ci}
160570af302Sopenharmony_ci
161570af302Sopenharmony_ciint main(int argc, char *argv[])
162570af302Sopenharmony_ci{
163570af302Sopenharmony_ci    futimesat_0100();
164570af302Sopenharmony_ci    futimesat_0200();
165570af302Sopenharmony_ci    futimesat_0300();
166570af302Sopenharmony_ci    futimesat_0400();
167570af302Sopenharmony_ci    futimesat_time64_0200();
168570af302Sopenharmony_ci    return t_status;
169570af302Sopenharmony_ci}