xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/mmap/mmap01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) International Business Machines  Corp., 2001
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software;  you can redistribute it and/or modify
5*49cdfc7eSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License as published by
6*49cdfc7eSAndroid Build Coastguard Worker  * the Free Software Foundation; either version 2 of the License, or
7*49cdfc7eSAndroid Build Coastguard Worker  * (at your option) any later version.
8*49cdfc7eSAndroid Build Coastguard Worker  *
9*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
10*49cdfc7eSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
11*49cdfc7eSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12*49cdfc7eSAndroid Build Coastguard Worker  * the GNU General Public License for more details.
13*49cdfc7eSAndroid Build Coastguard Worker  *
14*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License
15*49cdfc7eSAndroid Build Coastguard Worker  * along with this program;  if not, write to the Free Software
16*49cdfc7eSAndroid Build Coastguard Worker  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*49cdfc7eSAndroid Build Coastguard Worker  */
18*49cdfc7eSAndroid Build Coastguard Worker 
19*49cdfc7eSAndroid Build Coastguard Worker /*
20*49cdfc7eSAndroid Build Coastguard Worker  * Test Description:
21*49cdfc7eSAndroid Build Coastguard Worker  *  Verify that, mmap() succeeds when used to map a file where size of the
22*49cdfc7eSAndroid Build Coastguard Worker  *  file is not a multiple of the page size, the memory area beyond the end
23*49cdfc7eSAndroid Build Coastguard Worker  *  of the file to the end of the page is accessible. Also, verify that
24*49cdfc7eSAndroid Build Coastguard Worker  *  this area is all zeroed and the modifications done to this area are
25*49cdfc7eSAndroid Build Coastguard Worker  *  not written to the file.
26*49cdfc7eSAndroid Build Coastguard Worker  *
27*49cdfc7eSAndroid Build Coastguard Worker  * Expected Result:
28*49cdfc7eSAndroid Build Coastguard Worker  *  mmap() should succeed returning the address of the mapped region.
29*49cdfc7eSAndroid Build Coastguard Worker  *  The memory area beyond the end of file to the end of page should be
30*49cdfc7eSAndroid Build Coastguard Worker  *  filled with zero.
31*49cdfc7eSAndroid Build Coastguard Worker  *  The changes beyond the end of file should not get written to the file.
32*49cdfc7eSAndroid Build Coastguard Worker  *
33*49cdfc7eSAndroid Build Coastguard Worker  * HISTORY
34*49cdfc7eSAndroid Build Coastguard Worker  *	07/2001 Ported by Wayne Boyer
35*49cdfc7eSAndroid Build Coastguard Worker  */
36*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
37*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
38*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
39*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
40*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
41*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
42*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
43*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
44*49cdfc7eSAndroid Build Coastguard Worker #include <stdint.h>
45*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
46*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mman.h>
47*49cdfc7eSAndroid Build Coastguard Worker #include <sys/shm.h>
48*49cdfc7eSAndroid Build Coastguard Worker 
49*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
50*49cdfc7eSAndroid Build Coastguard Worker 
51*49cdfc7eSAndroid Build Coastguard Worker #define TEMPFILE	"mmapfile"
52*49cdfc7eSAndroid Build Coastguard Worker 
53*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "mmap01";
54*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 1;
55*49cdfc7eSAndroid Build Coastguard Worker 
56*49cdfc7eSAndroid Build Coastguard Worker static char *addr;
57*49cdfc7eSAndroid Build Coastguard Worker static char *dummy;
58*49cdfc7eSAndroid Build Coastguard Worker static size_t page_sz;
59*49cdfc7eSAndroid Build Coastguard Worker static size_t file_sz;
60*49cdfc7eSAndroid Build Coastguard Worker static int fildes;
61*49cdfc7eSAndroid Build Coastguard Worker static char cmd_buffer[BUFSIZ];
62*49cdfc7eSAndroid Build Coastguard Worker 
63*49cdfc7eSAndroid Build Coastguard Worker static void setup(void);
64*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void);
65*49cdfc7eSAndroid Build Coastguard Worker 
main(int ac,char ** av)66*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char **av)
67*49cdfc7eSAndroid Build Coastguard Worker {
68*49cdfc7eSAndroid Build Coastguard Worker 	int lc;
69*49cdfc7eSAndroid Build Coastguard Worker 
70*49cdfc7eSAndroid Build Coastguard Worker 	tst_parse_opts(ac, av, NULL, NULL);
71*49cdfc7eSAndroid Build Coastguard Worker 
72*49cdfc7eSAndroid Build Coastguard Worker 	setup();
73*49cdfc7eSAndroid Build Coastguard Worker 
74*49cdfc7eSAndroid Build Coastguard Worker 	for (lc = 0; TEST_LOOPING(lc); lc++) {
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker 		tst_count = 0;
77*49cdfc7eSAndroid Build Coastguard Worker 
78*49cdfc7eSAndroid Build Coastguard Worker 		/*
79*49cdfc7eSAndroid Build Coastguard Worker 		 * Call mmap to map the temporary file beyond EOF
80*49cdfc7eSAndroid Build Coastguard Worker 		 * with write access.
81*49cdfc7eSAndroid Build Coastguard Worker 		 */
82*49cdfc7eSAndroid Build Coastguard Worker 		errno = 0;
83*49cdfc7eSAndroid Build Coastguard Worker 		addr = mmap(NULL, page_sz, PROT_READ | PROT_WRITE,
84*49cdfc7eSAndroid Build Coastguard Worker 			    MAP_FILE | MAP_SHARED, fildes, 0);
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 		/* Check for the return value of mmap() */
87*49cdfc7eSAndroid Build Coastguard Worker 		if (addr == MAP_FAILED) {
88*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE);
89*49cdfc7eSAndroid Build Coastguard Worker 			continue;
90*49cdfc7eSAndroid Build Coastguard Worker 		}
91*49cdfc7eSAndroid Build Coastguard Worker 
92*49cdfc7eSAndroid Build Coastguard Worker 		/*
93*49cdfc7eSAndroid Build Coastguard Worker 		 * Check if mapped memory area beyond EOF are
94*49cdfc7eSAndroid Build Coastguard Worker 		 * zeros and changes beyond EOF are not written
95*49cdfc7eSAndroid Build Coastguard Worker 		 * to file.
96*49cdfc7eSAndroid Build Coastguard Worker 		 */
97*49cdfc7eSAndroid Build Coastguard Worker 		if (memcmp(&addr[file_sz], dummy, page_sz - file_sz)) {
98*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TFAIL, cleanup,
99*49cdfc7eSAndroid Build Coastguard Worker 				 "mapped memory area contains invalid "
100*49cdfc7eSAndroid Build Coastguard Worker 				 "data");
101*49cdfc7eSAndroid Build Coastguard Worker 		}
102*49cdfc7eSAndroid Build Coastguard Worker 
103*49cdfc7eSAndroid Build Coastguard Worker 		/*
104*49cdfc7eSAndroid Build Coastguard Worker 		 * Initialize memory beyond file size
105*49cdfc7eSAndroid Build Coastguard Worker 		 */
106*49cdfc7eSAndroid Build Coastguard Worker 		addr[file_sz] = 'X';
107*49cdfc7eSAndroid Build Coastguard Worker 		addr[file_sz + 1] = 'Y';
108*49cdfc7eSAndroid Build Coastguard Worker 		addr[file_sz + 2] = 'Z';
109*49cdfc7eSAndroid Build Coastguard Worker 
110*49cdfc7eSAndroid Build Coastguard Worker 		/*
111*49cdfc7eSAndroid Build Coastguard Worker 		 * Synchronize the mapped memory region
112*49cdfc7eSAndroid Build Coastguard Worker 		 * with the file.
113*49cdfc7eSAndroid Build Coastguard Worker 		 */
114*49cdfc7eSAndroid Build Coastguard Worker 		if (msync(addr, page_sz, MS_SYNC) != 0) {
115*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TFAIL | TERRNO, cleanup,
116*49cdfc7eSAndroid Build Coastguard Worker 				 "failed to synchronize mapped file");
117*49cdfc7eSAndroid Build Coastguard Worker 		}
118*49cdfc7eSAndroid Build Coastguard Worker 
119*49cdfc7eSAndroid Build Coastguard Worker 		/*
120*49cdfc7eSAndroid Build Coastguard Worker 		 * Now, Search for the pattern 'XYZ' in the
121*49cdfc7eSAndroid Build Coastguard Worker 		 * temporary file.  The pattern should not be
122*49cdfc7eSAndroid Build Coastguard Worker 		 * found and the return value should be 1.
123*49cdfc7eSAndroid Build Coastguard Worker 		 */
124*49cdfc7eSAndroid Build Coastguard Worker 		if (system(cmd_buffer) != 0) {
125*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TPASS,
126*49cdfc7eSAndroid Build Coastguard Worker 				 "Functionality of mmap() successful");
127*49cdfc7eSAndroid Build Coastguard Worker 		} else {
128*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL,
129*49cdfc7eSAndroid Build Coastguard Worker 				 "Specified pattern found in file");
130*49cdfc7eSAndroid Build Coastguard Worker 		}
131*49cdfc7eSAndroid Build Coastguard Worker 
132*49cdfc7eSAndroid Build Coastguard Worker 		/* Clean up things in case we are looping */
133*49cdfc7eSAndroid Build Coastguard Worker 		/* Unmap the mapped memory */
134*49cdfc7eSAndroid Build Coastguard Worker 		if (munmap(addr, page_sz) != 0) {
135*49cdfc7eSAndroid Build Coastguard Worker 			tst_brkm(TFAIL | TERRNO, NULL, "munmap failed");
136*49cdfc7eSAndroid Build Coastguard Worker 		}
137*49cdfc7eSAndroid Build Coastguard Worker 	}
138*49cdfc7eSAndroid Build Coastguard Worker 
139*49cdfc7eSAndroid Build Coastguard Worker 	cleanup();
140*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
141*49cdfc7eSAndroid Build Coastguard Worker }
142*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)143*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
144*49cdfc7eSAndroid Build Coastguard Worker {
145*49cdfc7eSAndroid Build Coastguard Worker 	struct stat stat_buf;
146*49cdfc7eSAndroid Build Coastguard Worker 	char Path_name[PATH_MAX];
147*49cdfc7eSAndroid Build Coastguard Worker 	char write_buf[] = "hello world\n";
148*49cdfc7eSAndroid Build Coastguard Worker 
149*49cdfc7eSAndroid Build Coastguard Worker 	tst_sig(FORK, DEF_HANDLER, cleanup);
150*49cdfc7eSAndroid Build Coastguard Worker 
151*49cdfc7eSAndroid Build Coastguard Worker 	TEST_PAUSE;
152*49cdfc7eSAndroid Build Coastguard Worker 
153*49cdfc7eSAndroid Build Coastguard Worker 	tst_tmpdir();
154*49cdfc7eSAndroid Build Coastguard Worker 
155*49cdfc7eSAndroid Build Coastguard Worker 	/* Get the path of temporary file to be created */
156*49cdfc7eSAndroid Build Coastguard Worker 	if (getcwd(Path_name, sizeof(Path_name)) == NULL) {
157*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, cleanup,
158*49cdfc7eSAndroid Build Coastguard Worker 			 "getcwd failed to get current working directory");
159*49cdfc7eSAndroid Build Coastguard Worker 	}
160*49cdfc7eSAndroid Build Coastguard Worker 
161*49cdfc7eSAndroid Build Coastguard Worker 	/* Creat a temporary file used for mapping */
162*49cdfc7eSAndroid Build Coastguard Worker 	if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
163*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE);
164*49cdfc7eSAndroid Build Coastguard Worker 	}
165*49cdfc7eSAndroid Build Coastguard Worker 
166*49cdfc7eSAndroid Build Coastguard Worker 	/* Write some data into temporary file */
167*49cdfc7eSAndroid Build Coastguard Worker 	if (write(fildes, write_buf, strlen(write_buf)) != (long)strlen(write_buf)) {
168*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, cleanup, "writing to %s", TEMPFILE);
169*49cdfc7eSAndroid Build Coastguard Worker 	}
170*49cdfc7eSAndroid Build Coastguard Worker 
171*49cdfc7eSAndroid Build Coastguard Worker 	/* Get the size of temporary file */
172*49cdfc7eSAndroid Build Coastguard Worker 	if (stat(TEMPFILE, &stat_buf) < 0) {
173*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, cleanup, "stat of %s failed",
174*49cdfc7eSAndroid Build Coastguard Worker 			 TEMPFILE);
175*49cdfc7eSAndroid Build Coastguard Worker 	}
176*49cdfc7eSAndroid Build Coastguard Worker 	file_sz = stat_buf.st_size;
177*49cdfc7eSAndroid Build Coastguard Worker 
178*49cdfc7eSAndroid Build Coastguard Worker 	page_sz = getpagesize();
179*49cdfc7eSAndroid Build Coastguard Worker 
180*49cdfc7eSAndroid Build Coastguard Worker 	/* Allocate and initialize dummy string of system page size bytes */
181*49cdfc7eSAndroid Build Coastguard Worker 	if ((dummy = calloc(page_sz, sizeof(char))) == NULL) {
182*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL, cleanup, "calloc failed (dummy)");
183*49cdfc7eSAndroid Build Coastguard Worker 	}
184*49cdfc7eSAndroid Build Coastguard Worker 
185*49cdfc7eSAndroid Build Coastguard Worker 	/* Create the command which will be executed in the test */
186*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(cmd_buffer, "grep XYZ %s/%s > /dev/null", Path_name, TEMPFILE);
187*49cdfc7eSAndroid Build Coastguard Worker }
188*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)189*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
190*49cdfc7eSAndroid Build Coastguard Worker {
191*49cdfc7eSAndroid Build Coastguard Worker 	close(fildes);
192*49cdfc7eSAndroid Build Coastguard Worker 	free(dummy);
193*49cdfc7eSAndroid Build Coastguard Worker 	tst_rmdir();
194*49cdfc7eSAndroid Build Coastguard Worker }
195