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 <dirent.h>
17 #include <fcntl.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include "filepath_util.h"
23
24 const char buf[] = "hello";
25 const char *filename = "./file.txt";
26 const char *linkfilename = "./linkfile.txt";
27
create_file(char * path)28 int create_file(char *path)
29 {
30 int fd = open(path, O_RDWR | O_CREAT, TEST_MODE);
31 if (fd < 0) {
32 return -1;
33 }
34
35 ssize_t bytes = write(fd, buf, sizeof(buf));
36 if (bytes <= 0) {
37 return -1;
38 }
39
40 int result = close(fd);
41 if (result != 0) {
42 return -1;
43 }
44
45 return 0;
46 }
47
48 /**
49 * @tc.name : readlinkat_0100
50 * @tc.desc : read value of a symbolic link
51 * @tc.level : Level 0
52 */
readlinkat_0100(void)53 void readlinkat_0100(void)
54 {
55 char path[PATH_MAX] = {0};
56 FILE_ABSOLUTE_PATH(STR_FILE_TXT, path);
57 int result = create_file(path);
58 if (result != 0) {
59 t_error("%s failed: result = %d\n", __func__, result);
60 return;
61 }
62
63 char linkpath[PATH_MAX] = {0};
64 FILE_ABSOLUTE_PATH(STR_FILE_LINK_TXT, linkpath);
65 remove(linkpath);
66
67 result = symlink(path, linkpath);
68 if (result != 0) {
69 t_error("%s failed: result = %d\n", __func__, result);
70 return;
71 }
72
73 int fd = open(linkpath, O_RDONLY);
74 if (fd < 0) {
75 t_error("%s failed: fd = %d\n", __func__, fd);
76 return;
77 }
78
79 char rbuf[BUFSIZ] = {0};
80 ssize_t bytes = readlinkat(fd, linkpath, rbuf, sizeof(rbuf));
81 if (bytes != strlen(rbuf)) {
82 t_error("%s failed: bytes = %ld\n", __func__, bytes);
83 }
84
85 if (strcmp(rbuf, path)) {
86 t_error("%s failed: rbuf = %s\n", __func__, rbuf);
87 }
88
89 remove(linkpath);
90 remove(path);
91 }
92
93 /**
94 * @tc.name : readlinkat_0200
95 * @tc.desc : read value of a symbolic link with a dir fd
96 * @tc.level : Level 1
97 */
readlinkat_0200(void)98 void readlinkat_0200(void)
99 {
100 char path[PATH_MAX] = {0};
101 FILE_ABSOLUTE_PATH(STR_FILE_TXT, path);
102 int result = create_file(path);
103 if (result != 0) {
104 t_error("%s failed: result = %d\n", __func__, result);
105 return;
106 }
107
108 char dirname[PATH_MAX] = {0};
109 FILE_ABSOLUTE_DIR(dirname);
110 DIR *dir = opendir(dirname);
111 if (dir == NULL) {
112 t_error("%s failed: dirname = %s\n", __func__, dirname);
113 return;
114 }
115
116 int fd = dirfd(dir);
117 if (fd < 0) {
118 t_error("%s failed: fd = %d\n", __func__, fd);
119 }
120
121 char linkpath[PATH_MAX] = {0};
122 FILE_ABSOLUTE_PATH(STR_FILE_LINK_TXT, linkpath);
123 remove(linkpath);
124
125 result = symlinkat(filename, fd, linkfilename);
126 if (result != 0) {
127 t_error("%s failed: result = %d\n", __func__, result);
128 return;
129 }
130
131 char rbuf[BUFSIZ] = {0};
132 ssize_t bytes = readlinkat(fd, linkfilename, rbuf, sizeof(rbuf));
133 if (bytes != strlen(rbuf)) {
134 t_error("%s failed: bytes = %ld\n", __func__, bytes);
135 }
136
137 if (strcmp(rbuf, filename)) {
138 t_error("%s failed: rbuf = %s\n", __func__, rbuf);
139 }
140
141 remove(linkpath);
142 remove(path);
143 }
144
145 /**
146 * @tc.name : readlinkat_0300
147 * @tc.desc : read value of a symbolic link with invalid parameters
148 * @tc.level : Level 2
149 */
readlinkat_0300(void)150 void readlinkat_0300(void)
151 {
152 ssize_t bytes = readlinkat(-1, NULL, NULL, 0);
153 if (bytes >= 0) {
154 t_error("%s failed: bytes = %ld\n", __func__, bytes);
155 }
156 }
157
main(int argc,char * argv[])158 int main(int argc, char *argv[])
159 {
160 readlinkat_0100();
161 readlinkat_0200();
162 readlinkat_0300();
163
164 return t_status;
165 }
166