1 | /* malloc might have been renamed as rpl_malloc. */
|
---|
2 | #undef malloc
|
---|
3 |
|
---|
4 | /* Thanks to Mike Haertel and Jim Avera for this test.
|
---|
5 | Here is a matrix of mmap possibilities:
|
---|
6 | mmap private not fixed
|
---|
7 | mmap private fixed at somewhere currently unmapped
|
---|
8 | mmap private fixed at somewhere already mapped
|
---|
9 | mmap shared not fixed
|
---|
10 | mmap shared fixed at somewhere currently unmapped
|
---|
11 | mmap shared fixed at somewhere already mapped
|
---|
12 | For private mappings, we should verify that changes cannot be read()
|
---|
13 | back from the file, nor mmap's back from the file at a different
|
---|
14 | address. (There have been systems where private was not correctly
|
---|
15 | implemented like the infamous i386 svr4.0, and systems where the
|
---|
16 | VM page cache was not coherent with the file system buffer cache
|
---|
17 | like early versions of FreeBSD and possibly contemporary NetBSD.)
|
---|
18 | For shared mappings, we should conversely verify that changes get
|
---|
19 | propagated back to all the places they're supposed to be.
|
---|
20 |
|
---|
21 | Grep wants private fixed already mapped.
|
---|
22 | The main things grep needs to know about mmap are:
|
---|
23 | * does it exist and is it safe to write into the mmap'd area
|
---|
24 | * how to use it (BSD variants) */
|
---|
25 |
|
---|
26 | #include <malloc.h>
|
---|
27 | #include <fcntl.h>
|
---|
28 | #include <sys/mman.h>
|
---|
29 | #include <stdlib.h>
|
---|
30 | #include <stdio.h>
|
---|
31 |
|
---|
32 | /* This mess was copied from the GNU getpagesize.h. */
|
---|
33 | #if !HAVE_GETPAGESIZE
|
---|
34 | /* Assume that all systems that can run configure have sys/param.h. */
|
---|
35 | # if !HAVE_SYS_PARAM_H
|
---|
36 | # define HAVE_SYS_PARAM_H 1
|
---|
37 | # endif
|
---|
38 |
|
---|
39 | # ifdef _SC_PAGESIZE
|
---|
40 | # define getpagesize() sysconf(_SC_PAGESIZE)
|
---|
41 | # else /* no _SC_PAGESIZE */
|
---|
42 | # if HAVE_SYS_PARAM_H
|
---|
43 | # include <sys/param.h>
|
---|
44 | # ifdef EXEC_PAGESIZE
|
---|
45 | # define getpagesize() EXEC_PAGESIZE
|
---|
46 | # else /* no EXEC_PAGESIZE */
|
---|
47 | # ifdef NBPG
|
---|
48 | # define getpagesize() NBPG * CLSIZE
|
---|
49 | # ifndef CLSIZE
|
---|
50 | # define CLSIZE 1
|
---|
51 | # endif /* no CLSIZE */
|
---|
52 | # else /* no NBPG */
|
---|
53 | # ifdef NBPC
|
---|
54 | # define getpagesize() NBPC
|
---|
55 | # else /* no NBPC */
|
---|
56 | # ifdef PAGESIZE
|
---|
57 | # define getpagesize() PAGESIZE
|
---|
58 | # endif /* PAGESIZE */
|
---|
59 | # endif /* no NBPC */
|
---|
60 | # endif /* no NBPG */
|
---|
61 | # endif /* no EXEC_PAGESIZE */
|
---|
62 | # else /* no HAVE_SYS_PARAM_H */
|
---|
63 | # define getpagesize() 8192 /* punt totally */
|
---|
64 | # endif /* no HAVE_SYS_PARAM_H */
|
---|
65 | # endif /* no _SC_PAGESIZE */
|
---|
66 |
|
---|
67 | #endif /* no HAVE_GETPAGESIZE */
|
---|
68 |
|
---|
69 | int
|
---|
70 | main ()
|
---|
71 | {
|
---|
72 | char *data, *data2, *data3;
|
---|
73 | int i, pagesize;
|
---|
74 | int fd;
|
---|
75 |
|
---|
76 | pagesize = getpagesize ();
|
---|
77 | printf("pagesize = %d\n", pagesize);
|
---|
78 |
|
---|
79 | /* First, make a file with some known garbage in it. */
|
---|
80 | data = (char *) malloc (pagesize);
|
---|
81 | if (!data) {
|
---|
82 | printf("data null\n");
|
---|
83 | exit (1);
|
---|
84 | }
|
---|
85 | for (i = 0; i < pagesize; ++i)
|
---|
86 | *(data + i) = rand ();
|
---|
87 | umask (0);
|
---|
88 | fd = creat ("conftest.mmap", 0600);
|
---|
89 | if (fd < 0) {
|
---|
90 | printf("0600 fd < 0: %d\n", fd);
|
---|
91 | exit (1);
|
---|
92 | }
|
---|
93 | if (write (fd, data, pagesize) != pagesize) {
|
---|
94 | printf("failed to write data to the file\n");
|
---|
95 | exit (1);
|
---|
96 | }
|
---|
97 | close (fd);
|
---|
98 |
|
---|
99 | /* Next, try to mmap the file at a fixed address which already has
|
---|
100 | something else allocated at it. If we can, also make sure that
|
---|
101 | we see the same garbage. */
|
---|
102 | fd = open ("conftest.mmap", O_RDWR);
|
---|
103 | if (fd < 0) {
|
---|
104 | printf("O_RDWR fd < 0: %d\n", fd);
|
---|
105 | exit (1);
|
---|
106 | }
|
---|
107 | data2 = (char *) malloc (2 * pagesize);
|
---|
108 | if (!data2) {
|
---|
109 | printf("data2 null\n");
|
---|
110 | exit (1);
|
---|
111 | }
|
---|
112 | data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1);
|
---|
113 | if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
|
---|
114 | MAP_PRIVATE | MAP_FIXED, fd, 0L)) {
|
---|
115 | printf("data2 mmap invalid\n");
|
---|
116 | exit (1);
|
---|
117 | }
|
---|
118 | for (i = 0; i < pagesize; ++i)
|
---|
119 | if (*(data + i) != *(data2 + i)) {
|
---|
120 | printf("data / data2 comparison failed\n");
|
---|
121 | exit (1);
|
---|
122 | }
|
---|
123 |
|
---|
124 | /* Finally, make sure that changes to the mapped area do not
|
---|
125 | percolate back to the file as seen by read(). (This is a bug on
|
---|
126 | some variants of i386 svr4.0.) */
|
---|
127 | for (i = 0; i < pagesize; ++i)
|
---|
128 | *(data2 + i) = *(data2 + i) + 1;
|
---|
129 | data3 = (char *) malloc (pagesize);
|
---|
130 | if (!data3) {
|
---|
131 | printf("data3 null\n");
|
---|
132 | exit (1);
|
---|
133 | }
|
---|
134 | if (read (fd, data3, pagesize) != pagesize) {
|
---|
135 | printf("data3 read failed\n");
|
---|
136 | exit (1);
|
---|
137 | }
|
---|
138 | for (i = 0; i < pagesize; ++i)
|
---|
139 | if (*(data + i) != *(data3 + i)) {
|
---|
140 | printf("data / data3 comparison failed\n");
|
---|
141 | exit (1);
|
---|
142 | }
|
---|
143 | close (fd);
|
---|
144 | exit (0);
|
---|
145 | }
|
---|