1/*
2 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like.  Any license provided herein, whether implied or
15 * otherwise, applies only to this software file.  Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 */
24
25/*
26 * access(2) test for errno(s) EFAULT.
27 */
28
29#include <errno.h>
30#include <string.h>
31#include <signal.h>
32
33#include <unistd.h>
34#include <sys/mman.h>
35#include "test.h"
36
37static void setup(void);
38static void cleanup(void);
39
40char *TCID = "access03";
41int TST_TOTAL = 8;
42
43/* XXX (garrcoop): uh, this isn't a bad address yo. */
44static void *low_addr;
45static void *high_addr;
46
47#if !defined(UCLINUX)
48
49int main(int ac, char **av)
50{
51	int lc;
52
53	tst_parse_opts(ac, av, NULL, NULL);
54
55	setup();
56
57#define TEST_ACCESS(addr, mode) \
58{ \
59	if (access(low_addr, mode) == -1) { \
60		if (errno == EFAULT) { \
61			tst_resm(TPASS, \
62			    "access(%p, %s) failed as expected with EFAULT", \
63			    addr, #mode); \
64		} else { \
65			tst_resm(TFAIL|TERRNO, \
66			    "access(%p, %s) failed unexpectedly; " \
67			    "expected (EFAULT)", addr, #mode); \
68		} \
69	} else { \
70		tst_resm(TFAIL, \
71		    "access(%p, %s) succeeded unexpectedly", addr, #mode); \
72	} \
73}
74
75	for (lc = 0; TEST_LOOPING(lc); lc++) {
76		tst_count = 0;
77
78		TEST_ACCESS(low_addr, R_OK);
79		TEST_ACCESS(low_addr, W_OK);
80		TEST_ACCESS(low_addr, X_OK);
81		TEST_ACCESS(low_addr, F_OK);
82
83		TEST_ACCESS(high_addr, R_OK);
84		TEST_ACCESS(high_addr, W_OK);
85		TEST_ACCESS(high_addr, X_OK);
86		TEST_ACCESS(high_addr, F_OK);
87	}
88
89	cleanup();
90	tst_exit();
91}
92
93static void setup(void)
94{
95	tst_sig(NOFORK, DEF_HANDLER, cleanup);
96	TEST_PAUSE;
97
98	low_addr = mmap(0, 1, PROT_NONE,
99			MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
100	if (low_addr == MAP_FAILED)
101		tst_brkm(TBROK | TERRNO, NULL, "mmap failed");
102
103	high_addr = get_high_address();
104	if (high_addr == NULL)
105		tst_brkm(TBROK | TERRNO, NULL, "get_high_address failed");
106	high_addr++;
107
108	tst_tmpdir();
109}
110
111static void cleanup(void)
112{
113	tst_rmdir();
114}
115
116#else
117
118int main(void)
119{
120	tst_brkm(TCONF, NULL, "test not available on UCLINUX");
121}
122
123#endif /* if !defined(UCLINUX) */
124