* winsup.api/mmaptest02.c: New test.
* winsup.api/mmaptest03.c: Ditto. * winsup.api/mmaptest04.c: Ditto.
This commit is contained in:
parent
b78d6f6e7b
commit
e8cec9646e
|
@ -1,3 +1,9 @@
|
|||
2001-04-19 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* winsup.api/mmaptest02.c: New test.
|
||||
* winsup.api/mmaptest03.c: Ditto.
|
||||
* winsup.api/mmaptest04.c: Ditto.
|
||||
|
||||
2001-04-03 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* winsup.api/mmaptest01.c: New test.
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
sigset_t unblock_sigsegv;
|
||||
jmp_buf r;
|
||||
size_t pg;
|
||||
|
||||
int fd;
|
||||
|
||||
/* Checks behaviour of anonymous mmap.
|
||||
|
||||
test_1: If we map a 2-page region and unmap its second page, the first page
|
||||
must remain.
|
||||
|
||||
test_2: If we map a 2-page region and unmap its first page, the second
|
||||
page must remain.
|
||||
|
||||
test_3: If we map two consecutive 1-page regions and unmap them both with
|
||||
one munmap, both must go away.
|
||||
*/
|
||||
|
||||
void
|
||||
perror_exit (char *str, int code)
|
||||
{
|
||||
perror (str);
|
||||
exit (code);
|
||||
}
|
||||
|
||||
void
|
||||
anonmap_init ()
|
||||
{
|
||||
sigemptyset (&unblock_sigsegv);
|
||||
sigaddset (&unblock_sigsegv, SIGSEGV);
|
||||
pg = getpagesize ();
|
||||
fd = open ("/dev/zero", O_RDWR);
|
||||
}
|
||||
|
||||
char *
|
||||
anonmap (size_t size)
|
||||
{
|
||||
return (char *) mmap (0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
}
|
||||
|
||||
void
|
||||
anonfree (char *loc, size_t size)
|
||||
{
|
||||
munmap (loc, size);
|
||||
}
|
||||
|
||||
void
|
||||
sigsegv (int unused)
|
||||
{
|
||||
sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0);
|
||||
longjmp (r, 1);
|
||||
}
|
||||
|
||||
int
|
||||
compare_pointers (const void *a, const void *b)
|
||||
{
|
||||
const char *x = *(const char *const *)a;
|
||||
const char *y = *(const char *const *)b;
|
||||
|
||||
if (x > y)
|
||||
return 1;
|
||||
if (x < y)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
test_1 ()
|
||||
{
|
||||
char *x = anonmap (pg * 2);
|
||||
if (x == (char *)MAP_FAILED)
|
||||
perror_exit ("test 1 mmap", 1);
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r))
|
||||
perror_exit ("test 1 fault", 2);
|
||||
|
||||
x[0] = 1;
|
||||
x[pg] = 1;
|
||||
|
||||
anonfree (x + pg, pg);
|
||||
x[0] = 2;
|
||||
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
x[pg] = 1;
|
||||
perror_exit ("test 1 no fault", 3);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_2 ()
|
||||
{
|
||||
char *x = anonmap (pg * 2);
|
||||
if (x == (char *)MAP_FAILED)
|
||||
perror_exit ("test 2 mmap", 4);
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r))
|
||||
perror_exit ("test 2 fault", 5);
|
||||
|
||||
x[0] = 1;
|
||||
x[pg] = 1;
|
||||
|
||||
anonfree (x, pg);
|
||||
x[pg] = 2;
|
||||
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
x[0] = 1;
|
||||
perror_exit ("test 2 no fault", 6);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_3 ()
|
||||
{
|
||||
char *x[10];
|
||||
char *y;
|
||||
int i;
|
||||
|
||||
/* There's no way to guarantee we get consecutive pages from the OS. The
|
||||
approach taken here is to allocate ten of them, sort the list, and
|
||||
look for consecutive pages. */
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
x[i] = anonmap (pg);
|
||||
if (x[i] == (char *)MAP_FAILED)
|
||||
perror_exit ("test 3 mmap 1", 7);
|
||||
}
|
||||
qsort (x, 10, sizeof (char *), compare_pointers);
|
||||
|
||||
y = 0;
|
||||
for (i = 0; i < 9; i++)
|
||||
if (x[i] + pg == x[i+1])
|
||||
{
|
||||
y = x[i];
|
||||
break;
|
||||
}
|
||||
if (y == 0)
|
||||
{
|
||||
fputs ("test 3: couldn't get two consecutive pages, giving up\n", stderr);
|
||||
exit (65);
|
||||
}
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r))
|
||||
perror_exit ("test 3 fault", 8);
|
||||
|
||||
y[0] = 1;
|
||||
y[pg] = 1;
|
||||
|
||||
anonfree (y, pg * 2);
|
||||
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
y[0] = 1;
|
||||
perror_exit ("test 3 no fault 1", 9);
|
||||
}
|
||||
|
||||
signal (SIGSEGV, sigsegv);
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
y[pg] = 1;
|
||||
perror_exit ("test 3 no fault 2", 10);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
anonmap_init();
|
||||
|
||||
test_1();
|
||||
test_2();
|
||||
test_3();
|
||||
|
||||
exit(0);
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* - Checks if mapping of already closed file survives fork()
|
||||
- Checks if mapping the same region of the same file twice
|
||||
is done correctly.
|
||||
*/
|
||||
|
||||
sigset_t unblock_sigsegv;
|
||||
jmp_buf r;
|
||||
|
||||
/* filler for file */
|
||||
char const line[] = "y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1 y1";
|
||||
|
||||
void
|
||||
perror_exit (char *str)
|
||||
{
|
||||
perror (str);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
void
|
||||
sigsegv (int unused)
|
||||
{
|
||||
sigprocmask (SIG_UNBLOCK, &unblock_sigsegv, 0);
|
||||
longjmp (r, 1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, fd, status;
|
||||
struct stat statbuf;
|
||||
char c, *buf1, *buf2;
|
||||
pid_t pid;
|
||||
|
||||
/* Create data file */
|
||||
if ((fd = open("y.txt", O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1)
|
||||
perror_exit ("Can't create data file");
|
||||
write (fd, line, sizeof(line) - 1);
|
||||
close (fd);
|
||||
|
||||
/* Open data file */
|
||||
if ((fd = open("y.txt", O_RDONLY)) == -1)
|
||||
perror_exit ("Can't open data file");
|
||||
|
||||
if (fstat(fd, &statbuf) < 0)
|
||||
perror_exit ("fstat failed");
|
||||
|
||||
if (!statbuf.st_size)
|
||||
perror_exit ("filesize is 0");
|
||||
|
||||
if ((buf1 = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0))
|
||||
== MAP_FAILED)
|
||||
perror_exit ("mmap 1 failed");
|
||||
|
||||
close(fd);
|
||||
|
||||
/* Open data file a second time */
|
||||
if ((fd = open("y.txt", O_RDONLY)) == -1)
|
||||
perror_exit ("Can't open data file in second run");
|
||||
|
||||
if ((buf2 = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0))
|
||||
== MAP_FAILED)
|
||||
perror_exit ("mmap 2 failed");
|
||||
|
||||
close(fd);
|
||||
|
||||
sigemptyset (&unblock_sigsegv);
|
||||
sigaddset (&unblock_sigsegv, SIGSEGV);
|
||||
signal (SIGSEGV, sigsegv);
|
||||
|
||||
if (setjmp (r))
|
||||
perror_exit ("SEGV in fork");
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid == -1)
|
||||
perror_exit ("fork failed");
|
||||
|
||||
if (setjmp (r))
|
||||
perror_exit (pid ? "SEGV in parent" : "SEGV in child");
|
||||
|
||||
c = buf1[0];
|
||||
c = buf2[0];
|
||||
|
||||
if (setjmp (r))
|
||||
perror_exit (pid ? "SEGV in parent's munmap" : "SEGV in child's munmap");
|
||||
|
||||
if (munmap(buf1, statbuf.st_size))
|
||||
perror_exit (pid ? "munmap failed in parent" : "munmap failed in child");
|
||||
|
||||
if (setjmp (r) == 0)
|
||||
{
|
||||
c = buf1[0];
|
||||
perror_exit (pid ? "no SEGV in parent after munmap" : "no SEGV in child after munmap");
|
||||
}
|
||||
|
||||
if (setjmp (r))
|
||||
perror_exit (pid ? "SEGV in parent after munmap" : "SEGV in child after munmap");
|
||||
|
||||
c = buf2[0];
|
||||
|
||||
if (setjmp (r))
|
||||
perror_exit (pid ? "SEGV in parent's munmap" : "SEGV in child's munmap");
|
||||
|
||||
if (munmap(buf2, statbuf.st_size))
|
||||
perror_exit (pid ? "munmap failed in parent" : "munmap failed in child");
|
||||
|
||||
if (pid)
|
||||
{
|
||||
waitpid (pid, &status, 0);
|
||||
unlink ("y.txt");
|
||||
if (!WIFEXITED (status) || WEXITSTATUS (status))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
char *data, *data2, *data3;
|
||||
int i, pagesize;
|
||||
int fd;
|
||||
|
||||
pagesize = 65536; //getpagesize();
|
||||
|
||||
/*
|
||||
* First, make a file with some known garbage in it.
|
||||
*/
|
||||
data = (char *) malloc (pagesize);
|
||||
if (!data)
|
||||
exit (1);
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
*(data + i) = rand ();
|
||||
umask (0);
|
||||
fd = creat ("conftestmmap", 0600);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf ("creat: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
if (write (fd, data, pagesize) != pagesize)
|
||||
{
|
||||
printf ("write: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
close (fd);
|
||||
|
||||
/*
|
||||
* Next, try to mmap the file.
|
||||
*/
|
||||
fd = open ("conftestmmap", O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf ("write: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
if ((data2 = mmap (data2, pagesize, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE, fd, 0L)) == MAP_FAILED)
|
||||
{
|
||||
printf ("mmap: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
if (*(data + i) != *(data2 + i))
|
||||
{
|
||||
printf ("check-if: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, make sure that changes to the mapped area
|
||||
* do not percolate back to the file as seen by read().
|
||||
* (This is a bug on some variants of i386 svr4.0.)
|
||||
*/
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
*(data2 + i) = *(data2 + i) + 1;
|
||||
data3 = (char *) malloc (pagesize);
|
||||
if (!data3)
|
||||
{
|
||||
printf ("malloc2: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
if (read (fd, data3, pagesize) != pagesize)
|
||||
{
|
||||
printf ("read: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
if (*(data + i) != *(data3 + i))
|
||||
{
|
||||
printf ("check-if2: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
if (msync (data2, pagesize, MS_SYNC))
|
||||
{
|
||||
printf ("msync: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
if (munmap (data2, pagesize))
|
||||
{
|
||||
printf ("munmap: %d\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
close (fd);
|
||||
unlink ("conftestmmap");
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in New Issue