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