diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2001-04-19 13:16:40 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2001-04-19 13:16:40 +0400 |
commit | e8cec9646ed21bffa7edfb5709ed7b0327884036 (patch) | |
tree | 9ab5a81c5ae0fb43f80e9f890953d5eb5c6768d6 /winsup/testsuite/winsup.api/mmaptest03.c | |
parent | b78d6f6e7b8e38f4f3be6f9ff8e88ce535765256 (diff) |
* winsup.api/mmaptest02.c: New test.
* winsup.api/mmaptest03.c: Ditto.
* winsup.api/mmaptest04.c: Ditto.
Diffstat (limited to 'winsup/testsuite/winsup.api/mmaptest03.c')
-rw-r--r-- | winsup/testsuite/winsup.api/mmaptest03.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/winsup/testsuite/winsup.api/mmaptest03.c b/winsup/testsuite/winsup.api/mmaptest03.c new file mode 100644 index 000000000..6cff97106 --- /dev/null +++ b/winsup/testsuite/winsup.api/mmaptest03.c @@ -0,0 +1,127 @@ +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <setjmp.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/wait.h> +#include <errno.h> + +/* - Checks if mapping of already closed file survives fork() + - Checks if mapping the same region of the same file twice + is done correctly. +*/ + +sigset_t unblock_sigsegv; +jmp_buf r; + +/* filler for file */ +char const line[] = "y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1"; + +void +perror_exit (char *str) +{ + perror (str); + exit (1); +} + +void +sigsegv (int unused) +{ + sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0); + longjmp (r, 1); +} + +int +main(int argc, char **argv) +{ + int i, fd, status; + struct stat statbuf; + char c, *buf1, *buf2; + pid_t pid; + + /* Create data file */ + if ((fd = open("y.txt", O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) + perror_exit ("Can't create data file"); + write (fd, line, sizeof(line) - 1); + close (fd); + + /* Open data file */ + if ((fd = open("y.txt", O_RDONLY)) == -1) + perror_exit ("Can't open data file"); + + if (fstat(fd, &statbuf) < 0) + perror_exit ("fstat failed"); + + if (!statbuf.st_size) + perror_exit ("filesize is 0"); + + if ((buf1 = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) + == MAP_FAILED) + perror_exit ("mmap 1 failed"); + + close(fd); + + /* Open data file a second time */ + if ((fd = open("y.txt", O_RDONLY)) == -1) + perror_exit ("Can't open data file in second run"); + + if ((buf2 = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) + == MAP_FAILED) + perror_exit ("mmap 2 failed"); + + close(fd); + + sigemptyset (&unblock_sigsegv); + sigaddset (&unblock_sigsegv, SIGSEGV); + signal (SIGSEGV, sigsegv); + + if (setjmp (r)) + perror_exit ("SEGV in fork"); + + pid = fork(); + + if (pid == -1) + perror_exit ("fork failed"); + + if (setjmp (r)) + perror_exit (pid ? "SEGV in parent" : "SEGV in child"); + + c = buf1[0]; + c = buf2[0]; + + if (setjmp (r)) + perror_exit (pid ? "SEGV in parent's munmap" : "SEGV in child's munmap"); + + if (munmap(buf1, statbuf.st_size)) + perror_exit (pid ? "munmap failed in parent" : "munmap failed in child"); + + if (setjmp (r) == 0) + { + c = buf1[0]; + perror_exit (pid ? "no SEGV in parent after munmap" : "no SEGV in child after munmap"); + } + + if (setjmp (r)) + perror_exit (pid ? "SEGV in parent after munmap" : "SEGV in child after munmap"); + + c = buf2[0]; + + if (setjmp (r)) + perror_exit (pid ? "SEGV in parent's munmap" : "SEGV in child's munmap"); + + if (munmap(buf2, statbuf.st_size)) + perror_exit (pid ? "munmap failed in parent" : "munmap failed in child"); + + if (pid) + { + waitpid (pid, &status, 0); + unlink ("y.txt"); + if (!WIFEXITED (status) || WEXITSTATUS (status)) + return 1; + } + + return 0; +} |