Add failed fmap test
This commit is contained in:
+2
-1
@@ -11,7 +11,7 @@ FAILING_TESTS=tls \
|
||||
mkfifo \
|
||||
sigchld \
|
||||
stdlib/ptsname \
|
||||
sys_mman \
|
||||
sys_mman/fmap \
|
||||
signals/pthread_kill-child \
|
||||
unistd/isatty \
|
||||
unistd/link \
|
||||
@@ -276,6 +276,7 @@ VARIED_NAMES=\
|
||||
stdlib/mktemp \
|
||||
stdlib/realpath \
|
||||
sys_epoll/epoll \
|
||||
sys_mman/mmap \
|
||||
sys_resource/constants \
|
||||
sys_socket/getpeername \
|
||||
sys_stat/stat \
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
// copied from autoconf mmap test, currently panicking kernel
|
||||
|
||||
/* Thanks to Mike Haertel and Jim Avera for this test.
|
||||
Here is a matrix of mmap possibilities:
|
||||
mmap private not fixed
|
||||
mmap private fixed at somewhere currently unmapped
|
||||
mmap private fixed at somewhere already mapped
|
||||
mmap shared not fixed
|
||||
mmap shared fixed at somewhere currently unmapped
|
||||
mmap shared fixed at somewhere already mapped
|
||||
For private mappings, we should verify that changes cannot be read()
|
||||
back from the file, nor mmap's back from the file at a different
|
||||
address. (There have been systems where private was not correctly
|
||||
implemented like the infamous i386 svr4.0, and systems where the
|
||||
VM page cache was not coherent with the file system buffer cache
|
||||
like early versions of FreeBSD and possibly contemporary NetBSD.)
|
||||
For shared mappings, we should conversely verify that changes get
|
||||
propagated back to all the places they're supposed to be.
|
||||
|
||||
Grep wants private fixed already mapped.
|
||||
The main things grep needs to know about mmap are:
|
||||
* does it exist and is it safe to write into the mmap'd area
|
||||
* how to use it (BSD variants) */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
char *data, *data2, *data3;
|
||||
const char *cdata2;
|
||||
int i, pagesize;
|
||||
int fd, fd2;
|
||||
|
||||
pagesize = sysconf(_SC_PAGESIZE);
|
||||
|
||||
/* First, make a file with some known garbage in it. */
|
||||
data = (char *) malloc (pagesize);
|
||||
if (!data)
|
||||
return 1;
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
*(data + i) = rand ();
|
||||
umask (0);
|
||||
fd = creat ("conftest.mmap", 0600);
|
||||
if (fd < 0)
|
||||
return 2;
|
||||
if (write (fd, data, pagesize) != pagesize)
|
||||
return 3;
|
||||
close (fd);
|
||||
|
||||
/* Next, check that the tail of a page is zero-filled. File must have
|
||||
non-zero length, otherwise we risk SIGBUS for entire page. */
|
||||
fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd2 < 0)
|
||||
return 4;
|
||||
cdata2 = "";
|
||||
if (write (fd2, cdata2, 1) != 1)
|
||||
return 5;
|
||||
data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L);
|
||||
if (data2 == MAP_FAILED)
|
||||
return 6;
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
if (*(data2 + i))
|
||||
return 7;
|
||||
close (fd2);
|
||||
if (munmap (data2, pagesize))
|
||||
return 8;
|
||||
|
||||
/* Next, try to mmap the file at a fixed address which already has
|
||||
something else allocated at it. If we can, also make sure that
|
||||
we see the same garbage. */
|
||||
fd = open ("conftest.mmap", O_RDWR);
|
||||
if (fd < 0)
|
||||
return 9;
|
||||
if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_FIXED, fd, 0L))
|
||||
return 10;
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
if (*(data + i) != *(data2 + i))
|
||||
return 11;
|
||||
|
||||
/* 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)
|
||||
return 12;
|
||||
if (read (fd, data3, pagesize) != pagesize)
|
||||
return 13;
|
||||
for (i = 0; i < pagesize; ++i)
|
||||
if (*(data + i) != *(data3 + i))
|
||||
return 14;
|
||||
close (fd);
|
||||
free (data);
|
||||
free (data3);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user