|  | #include <assert.h> | 
|  | #include <errno.h> | 
|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  | #include <unistd.h> | 
|  | #include <sys/mman.h> | 
|  |  | 
|  |  | 
|  | static int | 
|  | do_test (void) | 
|  | { | 
|  | int result = 0; | 
|  | FILE *fp; | 
|  | size_t c; | 
|  | char buf[1000]; | 
|  | int fd; | 
|  | unsigned char *ptr; | 
|  | size_t ps = sysconf (_SC_PAGESIZE); | 
|  | void *mem; | 
|  |  | 
|  | /* Create a file and put some data in it.  */ | 
|  | fp = tmpfile (); | 
|  | if (fp == NULL) | 
|  | { | 
|  | printf ("Cannot create temporary file: %m\n"); | 
|  | return 1; | 
|  | } | 
|  | fd = fileno (fp); | 
|  |  | 
|  | for (c = 0; c < sizeof (buf); ++c) | 
|  | buf[c] = '0' + (c % 10); | 
|  |  | 
|  | for (c = 0; c < (ps * 4) / sizeof (buf); ++c) | 
|  | if (fwrite (buf, 1, sizeof (buf), fp) != sizeof (buf)) | 
|  | { | 
|  | printf ("`fwrite' failed: %m\n"); | 
|  | return 1; | 
|  | } | 
|  | fflush (fp); | 
|  | assert (ps + 1000 < c * sizeof (buf)); | 
|  |  | 
|  | /* First try something which is not allowed: map at an offset which is | 
|  | not modulo the pagesize.  */ | 
|  | ptr = mmap (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps - 1); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at offset with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | /* Try the same for mmap64.  */ | 
|  | ptr = mmap64 (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps - 1); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at offset with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | /* And the same for private mapping.  */ | 
|  | ptr = mmap (NULL, 1000, PROT_READ, MAP_PRIVATE, fd, ps - 1); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at offset with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | /* Try the same for mmap64.  */ | 
|  | ptr = mmap64 (NULL, 1000, PROT_READ, MAP_PRIVATE, fd, ps - 1); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at offset with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | /* Get a valid address.  */ | 
|  | mem = malloc (2 * ps); | 
|  | if (mem != NULL) | 
|  | { | 
|  | /* Now we map at an address which is not mod pagesize.  */ | 
|  | ptr = mmap (mem + 1, 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, ps); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at address with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else  if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | /* Try the same for mmap64.  */ | 
|  | ptr = mmap64 (mem + 1, 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, ps); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at address with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else  if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | /* And again for MAP_PRIVATE.  */ | 
|  | ptr = mmap (mem + 1, 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ps); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at address with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else  if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | /* Try the same for mmap64.  */ | 
|  | ptr = mmap64 (mem + 1, 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ps); | 
|  | if (ptr != MAP_FAILED) | 
|  | { | 
|  | puts ("mapping at address with mod pagesize != 0 succeeded!"); | 
|  | result = 1; | 
|  | } | 
|  | else  if (errno != EINVAL && errno != ENOSYS) | 
|  | { | 
|  | puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)"); | 
|  | result = 1; | 
|  | } | 
|  |  | 
|  | free (mem); | 
|  | } | 
|  |  | 
|  | /* Now map the memory and see whether the content of the mapped area | 
|  | is correct.  */ | 
|  | ptr = mmap (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps); | 
|  | if (ptr == MAP_FAILED) | 
|  | { | 
|  | if (errno != ENOSYS) | 
|  | { | 
|  | printf ("cannot mmap file: %m\n"); | 
|  | result = 1; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | for (c = ps; c < ps + 1000; ++c) | 
|  | if (ptr[c - ps] != '0' + (c % 10)) | 
|  | { | 
|  | printf ("wrong data mapped at offset %zd\n", c); | 
|  | result = 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* And for mmap64. */ | 
|  | ptr = mmap64 (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps); | 
|  | if (ptr == MAP_FAILED) | 
|  | { | 
|  | if (errno != ENOSYS) | 
|  | { | 
|  | printf ("cannot mmap file: %m\n"); | 
|  | result = 1; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | for (c = ps; c < ps + 1000; ++c) | 
|  | if (ptr[c - ps] != '0' + (c % 10)) | 
|  | { | 
|  | printf ("wrong data mapped at offset %zd\n", c); | 
|  | result = 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* That's it.  */ | 
|  | return result; | 
|  | } | 
|  |  | 
|  | #define TEST_FUNCTION do_test () | 
|  | #include "../test-skeleton.c" |