summaryrefslogtreecommitdiff
path: root/minix/tests/test44.c
blob: eb325ce639c9b2de949d7514f97bc4e3bf6f2c30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/wait.h>

int max_error = 2;
#include "common.h"


int subtest = 0;

int
main(int argc, char *argv[])
{
#define CHUNKSIZE 8192
#define CHUNKS1	3
#define CHUNKS2	2
#define CHUNKS (CHUNKS1+CHUNKS2)
#define LARGESIZE 262144
	int i, fd;
	char *v[CHUNKS];
#define STARTV 0x90000000
	char *vaddr = (char *) STARTV;
	ssize_t l;
	pid_t f;

	start(44);

	for(i = 0; i < CHUNKS; i++) {
		v[i] = mmap(vaddr, CHUNKSIZE, PROT_READ|PROT_WRITE, 0,
				  -1, 0);
		if(v[i] == MAP_FAILED) {
			perror("mmap");
			fprintf(stderr, "mmap failed\n");
			quit();
		}
		if(v[i] != vaddr) {
			fprintf(stderr,
				"mmap said 0x%p but i wanted 0x%p\n",
				v[i], vaddr);
			quit();
		}
		vaddr += CHUNKSIZE;
	}

#define DEV_ZERO "/dev/zero"
	if((fd=open(DEV_ZERO, O_RDONLY)) < 0) {
		perror("open");
		fprintf(stderr, "open failed for %s\n", DEV_ZERO);
		quit();
	}

#define TOTAL1 (CHUNKS1*CHUNKSIZE)
	/* Make single read cross region boundary. */
	if((l=read(fd, v[0], TOTAL1)) != TOTAL1) {
		fprintf(stderr, "read %d but expected %d\n", l, TOTAL1);
		quit();
	}

	/* Force single copy to cross region boundary. */
	{
		char *t;
		t = v[CHUNKS1]+CHUNKSIZE-2;
		if((l=read(fd, t, CHUNKSIZE)) != CHUNKSIZE) {
			fprintf(stderr, "read %d but expected %d\n", l, CHUNKSIZE);
			quit();
		}
	}

	/* Now start a child to test bogus memory access */
	if((f = fork()) == -1) {
		perror("fork");
		quit();
	}

	if(f > 0) {
		int st;
		/* Parent waits. */
		if(waitpid(f, &st, 0) < 0) {
			perror("waitpid");
			quit();
		}
		if(!WIFEXITED(st)) {
			fprintf(stderr, "child not signaled\n");
			quit();
		}
		if(WEXITSTATUS(st) != 0) {
			fprintf(stderr, "child exited with nonzero status\n");
			quit();
		}
	} else {
		/* Child performs bogus read */
		int res;
		char *buf = v[CHUNKS-1];
		errno = 0;
		res = read(fd, buf, LARGESIZE);
		if(res >= 0)  {
			fprintf(stderr, "res %d\n", res);
			quit();
		}
		if(errno != EFAULT) {
			fprintf(stderr, "errno %d\n", errno);
			quit();
		}
		return(0);
	}

	quit();
	return(-1);
}