1#include <assert.h>
2#include <errno.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <sys/mman.h>
7
8
9static int
10do_test (void)
11{
12 int result = 0;
13 FILE *fp;
14 size_t c;
15 char buf[1000];
16 int fd;
17 unsigned char *ptr;
18 size_t ps = sysconf (_SC_PAGESIZE);
19 void *mem;
20
21 /* Create a file and put some data in it. */
22 fp = tmpfile ();
23 if (fp == NULL)
24 {
25 printf (format: "Cannot create temporary file: %m\n");
26 return 1;
27 }
28 fd = fileno (fp);
29
30 for (c = 0; c < sizeof (buf); ++c)
31 buf[c] = '0' + (c % 10);
32
33 for (c = 0; c < (ps * 4) / sizeof (buf); ++c)
34 if (fwrite (buf, 1, sizeof (buf), fp) != sizeof (buf))
35 {
36 printf (format: "`fwrite' failed: %m\n");
37 return 1;
38 }
39 fflush (fp);
40 assert (ps + 1000 < c * sizeof (buf));
41
42 /* First try something which is not allowed: map at an offset which is
43 not modulo the pagesize. */
44 ptr = mmap (NULL, len: 1000, PROT_READ, MAP_SHARED, fd: fd, offset: ps - 1);
45 if (ptr != MAP_FAILED)
46 {
47 puts (s: "mapping at offset with mod pagesize != 0 succeeded!");
48 result = 1;
49 }
50 else if (errno != EINVAL && errno != ENOSYS)
51 {
52 puts (s: "wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
53 result = 1;
54 }
55
56 /* Try the same for mmap64. */
57 ptr = mmap64 (NULL, len: 1000, PROT_READ, MAP_SHARED, fd: fd, offset: ps - 1);
58 if (ptr != MAP_FAILED)
59 {
60 puts (s: "mapping at offset with mod pagesize != 0 succeeded!");
61 result = 1;
62 }
63 else if (errno != EINVAL && errno != ENOSYS)
64 {
65 puts (s: "wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
66 result = 1;
67 }
68
69 /* And the same for private mapping. */
70 ptr = mmap (NULL, len: 1000, PROT_READ, MAP_PRIVATE, fd: fd, offset: ps - 1);
71 if (ptr != MAP_FAILED)
72 {
73 puts (s: "mapping at offset with mod pagesize != 0 succeeded!");
74 result = 1;
75 }
76 else if (errno != EINVAL && errno != ENOSYS)
77 {
78 puts (s: "wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
79 result = 1;
80 }
81
82 /* Try the same for mmap64. */
83 ptr = mmap64 (NULL, len: 1000, PROT_READ, MAP_PRIVATE, fd: fd, offset: ps - 1);
84 if (ptr != MAP_FAILED)
85 {
86 puts (s: "mapping at offset with mod pagesize != 0 succeeded!");
87 result = 1;
88 }
89 else if (errno != EINVAL && errno != ENOSYS)
90 {
91 puts (s: "wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
92 result = 1;
93 }
94
95 /* Get a valid address. */
96 mem = malloc (size: 2 * ps);
97 if (mem != NULL)
98 {
99 /* Now we map at an address which is not mod pagesize. */
100 ptr = mmap (addr: mem + 1, len: 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd: fd, offset: ps);
101 if (ptr != MAP_FAILED)
102 {
103 puts (s: "mapping at address with mod pagesize != 0 succeeded!");
104 result = 1;
105 }
106 else if (errno != EINVAL && errno != ENOSYS)
107 {
108 puts (s: "wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
109 result = 1;
110 }
111
112 /* Try the same for mmap64. */
113 ptr = mmap64 (addr: mem + 1, len: 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd: fd, offset: ps);
114 if (ptr != MAP_FAILED)
115 {
116 puts (s: "mapping at address with mod pagesize != 0 succeeded!");
117 result = 1;
118 }
119 else if (errno != EINVAL && errno != ENOSYS)
120 {
121 puts (s: "wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
122 result = 1;
123 }
124
125 /* And again for MAP_PRIVATE. */
126 ptr = mmap (addr: mem + 1, len: 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd: fd, offset: ps);
127 if (ptr != MAP_FAILED)
128 {
129 puts (s: "mapping at address with mod pagesize != 0 succeeded!");
130 result = 1;
131 }
132 else if (errno != EINVAL && errno != ENOSYS)
133 {
134 puts (s: "wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
135 result = 1;
136 }
137
138 /* Try the same for mmap64. */
139 ptr = mmap64 (addr: mem + 1, len: 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd: fd, offset: ps);
140 if (ptr != MAP_FAILED)
141 {
142 puts (s: "mapping at address with mod pagesize != 0 succeeded!");
143 result = 1;
144 }
145 else if (errno != EINVAL && errno != ENOSYS)
146 {
147 puts (s: "wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
148 result = 1;
149 }
150
151 free (ptr: mem);
152 }
153
154 /* Now map the memory and see whether the content of the mapped area
155 is correct. */
156 ptr = mmap (NULL, len: 1000, PROT_READ, MAP_SHARED, fd: fd, offset: ps);
157 if (ptr == MAP_FAILED)
158 {
159 if (errno != ENOSYS)
160 {
161 printf (format: "cannot mmap file: %m\n");
162 result = 1;
163 }
164 }
165 else
166 {
167 for (c = ps; c < ps + 1000; ++c)
168 if (ptr[c - ps] != '0' + (c % 10))
169 {
170 printf (format: "wrong data mapped at offset %zd\n", c);
171 result = 1;
172 }
173 }
174
175 /* And for mmap64. */
176 ptr = mmap64 (NULL, len: 1000, PROT_READ, MAP_SHARED, fd: fd, offset: ps);
177 if (ptr == MAP_FAILED)
178 {
179 if (errno != ENOSYS)
180 {
181 printf (format: "cannot mmap file: %m\n");
182 result = 1;
183 }
184 }
185 else
186 {
187 for (c = ps; c < ps + 1000; ++c)
188 if (ptr[c - ps] != '0' + (c % 10))
189 {
190 printf (format: "wrong data mapped at offset %zd\n", c);
191 result = 1;
192 }
193 }
194
195 /* That's it. */
196 return result;
197}
198
199#define TEST_FUNCTION do_test ()
200#include "../test-skeleton.c"
201

source code of glibc/posix/tst-mmap.c