blob: df86b529d335616bfb1b407d73d792f61cc1ba03 [file] [log] [blame]
/*
* 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);
return 0;
}