1 /*
2 * Copyright (c) International Business Machines Corp., 2001
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 /*
20 * Test Description:
21 * Call mmap() with prot parameter set to PROT_READ and with the file
22 * descriptor being open for read, to map a file creating mapped memory
23 * with read access. The minimum file permissions should be 0444.
24 *
25 * The call should succeed to create the mapped region with required
26 * attributes.
27 *
28 * Expected Result:
29 * mmap() should succeed returning the address of the mapped region,
30 * the mapped region should contain the contents of the mapped file.
31 *
32 * HISTORY
33 * 07/2001 Ported by Wayne Boyer
34 */
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <sys/types.h>
38 #include <errno.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <sys/stat.h>
44 #include <sys/mman.h>
45
46 #include "test.h"
47
48 #define TEMPFILE "mmapfile"
49
50 char *TCID = "mmap02";
51 int TST_TOTAL = 1;
52
53 static char *addr;
54 static char *dummy;
55 static size_t page_sz;
56 static int fildes;
57
58 static void setup(void);
59 static void cleanup(void);
60
main(int ac,char ** av)61 int main(int ac, char **av)
62 {
63 int lc;
64
65 tst_parse_opts(ac, av, NULL, NULL);
66
67 setup();
68
69 for (lc = 0; TEST_LOOPING(lc); lc++) {
70
71 tst_count = 0;
72
73 /*
74 * Call mmap to map the temporary file 'TEMPFILE'
75 * with read access.
76 */
77 errno = 0;
78 addr = mmap(0, page_sz, PROT_READ,
79 MAP_FILE | MAP_SHARED, fildes, 0);
80
81 /* Check for the return value of mmap() */
82 if (addr == MAP_FAILED) {
83 tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE);
84 continue;
85 }
86
87 /*
88 * Read the file contents into the dummy
89 * string.
90 */
91 if (read(fildes, dummy, page_sz) < 0) {
92 tst_brkm(TFAIL | TERRNO, cleanup,
93 "reading %s failed", TEMPFILE);
94 }
95
96 /*
97 * Check whether mapped memory region has
98 * the file contents.
99 */
100 if (memcmp(dummy, addr, page_sz)) {
101 tst_resm(TFAIL, "mapped memory area contains "
102 "invalid data");
103 } else {
104 tst_resm(TPASS,
105 "Functionality of mmap() successful");
106 }
107
108 /* Clean up things in case we are looping */
109 /* Unmap the mapped memory */
110 if (munmap(addr, page_sz) != 0) {
111 tst_brkm(TFAIL | TERRNO, cleanup, "munmapping failed");
112 }
113 }
114
115 cleanup();
116 tst_exit();
117 }
118
setup(void)119 static void setup(void)
120 {
121 char *tst_buff;
122
123 tst_sig(FORK, DEF_HANDLER, cleanup);
124
125 TEST_PAUSE;
126
127 page_sz = getpagesize();
128
129 /* Allocate space for the test buffer */
130 if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
131 tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)");
132 }
133
134 /* Fill the test buffer with the known data */
135 memset(tst_buff, 'A', page_sz);
136
137 tst_tmpdir();
138
139 /* Creat a temporary file used for mapping */
140 if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
141 free(tst_buff);
142 tst_brkm(TFAIL | TERRNO, cleanup, "opening %s failed",
143 TEMPFILE);
144 }
145
146 /* Write test buffer contents into temporary file */
147 if (write(fildes, tst_buff, page_sz) < page_sz) {
148 free(tst_buff);
149 tst_brkm(TFAIL | TERRNO, cleanup,
150 "writing to %s failed", TEMPFILE);
151 }
152
153 /* Free the memory allocated for test buffer */
154 free(tst_buff);
155
156 /* Change Mode permissions on Temporary file */
157 if (fchmod(fildes, 0444) < 0) {
158 tst_brkm(TFAIL | TERRNO, cleanup, "fchmod(%s, 0444) failed",
159 TEMPFILE);
160 }
161
162 /* Close the temporary file */
163 if (close(fildes) < 0) {
164 tst_brkm(TFAIL | TERRNO, cleanup, "closing %s failed",
165 TEMPFILE);
166 }
167
168 /* Open the temporary file again, - Readonly mode */
169 if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
170 tst_brkm(TFAIL, cleanup, "reopening %s readonly failed",
171 TEMPFILE);
172 }
173
174 /* Allocate and initialize dummy string of system page size bytes */
175 if ((dummy = calloc(page_sz, sizeof(char))) == NULL) {
176 tst_brkm(TFAIL, cleanup, "calloc failed (dummy)");
177 }
178
179 }
180
cleanup(void)181 static void cleanup(void)
182 {
183 close(fildes);
184 free(dummy);
185 tst_rmdir();
186 }
187