1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Red Hat Inc., 2007
4 */
5
6 /*
7 * NAME
8 * posix_fadvise03.c
9 *
10 * DESCRIPTION
11 * Check the value that posix_fadvise returns for wrong ADVISE value.
12 *
13 * USAGE
14 * posix_fadvise03
15 *
16 * HISTORY
17 * 11/2007 Initial version by Masatake YAMATO <yamato@redhat.com>
18 *
19 * RESTRICTIONS
20 * None
21 */
22
23 #define _XOPEN_SOURCE 600
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <signal.h>
27 #include <errno.h>
28 #include <limits.h>
29 #include <string.h>
30
31 #include "tst_test.h"
32 #include "lapi/syscalls.h"
33
34 char fname[] = "/bin/cat"; /* test executable to open */
35 int fd = -1; /* initialized in open */
36
37 int expected_error = EINVAL;
38
39 int defined_advise[] = {
40 POSIX_FADV_NORMAL,
41 POSIX_FADV_SEQUENTIAL,
42 POSIX_FADV_RANDOM,
43 POSIX_FADV_WILLNEED,
44 #if defined(__s390__) && __WORDSIZE == 32
45 /* POSIX_FADV_DONTNEED and POSIX_FADV_NOREUSE are 6,7 on 31bit s390,
46 * but the kernel accepts 4,5 as well and rewrites them internally,
47 * see Linux kernel commit 068e1b94bbd268f375349f68531829c8b7c210bc
48 *
49 * since header definitions are incomplete - posix fcntl.h doesn't care
50 * and defines them as 4,5 while linux/fadvise.h (which uses 6,7)
51 * matches only 64bit - we need to hardcode the values here for
52 * all 4 cases, unfortunately
53 */
54 4, /* POSIX_FADV_DONTNEED */
55 5, /* POSIX_FADV_NOREUSE */
56 6, /* POSIX_FADV_DONTNEED */
57 7, /* POSIX_FADV_NOREUSE */
58 #else
59 POSIX_FADV_DONTNEED,
60 POSIX_FADV_NOREUSE,
61 #endif
62 };
63
64 const int defined_advise_total = ARRAY_SIZE(defined_advise);
65
66 #define ADVISE_LIMIT 32
67
68 /* is_defined_advise:
69 Return 1 if advise is in defined_advise.
70 Return 0 if not. */
is_defined_advise(int advise)71 static int is_defined_advise(int advise)
72 {
73 int i;
74 for (i = 0; i < defined_advise_total; i++) {
75 if (defined_advise[i] == advise)
76 return 1;
77 }
78
79 return 0;
80 }
81
verify_fadvise(unsigned int n)82 static void verify_fadvise(unsigned int n)
83 {
84 /* Don't use defined advise as an argument. */
85 if (is_defined_advise(n)) {
86 tst_res(TPASS, "skipping defined - advise = %d", n);
87 return;
88 }
89
90 TEST(posix_fadvise(fd, 0, 0, n));
91
92 if (TST_RET == 0) {
93 tst_res(TFAIL, "call succeeded unexpectedly");
94 return;
95 }
96
97 /* Man page says:
98 "On error, an error number is returned." */
99 if (TST_RET == expected_error) {
100 tst_res(TPASS,
101 "expected failure - "
102 "returned value = %ld, advise = %d : %s",
103 TST_RET,
104 n, tst_strerrno(TST_RET));
105 } else {
106 tst_res(TFAIL,
107 "unexpected return value - %ld : %s, advise %d - "
108 "expected %d",
109 TST_RET,
110 tst_strerrno(TST_RET),
111 n, expected_error);
112 }
113 }
114
setup(void)115 static void setup(void)
116 {
117 fd = SAFE_OPEN(fname, O_RDONLY);
118 }
119
cleanup(void)120 static void cleanup(void)
121 {
122 if (fd > 0)
123 SAFE_CLOSE(fd);
124 }
125
126 static struct tst_test test = {
127 .setup = setup,
128 .cleanup = cleanup,
129 .test = verify_fadvise,
130 .tcnt = ADVISE_LIMIT,
131 };
132