1 /* IBM Corporation */
2 /* 01/02/2003	Port to LTP	avenkat@us.ibm.com*/
3 /* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
4 /*
5  *   Copyright (c) International Business Machines  Corp., 2003
6  *
7  *
8  *   This program is free software;  you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
16  *   the GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program;  if not, write to the Free Software
20  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /* mfile_insque:
24  *	This test mmaps a portion of a file, and then mmaps the next
25  *	portion of the file in front of the virtual space containing the
26  *	original mmap.  It then mmaps the preceding portion of the file behind
27  *	the original mmap.  None of the mmaps can be concatenated.
28  */
29 #include <sys/types.h>
30 #include <sys/mman.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <stdio.h>
35 #include <errno.h>
36 /* #include <sys/pte.h> */
37 
38 /*****	LTP Port	*****/
39 #include "test.h"
40 /*****	**	**	*****/
41 
42 #ifndef MMU_NARROWPTEPG
43 #define MMU_NARROWPTEPG	1024
44 #endif
45 
46 /*****	LTP Port	*****/
47 #define FAILED 0
48 #define PASSED 1
49 
50 int local_flag = PASSED;
51 char *TCID = "mmapstress05";	//mfile_insque
52 FILE *temp;
53 int TST_TOTAL = 1;
54 
55 int anyfail();
56 void ok_exit();
57 /*****	**	**	*****/
58 
59 #define ERROR(M)	(void)fprintf(stderr, "%s:  errno = %d; " M "\n", \
60 				progname, errno);
61 #define CLEAN	(void)close(fd); \
62 		if (munmap(mmapaddr+pagesize, pagesize) == -1) { \
63 			ERROR("munmap failed"); \
64 		} \
65 		if (munmap(mmapaddr, pagesize) == -1) { \
66 			ERROR("munmap failed"); \
67 		} \
68 		if (munmap(mmapaddr+2*pagesize, pagesize) == -1) { \
69 			ERROR("munmap failed"); \
70 		} \
71 		if (unlink(tmpname)) { \
72 			ERROR("couldn't clean up temp file"); \
73 		}
74 
75 #define CERROR(M)	CLEAN; ERROR(M)
76 
77 #define CATCH_SIG(SIG) \
78         if (sigaction(SIG, &sa, 0) == -1) { \
79 		ERROR("couldn't catch signal " #SIG); \
80                 exit(1); \
81         }
82 
83 extern time_t time(time_t *);
84 extern char *ctime(const time_t *);
85 extern void exit(int);
86 
87 static int fd;
88 //static char *tmpname; 12/31/02
89 static char tmpname[] = "fileXXXXXX";
90 static char *progname;
91 
92  /*ARGSUSED*/ static
cleanup(int sig)93 void cleanup(int sig)
94 {
95 	/*
96 	 * Don't check error codes - we could be signaled before the file is
97 	 * created.
98 	 */
99 	(void)close(fd);
100 	(void)unlink(tmpname);
101 	exit(1);
102 }
103 
main(int argc,char * argv[])104 int main(int argc, char *argv[])
105 {
106 	size_t pagesize = (size_t) sysconf(_SC_PAGE_SIZE);
107 	caddr_t mmapaddr;
108 	char *buf;
109 	time_t t;
110 	int i;
111 	struct sigaction sa;
112 
113 	if (!argc) {
114 		(void)fprintf(stderr, "argc == 0\n");
115 		return 1;
116 	}
117 	tst_tmpdir();
118 	progname = argv[0];
119 	(void)time(&t);
120 //      (void)printf("%s: Started %s", argv[0], ctime(&t)); LTP Port
121 	if (sbrk(pagesize - ((ulong) sbrk(0) & (pagesize - 1))) == (char *)-1) {
122 		ERROR("couldn't round up brk");
123 		anyfail();
124 	}
125 	if ((buf = sbrk(pagesize)) == (char *)-1) {
126 		ERROR("couldn't allocate output buffer");
127 		anyfail();
128 	}
129 	if ((mmapaddr = (caddr_t) sbrk(0)) == (caddr_t) - 1) {
130 		ERROR("couldn't find top of brk");
131 		anyfail();
132 	}
133 
134 	/* i changed the second argument to NULL
135 	   from argv[0]. otherwise it causes the
136 	   open to fail
137 	   -- sreeni
138 	 */
139 
140 	if ((fd = mkstemp(tmpname)) == -1) {
141 		ERROR("mkstemp failed");
142 		anyfail();
143 	}
144 	sa.sa_handler = cleanup;
145 	sa.sa_flags = 0;
146 	if (sigemptyset(&sa.sa_mask)) {
147 		ERROR("sigemptyset failed");
148 		anyfail();
149 	}
150 	CATCH_SIG(SIGINT);
151 	CATCH_SIG(SIGQUIT);
152 	CATCH_SIG(SIGTERM);
153 	for (i = 0; i < pagesize; i++)
154 		buf[i] = 'a';
155 	if (write(fd, buf, pagesize) != pagesize) {
156 		CERROR("couldn't write page case 1");
157 		anyfail();
158 	}
159 	if (lseek(fd, MMU_NARROWPTEPG * pagesize, SEEK_SET) == -1) {
160 		CERROR("lseek case 1 failed");
161 		anyfail();
162 	}
163 	if (write(fd, buf, pagesize) != pagesize) {
164 		CERROR("couldn't write page case 2");
165 		anyfail();
166 	}
167 	if (lseek(fd, 2 * MMU_NARROWPTEPG * pagesize, SEEK_SET) == -1) {
168 		CERROR("lseek case 2 failed");
169 		anyfail();
170 	}
171 	if (write(fd, buf, pagesize) != pagesize) {
172 		CERROR("couldn't write page case 3");
173 		anyfail();
174 	}
175 	/* fd now references a sparce file which has three pages widely spaced.
176 	 * Hopefully different mfile objects will be needed to reference each
177 	 * page.
178 	 */
179 	if (mmap(mmapaddr + pagesize, pagesize, PROT_READ,
180 		 MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd,
181 		 MMU_NARROWPTEPG * pagesize)
182 	    == (caddr_t) - 1) {
183 		CERROR("first mmap (of third page) failed");
184 		anyfail();
185 	}
186 	if (mmap(mmapaddr, pagesize, PROT_READ,
187 		 MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd,
188 		 2 * MMU_NARROWPTEPG * pagesize)
189 	    == (caddr_t) - 1) {
190 		CERROR("second mmap (of fifth page) failed");
191 		anyfail();
192 	}
193 	if (mmap(mmapaddr + 2 * pagesize, pagesize, PROT_READ,
194 		 MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd, 0) == (caddr_t) - 1) {
195 		CERROR("third mmap (of first page) failed");
196 		anyfail();
197 	}
198 	CLEAN;			/*comment */
199 	(void)time(&t);
200 //      (void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP Port
201 	ok_exit();
202 	tst_exit();
203 }
204 
ok_exit(void)205 void ok_exit(void)
206 {
207 	tst_resm(TPASS, "Test passed\n");
208 	tst_rmdir();
209 	tst_exit();
210 }
211 
anyfail(void)212 int anyfail(void)
213 {
214 	tst_brkm(TFAIL, tst_rmdir, "Test failed\n");
215 }
216