1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2012 Linux Test Project, Inc.
4 */
5
6 /*
7 * errno tests for readahead() syscall
8 */
9 #define _GNU_SOURCE
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <sys/socket.h>
16 #include <sys/stat.h>
17 #include <sys/syscall.h>
18 #include <sys/types.h>
19 #include "config.h"
20 #include "tst_test.h"
21 #include "lapi/syscalls.h"
22
23 #if defined(__NR_readahead)
check_ret(long expected_ret)24 static void check_ret(long expected_ret)
25 {
26 if (expected_ret == TST_RET) {
27 tst_res(TPASS, "expected ret success - "
28 "returned value = %ld", TST_RET);
29 return;
30 }
31 tst_res(TFAIL, "unexpected failure - "
32 "returned value = %ld, expected: %ld",
33 TST_RET, expected_ret);
34 }
35
check_errno(long expected_errno)36 static void check_errno(long expected_errno)
37 {
38 if (TST_ERR == expected_errno) {
39 tst_res(TPASS | TTERRNO, "expected failure");
40 return;
41 }
42
43 if (TST_ERR == 0)
44 tst_res(TFAIL, "call succeeded unexpectedly");
45 else
46 tst_res(TFAIL | TTERRNO, "unexpected failure - "
47 "expected = %ld : %s, actual",
48 expected_errno, strerror(expected_errno));
49 }
50
test_bad_fd(void)51 static void test_bad_fd(void)
52 {
53 char tempname[PATH_MAX] = "readahead01_XXXXXX";
54 int fd;
55
56 tst_res(TINFO, "test_bad_fd -1");
57 TEST(readahead(-1, 0, getpagesize()));
58 check_ret(-1);
59 check_errno(EBADF);
60
61 tst_res(TINFO, "test_bad_fd O_WRONLY");
62 fd = mkstemp(tempname);
63 if (fd == -1)
64 tst_res(TFAIL | TERRNO, "mkstemp failed");
65 SAFE_CLOSE(fd);
66 fd = SAFE_OPEN(tempname, O_WRONLY);
67 TEST(readahead(fd, 0, getpagesize()));
68 check_ret(-1);
69 check_errno(EBADF);
70 SAFE_CLOSE(fd);
71 unlink(tempname);
72 }
73
test_invalid_fd(void)74 static void test_invalid_fd(void)
75 {
76 int fd[2];
77
78 tst_res(TINFO, "test_invalid_fd pipe");
79 SAFE_PIPE(fd);
80 TEST(readahead(fd[0], 0, getpagesize()));
81 check_ret(-1);
82 check_errno(EINVAL);
83 SAFE_CLOSE(fd[0]);
84 SAFE_CLOSE(fd[1]);
85
86 tst_res(TINFO, "test_invalid_fd socket");
87 fd[0] = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
88 TEST(readahead(fd[0], 0, getpagesize()));
89 check_ret(-1);
90 check_errno(EINVAL);
91 SAFE_CLOSE(fd[0]);
92 }
93
test_readahead(void)94 void test_readahead(void)
95 {
96 test_bad_fd();
97 test_invalid_fd();
98 }
99
setup(void)100 static void setup(void)
101 {
102 /* check if readahead syscall is supported */
103 tst_syscall(__NR_readahead, 0, 0, 0);
104 }
105
106 static struct tst_test test = {
107 .needs_tmpdir = 1,
108 .setup = setup,
109 .test_all = test_readahead,
110 };
111
112 #else /* __NR_readahead */
113 TST_TEST_TCONF("System doesn't support __NR_readahead");
114 #endif
115