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