#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"