shared mapping of /dev/zero ?

Thomas Koenig (ig25@mvmampc66.ciw.uni-karlsruhe.de)
Fri, 27 Sep 1996 19:58:41 +0200 (MET DST)


Does shared mapping of /dev/zero work at all in 2.0.21? Whenever I try
to do it, I get an EINVAL.

Looking at strace, I find that something else already (probably libc
or the dynamic linker) maps a part of /dev/zero, privately. Is this
what messes things up? I also tried setting the last argument of
mmap to something higher, to avoid collisions, but to no avail.

If this really does not work, what should I use instead? Please,
not the shm* functions - I don't want that memory segment to stay
around until the next reboot if somebody does a kill -9 on my process.

Here's my program (mostly lifted from the pages of Steven's APITUE):

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>

int main()
{
int fd;
caddr_t a;

if ((fd = open("/dev/zero", O_RDWR)) == -1) {
perror("open of /dev/zero failed");
exit(EXIT_FAILURE);
}
a = mmap (0, 8192, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE,
fd, 0);
if (a == (caddr_t) -1) {
perror("mmap failed");
exit(EXIT_FAILURE);
}
printf("a = %p\n",a);
return 0;
}

Here's my strace:

execve("./a.out", ["./a.out"], [/* 37 vars */]) = 0
open("/dev/zero", O_RDONLY) = 4
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE, 4, 0) = 0x40006000
close(4) = 0
mprotect(0x40000000, 17899, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mprotect(0x8048000, 1535, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
getuid() = 11025
geteuid() = 11025
getgid() = 11000
getegid() = 11000
stat("/etc/ld.so.cache", {st_mode=S_IFREG|0644, st_size=3599, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY) = 4
mmap(0, 3599, PROT_READ, MAP_SHARED, 4, 0) = 0x40007000
close(4) = 0
open("/usr/lib/libc.so.5", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libc.so.5", O_RDONLY) = 4
open("/dev/zero", O_RDONLY) = 5
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096) = 4096
mmap(0, 724992, PROT_NONE, MAP_PRIVATE, 5, 0) = 0x40008000
mmap(0x40008000, 496206, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 4, 0) = 0x40008000
mmap(0x40082000, 20032, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 4, 0x79000) = 0x40082000
mmap(0x40087000, 204584, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 5, 0) = 0x40087000
close(5) = 0
close(4) = 0
mprotect(0x40008000, 496206, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
munmap(0x40007000, 3599) = 0
mprotect(0x8048000, 1535, PROT_READ|PROT_EXEC) = 0
mprotect(0x40008000, 496206, PROT_READ|PROT_EXEC) = 0
mprotect(0x40000000, 17899, PROT_READ|PROT_EXEC) = 0
personality(PER_LINUX) = 0
open("/dev/zero", O_RDWR) = 4
mmap(0, 8192, PROT_READ|PROT_WRITE, MAP_SHARED, 4, 0) = -1 EINVAL (Invalid argument)
brk(0x80496ec) = 0x80496ec
brk(0x804a000) = 0x804a000
open("/usr/share/locale/C/LC_MESSAGES", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/etc/locale/C/libc.cat", 0xbffff1a4) = -1 ENOENT (No such file or directory)
stat("/usr/lib/locale/C/libc.cat", 0xbffff1a4) = -1 ENOENT (No such file or directory)
stat("/usr/lib/locale/libc/C", 0xbffff1a4) = -1 ENOENT (No such file or directory)
stat("/usr/share/locale/C/libc.cat", 0xbffff1a4) = -1 ENOENT (No such file or directory)
stat("/usr/local/share/locale/C/libc.cat", 0xbffff1a4) = -1 ENOENT (No such file or directory)
write(2, "mmap failed: Invalid argument\n", 30) = 30
_exit(1) = ?

-- 
Thomas Koenig, Thomas.Koenig@ciw.uni-karlsruhe.de, ig25@dkauni2.bitnet.
The joy of engineering is to find a straight line on a double
logarithmic diagram.