1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "tests/sys_mman.h"
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h>
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic unsigned int pagesize;
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PAGES	1024u
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LEN	(PAGES*pagesize)
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void *domap(void)
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	void *ret = mmap(0, LEN, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (ret == (void *)-1) {
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		perror("mmap");
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		exit(1);
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return ret;
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* unmap in pieces to exercise munmap more */
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void nibblemap(void *p)
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int off;
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int i;
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	off = (random() % LEN) & ~(pagesize-1);
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	for(i = 0; i < PAGES; i++) {
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		/* printf("unmapping off=%d\n", off/pagesize); */
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		munmap((char *)p + off, pagesize);
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		off += 619*pagesize;
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		off %= LEN;
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void prmaps()
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	char buf[100];
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	sprintf(buf, "/bin/cat /proc/%d/maps", getpid());
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	system(buf);
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	exit(1);
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main()
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int i;
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	void *expect1, *expect2;
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pagesize = getpagesize();
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	expect1 = domap();
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	expect2 = domap();
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	munmap(expect1, LEN);
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	munmap(expect2, LEN);
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	for(i = 0; i < 5; i++) {
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		void *m1, *m2;
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		m1 = domap();
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (m1 != expect1) {
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			printf("FAIL i=%d: m1=%p expect1=%p\n",
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			       i, m1, expect1);
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			prmaps();
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			return 1;
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		m2 = domap();
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (m2 != expect2) {
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			printf("FAIL i=%d: m2=%p expect2=%p\n",
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			       i, m2, expect2);
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			prmaps();
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			return 1;
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		nibblemap(m2);
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		munmap(m1, LEN);
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	printf("PASS\n");
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return 0;
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
83