OSDN Git Service

544e3e43c1b5ed1f70868a6fc687eee56e378bb0
[pf3gnuchains/pf3gnuchains3x.git] / winsup / testsuite / winsup.api / mmaptest03.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <signal.h>
4 #include <setjmp.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <sys/stat.h>
8 #include <sys/mman.h>
9 #include <sys/wait.h>
10 #include <errno.h>
11
12 /* - Checks if mapping of already closed file survives fork()
13    - Checks if mapping the same region of the same file twice
14      is done correctly.
15 */
16
17 sigset_t unblock_sigsegv;
18 jmp_buf r;
19
20 /* filler for file */
21 char const line[] = "y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1";
22
23 void
24 perror_exit (char *str)
25 {    
26   printf ("%s: %s\n", str, strerror (errno));
27   exit (1);
28 }
29
30 void
31 sigsegv (int unused)
32
33   sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0);
34   longjmp (r, 1);
35 }
36
37 int
38 main(int argc, char **argv)
39 {
40   int i, fd, status;
41   struct stat statbuf;
42   char c, *buf1, *buf2;
43   pid_t pid;
44
45   /* Create data file */
46   if ((fd = open("y.txt", O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1)
47     perror_exit ("Can't create data file");
48   write (fd, line, sizeof(line) - 1);
49   close (fd);
50
51   /* Open data file */
52   if ((fd = open("y.txt", O_RDONLY)) == -1)
53     perror_exit ("Can't open data file");
54
55   if (fstat(fd, &statbuf) < 0)
56     perror_exit ("fstat failed");
57
58   if (!statbuf.st_size)
59     perror_exit ("filesize is 0");
60
61   if ((buf1 = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0))
62       == MAP_FAILED)
63     perror_exit ("mmap 1 failed");
64
65   close(fd);
66
67   /* Open data file a second time */
68   if ((fd = open("y.txt", O_RDONLY)) == -1)
69     perror_exit ("Can't open data file in second run");
70
71   if ((buf2 = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0))
72       == MAP_FAILED)
73     perror_exit ("mmap 2 failed");
74
75   close(fd);
76
77   sigemptyset (&unblock_sigsegv);
78   sigaddset (&unblock_sigsegv, SIGSEGV);
79   signal (SIGSEGV, sigsegv);
80
81   if (setjmp (r))
82     perror_exit ("SEGV in fork");
83
84   pid = fork();
85
86   if (pid == -1)
87     perror_exit ("fork failed");
88
89   if (setjmp (r))
90     perror_exit (pid ? "SEGV in parent" : "SEGV in child");
91
92   c = buf1[0];
93   c = buf2[0];
94
95   if (setjmp (r))
96     perror_exit (pid ? "SEGV in parent's munmap" : "SEGV in child's munmap");
97
98   if (munmap(buf1, statbuf.st_size))
99     perror_exit (pid ? "munmap failed in parent" : "munmap failed in child");
100
101   if (setjmp (r) == 0)
102     {
103       c = buf1[0];
104       perror_exit (pid ? "no SEGV in parent after munmap" : "no SEGV in child after munmap");
105     }
106
107   if (setjmp (r))
108     perror_exit (pid ? "SEGV in parent after munmap" : "SEGV in child after munmap");
109
110   c = buf2[0];
111
112   if (setjmp (r))
113     perror_exit (pid ? "SEGV in parent's munmap" : "SEGV in child's munmap");
114
115   if (munmap(buf2, statbuf.st_size))
116     perror_exit (pid ? "munmap failed in parent" : "munmap failed in child");
117
118   if (pid)
119     {
120       waitpid (pid, &status, 0);
121       unlink ("y.txt");
122       if (!WIFEXITED (status) || WEXITSTATUS (status))
123         return 1;
124     }
125
126   return 0;
127 }