Ticket #5168: mman.c

File mman.c, 4.2 KB (added by andrewbachmann, 14 years ago)
Line 
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
69int
70main ()
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}