| /* |
| * Copyright (c) International Business Machines Corp., 2004 |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
| * the GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| /* |
| * FILE NAME : mmapfile.c |
| * |
| * PURPOSE : This executable is invoked by the mmap test case to invoke |
| * mmap() from a process different than mmap. If mmap() is |
| * invoked by the mmap process, a hang will generally occur |
| * because sys_mmap obtains write access to mmap_sem, and any |
| * page fault within the same process (while process is |
| * responding to read/write event generated by mmap() call) |
| * requires read access to the same mmap_sem. |
| * |
| * PARAMETERS : argv[1] - name of file being memory mapped |
| * argv[2] - open flags: |
| * 0 - read-only |
| * 1 - write-only |
| * 2 - read-write |
| * argv[3] - offset within file of memory mapped region |
| * argv[4] - length of memory mapped region |
| * argv[5] - mmap() expected pass/fail status |
| * 0 - fail |
| * 1 - pass |
| * |
| */ |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <errno.h> |
| #include <unistd.h> |
| #include <sys/mman.h> |
| #include <fcntl.h> |
| #include "dm_test.h" |
| |
| char DummyFile[FILENAME_MAX]; |
| |
| int main(int argc, char **argv) |
| { |
| int rc; |
| int fd; |
| int openflags; |
| int offset; |
| int length; |
| int passflag; |
| int flags; |
| void *memmap; |
| |
| if (--argc != 5) { |
| printf("usage: %s filename openflags offset length passflag\n", argv[0]); |
| exit(-1); |
| } |
| |
| passflag = atoi(argv[5]); |
| if ((passflag != 0) && (passflag != 1)) { |
| printf("%s error: invalid passflag %s\n", argv[0], argv[5]); |
| exit(-1); |
| } |
| |
| length = atoi(argv[4]); |
| if (length < 0) { |
| printf("%s error: invalid length %s\n", argv[0], argv[4]); |
| exit(-1); |
| } |
| |
| offset = atoi(argv[3]); |
| if (offset < 0) { |
| printf("%s error: invalid offset %s\n", argv[0], argv[3]); |
| exit(-1); |
| } |
| if (offset & (PAGE_SIZE-1)) { |
| printf("%s error: unaligned offset %d\n", argv[0], offset); |
| exit(-1); |
| } |
| |
| openflags = atoi(argv[2]); |
| if (openflags == O_RDONLY) { |
| flags = PROT_READ; |
| } else if (openflags == O_WRONLY) { |
| flags = PROT_WRITE; |
| } else if (openflags == O_RDWR) { |
| flags = PROT_READ|PROT_WRITE; |
| } else { |
| printf("%s error: invalid openflags %s\n", argv[0], argv[2]); |
| exit(-1); |
| } |
| |
| printf("invoking open(%s, %d)\n", argv[1], openflags); |
| fd = open(argv[1], openflags); |
| if (fd == -1) { |
| printf("%s error: open failed with rc = %d (errno = %d)\n", argv[0], rc, errno); |
| exit(-1); |
| } |
| |
| printf("invoking memmap(%d, %d, %s, %d)\n", length, flags, argv[1], offset); |
| memmap = mmap(NULL, length, flags, MAP_SHARED, fd, offset); |
| if (memmap == MAP_FAILED) { |
| printf("%s error: mmap failed with errno = %d\n", argv[0], errno); |
| if (passflag) { |
| close(fd); |
| exit(-1); |
| } |
| } |
| |
| EVENT_DELIVERY_DELAY; |
| |
| if (memmap != MAP_FAILED) { |
| printf("invoking munmap(%p, %d)\n", memmap, length); |
| munmap(memmap, length); |
| } |
| |
| close(fd); |
| |
| _exit(0); |
| tst_exit(); |
| } |