1/* 2 * Copyright (c) International Business Machines Corp., 2004 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 * FILE NAME : mmapfile.c 21 * 22 * PURPOSE : This executable is invoked by the mmap test case to invoke 23 * mmap() from a process different than mmap. If mmap() is 24 * invoked by the mmap process, a hang will generally occur 25 * because sys_mmap obtains write access to mmap_sem, and any 26 * page fault within the same process (while process is 27 * responding to read/write event generated by mmap() call) 28 * requires read access to the same mmap_sem. 29 * 30 * PARAMETERS : argv[1] - name of file being memory mapped 31 * argv[2] - open flags: 32 * 0 - read-only 33 * 1 - write-only 34 * 2 - read-write 35 * argv[3] - offset within file of memory mapped region 36 * argv[4] - length of memory mapped region 37 * argv[5] - mmap() expected pass/fail status 38 * 0 - fail 39 * 1 - pass 40 * 41 */ 42#include <stdio.h> 43#include <string.h> 44#include <stdlib.h> 45#include <errno.h> 46#include <unistd.h> 47#include <sys/mman.h> 48#include <fcntl.h> 49#include "dm_test.h" 50 51char DummyFile[FILENAME_MAX]; 52 53int main(int argc, char **argv) 54{ 55 int rc; 56 int fd; 57 int openflags; 58 int offset; 59 int length; 60 int passflag; 61 int flags; 62 void *memmap; 63 64 if (--argc != 5) { 65 printf("usage: %s filename openflags offset length passflag\n", 66 argv[0]); 67 exit(-1); 68 } 69 70 passflag = atoi(argv[5]); 71 if ((passflag != 0) && (passflag != 1)) { 72 printf("%s error: invalid passflag %s\n", argv[0], argv[5]); 73 exit(-1); 74 } 75 76 length = atoi(argv[4]); 77 if (length < 0) { 78 printf("%s error: invalid length %s\n", argv[0], argv[4]); 79 exit(-1); 80 } 81 82 offset = atoi(argv[3]); 83 if (offset < 0) { 84 printf("%s error: invalid offset %s\n", argv[0], argv[3]); 85 exit(-1); 86 } 87 if (offset & (PAGE_SIZE - 1)) { 88 printf("%s error: unaligned offset %d\n", argv[0], offset); 89 exit(-1); 90 } 91 92 openflags = atoi(argv[2]); 93 if (openflags == O_RDONLY) { 94 flags = PROT_READ; 95 } else if (openflags == O_WRONLY) { 96 flags = PROT_WRITE; 97 } else if (openflags == O_RDWR) { 98 flags = PROT_READ | PROT_WRITE; 99 } else { 100 printf("%s error: invalid openflags %s\n", argv[0], argv[2]); 101 exit(-1); 102 } 103 104 printf("invoking open(%s, %d)\n", argv[1], openflags); 105 fd = open(argv[1], openflags); 106 if (fd == -1) { 107 printf("%s error: open failed with rc = %d (errno = %d)\n", 108 argv[0], rc, errno); 109 exit(-1); 110 } 111 112 printf("invoking memmap(%d, %d, %s, %d)\n", length, flags, argv[1], 113 offset); 114 memmap = mmap(NULL, length, flags, MAP_SHARED, fd, offset); 115 if (memmap == MAP_FAILED) { 116 printf("%s error: mmap failed with errno = %d\n", argv[0], 117 errno); 118 if (passflag) { 119 close(fd); 120 exit(-1); 121 } 122 } 123 124 EVENT_DELIVERY_DELAY; 125 126 if (memmap != MAP_FAILED) { 127 printf("invoking munmap(%p, %d)\n", memmap, length); 128 munmap(memmap, length); 129 } 130 131 close(fd); 132 133 _exit(0); 134 tst_exit(); 135} 136