• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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