diff options
Diffstat (limited to 'none/tests/solaris/mmap_noreserve.c')
-rw-r--r-- | none/tests/solaris/mmap_noreserve.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/none/tests/solaris/mmap_noreserve.c b/none/tests/solaris/mmap_noreserve.c new file mode 100644 index 000000000..975e95127 --- /dev/null +++ b/none/tests/solaris/mmap_noreserve.c @@ -0,0 +1,90 @@ +/* Maps several pages with or without MAP_NORESEVE. + Mappings with MAP_NORESEVE do not show in /proc/self/xmap + (only in /proc/self/rmap) until they actually materialize. + Very nice from Solaris kernel :-( + */ + +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <wait.h> +#include <sys/mman.h> +#include <sys/param.h> + +static void *do_map(int flags) +{ + flags |= MAP_PRIVATE | MAP_ANON; + void *addr = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, flags, -1, 0); + if (addr == NULL) { + perror("mmap"); + exit(1); + } else { + return addr; + } +} + +static void *do_dlopen(const char *pathname) +{ + int mode = RTLD_LAZY | RTLD_LOCAL; + void *handle = dlopen(pathname, mode); + if (handle == NULL) { + fprintf(stderr, "dlopen failed for %s: %s", + pathname, dlerror()); + exit(1); + } else { + return handle; + } +} + +int main(int argc, const char *argv[]) +{ + do_map(MAP_NORESERVE); + do_dlopen("libm.so"); + do_map(0); + do_map(0); + do_map(MAP_NORESERVE); + do_dlopen("liby.so"); + do_map(MAP_NORESERVE); + do_map(0); + do_map(0); + do_map(MAP_NORESERVE); + do_map(MAP_NORESERVE); + do_dlopen("libz.so"); + do_map(MAP_NORESERVE); + do_map(MAP_NORESERVE); + do_map(0); + + pid_t pid = fork(); + if (pid == -1) { + perror("fork"); + exit(1); + } + + if (pid == 0) { + do_map(MAP_NORESERVE); + do_map(0); + do_map(0); + do_dlopen("libw.so"); + do_map(0); + do_map(MAP_NORESERVE); + do_map(MAP_NORESERVE); + do_map(0); + printf("CHILD: PASSED\n"); + fflush(stdout); + return 0; + } + + int status; + if (waitpid(pid, &status, 0) != pid) { + perror("waitpid"); + } else if ((WIFEXITED(status) != 0) && (WEXITSTATUS(status) == 0)) { + printf("PASSED\n"); + } else { + fprintf(stderr, "FAILED: child exited with unexpected status %s %d\n", + WIFEXITED(status) ? "exit" : "signal", + WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)); + } + + return 0; +} |