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 
9 static int
do_test(void)10 do_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 ("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 ("`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, 1000, PROT_READ, MAP_SHARED, fd, ps - 1);
45   if (ptr != MAP_FAILED)
46     {
47       puts ("mapping at offset with mod pagesize != 0 succeeded!");
48       result = 1;
49     }
50   else if (errno != EINVAL && errno != ENOSYS)
51     {
52       puts ("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, 1000, PROT_READ, MAP_SHARED, fd, ps - 1);
58   if (ptr != MAP_FAILED)
59     {
60       puts ("mapping at offset with mod pagesize != 0 succeeded!");
61       result = 1;
62     }
63   else if (errno != EINVAL && errno != ENOSYS)
64     {
65       puts ("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, 1000, PROT_READ, MAP_PRIVATE, fd, ps - 1);
71   if (ptr != MAP_FAILED)
72     {
73       puts ("mapping at offset with mod pagesize != 0 succeeded!");
74       result = 1;
75     }
76   else if (errno != EINVAL && errno != ENOSYS)
77     {
78       puts ("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, 1000, PROT_READ, MAP_PRIVATE, fd, ps - 1);
84   if (ptr != MAP_FAILED)
85     {
86       puts ("mapping at offset with mod pagesize != 0 succeeded!");
87       result = 1;
88     }
89   else if (errno != EINVAL && errno != ENOSYS)
90     {
91       puts ("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 (2 * ps);
97   if (mem != NULL)
98     {
99       /* Now we map at an address which is not mod pagesize.  */
100       ptr = mmap (mem + 1, 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, ps);
101       if (ptr != MAP_FAILED)
102 	{
103 	  puts ("mapping at address with mod pagesize != 0 succeeded!");
104 	  result = 1;
105 	}
106       else  if (errno != EINVAL && errno != ENOSYS)
107 	{
108 	  puts ("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 (mem + 1, 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, ps);
114       if (ptr != MAP_FAILED)
115 	{
116 	  puts ("mapping at address with mod pagesize != 0 succeeded!");
117 	  result = 1;
118 	}
119       else  if (errno != EINVAL && errno != ENOSYS)
120 	{
121 	  puts ("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 (mem + 1, 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ps);
127       if (ptr != MAP_FAILED)
128 	{
129 	  puts ("mapping at address with mod pagesize != 0 succeeded!");
130 	  result = 1;
131 	}
132       else  if (errno != EINVAL && errno != ENOSYS)
133 	{
134 	  puts ("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 (mem + 1, 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ps);
140       if (ptr != MAP_FAILED)
141 	{
142 	  puts ("mapping at address with mod pagesize != 0 succeeded!");
143 	  result = 1;
144 	}
145       else  if (errno != EINVAL && errno != ENOSYS)
146 	{
147 	  puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
148 	  result = 1;
149 	}
150 
151       free (mem);
152     }
153 
154   /* Now map the memory and see whether the content of the mapped area
155      is correct.  */
156   ptr = mmap (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps);
157   if (ptr == MAP_FAILED)
158     {
159       if (errno != ENOSYS)
160 	{
161 	  printf ("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 ("wrong data mapped at offset %zd\n", c);
171 	    result = 1;
172 	  }
173     }
174 
175   /* And for mmap64. */
176   ptr = mmap64 (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps);
177   if (ptr == MAP_FAILED)
178     {
179       if (errno != ENOSYS)
180 	{
181 	  printf ("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 ("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