blob: 68e1239c2bc355081e3f006610f2c78add539215 [file] [log] [blame]
Zeng Linggang5cdd6542014-04-08 18:41:48 +08001/*
2 * Copyright (c) 2014 Fujitsu Ltd.
3 * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
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 the
13 * GNU Library 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
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20/*
21 * Test Description:
22 * Verify that,
23 * 1. bufsiz is 0, EINVAL should be returned.
24 * 2. The named file is not a symbolic link, EINVAL should be returned.
25 * 3. The component of the path prefix is not a directory, ENOTDIR should be
26 * returned.
27 * 4. pathname is relative and dirfd is a file descriptor referring to a file
28 * other than a directory, ENOTDIR should be returned.
29 */
30
31#include <fcntl.h>
32#include <unistd.h>
33#include <errno.h>
34
35#include "test.h"
Zeng Linggang5cdd6542014-04-08 18:41:48 +080036#include "safe_macros.h"
37#include "lapi/readlinkat.h"
38#include "linux_syscall_numbers.h"
39
40#define TEST_FILE "test_file"
41#define SYMLINK_FILE "symlink_file"
42#define BUFF_SIZE 256
43
44static int file_fd, dir_fd;
45
46static struct test_case_t {
47 int *dirfd;
48 const char *pathname;
49 size_t bufsiz;
50 int exp_errno;
51} test_cases[] = {
52 {&dir_fd, SYMLINK_FILE, 0, EINVAL},
53 {&dir_fd, TEST_FILE, BUFF_SIZE, EINVAL},
54 {&file_fd, SYMLINK_FILE, BUFF_SIZE, ENOTDIR},
55 {&dir_fd, "test_file/test_file", BUFF_SIZE, ENOTDIR},
56};
57
58char *TCID = "readlinkat02";
59int TST_TOTAL = ARRAY_SIZE(test_cases);
Zeng Linggang5cdd6542014-04-08 18:41:48 +080060static void setup(void);
61static void cleanup(void);
62static void readlinkat_verify(const struct test_case_t *);
63
64int main(int argc, char **argv)
65{
66 int i, lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020067 const char *msg;
Zeng Linggang5cdd6542014-04-08 18:41:48 +080068
69 msg = parse_opts(argc, argv, NULL, NULL);
70 if (msg != NULL)
71 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
72
73 setup();
74
75 for (lc = 0; TEST_LOOPING(lc); lc++) {
76 tst_count = 0;
77 for (i = 0; i < TST_TOTAL; i++)
78 readlinkat_verify(&test_cases[i]);
79 }
80
81 cleanup();
82 tst_exit();
83}
84
85static void setup(void)
86{
87 tst_sig(NOFORK, DEF_HANDLER, cleanup);
88
Zeng Linggang5cdd6542014-04-08 18:41:48 +080089 TEST_PAUSE;
90
91 tst_tmpdir();
92
93 dir_fd = SAFE_OPEN(cleanup, "./", O_RDONLY);
94
95 file_fd = SAFE_OPEN(cleanup, TEST_FILE, O_RDWR | O_CREAT, 0644);
96
97 SAFE_SYMLINK(cleanup, TEST_FILE, SYMLINK_FILE);
98}
99
100static void readlinkat_verify(const struct test_case_t *test)
101{
102 char buf[BUFF_SIZE];
103 TEST(readlinkat(*test->dirfd, test->pathname, buf, test->bufsiz));
104
105 if (TEST_RETURN != -1) {
106 tst_resm(TFAIL, "readlinkat succeeded unexpectedly");
107 return;
108 }
109
110 if (TEST_ERRNO == test->exp_errno) {
111 tst_resm(TPASS | TTERRNO, "readlinkat failed as expected");
112 } else {
113 tst_resm(TFAIL | TTERRNO,
114 "readlinkat failed unexpectedly; expected: %d - %s",
115 test->exp_errno, strerror(test->exp_errno));
116 }
117}
118
119static void cleanup(void)
120{
Zeng Linggang5cdd6542014-04-08 18:41:48 +0800121 tst_rmdir();
122}