blob: e1aeca501ea88ceff5690444815c58ed09c10fa5 [file] [log] [blame]
vapier8a63ecb2006-09-10 10:03:21 +00001/******************************************************************************
2 *
3 * Copyright (c) International Business Machines Corp., 2006
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the 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 to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
vapier8a63ecb2006-09-10 10:03:21 +000018 *
19 * NAME
20 * readlinkat01.c
21 *
22 * DESCRIPTION
23 * This test case will verify basic function of readlinkat
24 * added by kernel 2.6.16 or up.
25 *
26 * USAGE: <for command-line>
27 * readlinkat01 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-p]
28 * where:
29 * -c n : Run n copies simultaneously.
30 * -e : Turn on errno logging.
31 * -i n : Execute test n times.
32 * -I x : Execute test for x seconds.
33 * -p : Pause for SIGUSR1 before starting
34 * -P x : Pause for x seconds between iterations.
35 * -t : Turn on syscall timing.
36 *
37 * Author
subrata_modak4bb656a2009-02-26 12:02:09 +000038 * Yi Yang <yyangcdl@cn.ibm.com>
vapier8a63ecb2006-09-10 10:03:21 +000039 *
40 * History
41 * 08/28/2006 Created first by Yi Yang <yyangcdl@cn.ibm.com>
42 *
43 *****************************************************************************/
44
45#define _GNU_SOURCE
46
47#include <sys/types.h>
48#include <sys/stat.h>
49#include <sys/time.h>
50#include <fcntl.h>
51#include <error.h>
52#include <stdlib.h>
53#include <errno.h>
54#include <string.h>
55#include <signal.h>
56#include "test.h"
57#include "usctest.h"
58#include "linux_syscall_numbers.h"
59
60#define TEST_CASES 5
61#define BUFF_SIZE 256
62#define MYRETCODE -999
63#ifndef AT_FDCWD
64#define AT_FDCWD -100
65#endif
66#ifndef AT_REMOVEDIR
67#define AT_REMOVEDIR 0x200
68#endif
69
70void setup();
71void cleanup();
72void setup_every_copy();
73
74char *TCID = "readlinkat01"; /* Test program identifier. */
75int TST_TOTAL = TEST_CASES; /* Total number of test cases. */
vapier8a63ecb2006-09-10 10:03:21 +000076char pathname[256];
77char dpathname[256];
78char testfile[256];
79char dtestfile[256];
80char testfile2[256];
81char dtestfile2[256];
82char testfile3[256];
83char dtestfile3[256];
84int dirfd, fd, ret;
85int fds[TEST_CASES];
86char *filenames[TEST_CASES];
87int expected_errno[TEST_CASES] = { 0, 0, ENOTDIR, EBADF, 0 };
Wanlong Gao354ebb42012-12-07 10:10:04 +080088
vapier8a63ecb2006-09-10 10:03:21 +000089char expected_buff[TEST_CASES][256];
90char buffer[BUFF_SIZE];
91
92int myreadlinkat(int dirfd, const char *filename, char *buffer, size_t bufsize)
93{
Jan Stancek359980f2013-02-15 10:16:05 +010094 return ltp_syscall(__NR_readlinkat, dirfd, filename, buffer, bufsize);
vapier8a63ecb2006-09-10 10:03:21 +000095}
96
97int main(int ac, char **av)
98{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020099 int lc;
100 char *msg;
vapier8a63ecb2006-09-10 10:03:21 +0000101 int i;
102
subrata_modak56207ce2009-03-23 13:35:39 +0000103 /* Disable test if the version of the kernel is less than 2.6.16 */
104 if ((tst_kvercmp(2, 6, 16)) < 0) {
105 tst_resm(TWARN, "This test can only run on kernels that are ");
106 tst_resm(TWARN, "2.6.16 and higher");
107 exit(0);
108 }
mreed10807cfe52006-09-18 19:03:19 +0000109
vapier8a63ecb2006-09-10 10:03:21 +0000110 /***************************************************************
111 * parse standard options
112 ***************************************************************/
Garrett Cooper45e285d2010-11-22 12:19:25 -0800113 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800114 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
vapier8a63ecb2006-09-10 10:03:21 +0000115
116 /***************************************************************
117 * perform global setup for test
118 ***************************************************************/
119 setup();
120
121 /***************************************************************
122 * check looping state if -c option given
123 ***************************************************************/
124 for (lc = 0; TEST_LOOPING(lc); lc++) {
125 setup_every_copy();
126
vapier8a63ecb2006-09-10 10:03:21 +0000127 Tst_count = 0;
128
subrata_modak4bb656a2009-02-26 12:02:09 +0000129 /*
130 * Call readlinkat
vapier8a63ecb2006-09-10 10:03:21 +0000131 */
132 for (i = 0; i < TST_TOTAL; i++) {
133 buffer[0] = '\0';
134 TEST(myreadlinkat
135 (fds[i], filenames[i], buffer, BUFF_SIZE));
136
137 if (TEST_RETURN >= 0) {
138 buffer[TEST_RETURN] = '\0';
139 }
140
141 /* check return code */
142 if (TEST_ERRNO == expected_errno[i]
143 && (strcmp(expected_buff[i], buffer) == 0)) {
144
145 /***************************************************************
146 * only perform functional verification if flag set (-f not given)
147 ***************************************************************/
148 if (STD_FUNCTIONAL_TEST) {
149 /* No Verification test, yet... */
150 tst_resm(TPASS,
151 "readlinkat() returned the expected errno %d: %s",
152 TEST_ERRNO,
153 strerror(TEST_ERRNO));
154 }
155 } else {
156 if (TEST_RETURN >= 0) {
157 tst_resm(TINFO,
158 "The link readlinkat got isn't as same as the expected");
159 }
160 TEST_ERROR_LOG(TEST_ERRNO);
161 tst_resm(TFAIL,
162 "readlinkat() Failed, errno=%d : %s",
163 TEST_ERRNO, strerror(TEST_ERRNO));
164 }
165 }
166
Garrett Cooper2c282152010-12-16 00:55:50 -0800167 }
vapier8a63ecb2006-09-10 10:03:21 +0000168
169 /***************************************************************
170 * cleanup and exit
171 ***************************************************************/
172 cleanup();
173
174 return (0);
Garrett Cooper2c282152010-12-16 00:55:50 -0800175}
vapier8a63ecb2006-09-10 10:03:21 +0000176
177void setup_every_copy()
178{
179 int i;
180 char tmpfilename[256] = "";
181
182 /* Initialize test dir and file names */
183 sprintf(pathname, "readlinkattestdir%d", getpid());
184 sprintf(dpathname, "dreadlinkattestdir%d", getpid());
185 sprintf(testfile, "readlinkattestfile%d.txt", getpid());
186 sprintf(dtestfile, "dreadlinkattestfile%d.txt", getpid());
187 sprintf(testfile2, "readlinkattestdir%d/readlinkattestfile%d.txt",
188 getpid(), getpid());
189 sprintf(dtestfile2, "dreadlinkattestdir%d/dreadlinkattestfile%d.txt",
190 getpid(), getpid());
191 sprintf(testfile3, "/tmp/readlinkattestfile%d.txt", getpid());
192 sprintf(dtestfile3, "/tmp/dreadlinkattestfile%d.txt", getpid());
193
194 ret = mkdir(pathname, 0700);
195 if (ret < 0) {
196 perror("mkdir: ");
197 exit(-1);
198 }
199
200 ret = mkdir(dpathname, 0700);
201 if (ret < 0) {
202 perror("mkdir: ");
203 exit(-1);
204 }
205
206 dirfd = open(dpathname, O_DIRECTORY);
207 if (dirfd < 0) {
208 perror("open: ");
209 exit(-1);
210 }
211
212 fd = open(testfile, O_CREAT | O_RDWR, 0600);
213 if (fd < 0) {
214 perror("open: ");
215 exit(-1);
216 }
217
218 ret = symlink(testfile, dtestfile);
219 if (ret < 0) {
220 perror("symlink: ");
221 exit(-1);
222 }
223
224 fd = open(testfile2, O_CREAT | O_RDWR, 0600);
225 if (fd < 0) {
226 perror("open: ");
227 exit(-1);
228 }
229
230 tmpfilename[0] = '\0';
231 strcat(strcat(tmpfilename, "../"), testfile2);
232 ret = symlink(tmpfilename, dtestfile2);
233 if (ret < 0) {
234 perror("symlink: ");
235 exit(-1);
236 }
237
238 fd = open(testfile3, O_CREAT | O_RDWR, 0600);
239 if (fd < 0) {
240 perror("open: ");
241 exit(-1);
242 }
243
244 ret = symlink(testfile3, dtestfile3);
245 if (ret < 0) {
246 perror("symlink: ");
247 exit(-1);
248 }
249
250 fds[0] = fds[1] = dirfd;
251 fds[2] = fd;
252 fds[3] = 100;
253 fds[4] = AT_FDCWD;
254
subrata_modakd6e4df22009-05-11 09:35:18 +0000255 filenames[0] = filenames[2] = filenames[3] = filenames[4] = dtestfile;
vapier8a63ecb2006-09-10 10:03:21 +0000256 filenames[1] = dtestfile3;
257
258 for (i = 0; i < TEST_CASES; i++)
259 expected_buff[i][0] = '\0';
260
261 strcat(strcat(expected_buff[0], "../"), testfile2);
262 strcat(expected_buff[1], testfile3);
263 strcat(expected_buff[2], "");
264 strcat(expected_buff[3], "");
265 strcat(expected_buff[4], testfile);
266}
267
268/***************************************************************
269 * setup() - performs all ONE TIME setup for this test.
270 ***************************************************************/
271void setup()
272{
Garrett Cooper2c282152010-12-16 00:55:50 -0800273
vapier8a63ecb2006-09-10 10:03:21 +0000274 tst_sig(NOFORK, DEF_HANDLER, cleanup);
275
vapier8a63ecb2006-09-10 10:03:21 +0000276 TEST_PAUSE;
Garrett Cooper2c282152010-12-16 00:55:50 -0800277}
vapier8a63ecb2006-09-10 10:03:21 +0000278
279/***************************************************************
280 * cleanup() - performs all ONE TIME cleanup for this test at
281 * completion or premature exit.
282 ***************************************************************/
283void cleanup()
284{
285 /* Remove them */
286 unlink(testfile2);
287 unlink(dtestfile2);
288 unlink(testfile3);
289 unlink(dtestfile3);
290 unlink(testfile);
291 unlink(dtestfile);
292 rmdir(pathname);
293 rmdir(dpathname);
294
295 /*
296 * print timing stats if that option was specified.
297 * print errno log if that option was specified.
298 */
299 TEST_CLEANUP;
300
Chris Dearmanec6edca2012-10-17 19:54:01 -0700301}