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