Tim> System: Linux 2.2.15, glibc 2.0.7, gcc 2.7.2.3, Debian 2.1,
Tim> i586.
what type of filesystem is the file on?
Tim> The program listed at the end of this posting demonstrates a
Tim> problem I just discovered. One file that is mmap'ed mysteriously
Tim> has a "!" (exclamation mark) at the end, although no such
Tim> character exists in the file.
this is probably a kernel bug, but there are problems with your code
too.
to cut straight to the point:
Tim> mapped = (char *)mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0);
Tim> close(fd);
Tim> if (mapped==(char *)-1)
Tim> DIE("mapping");
Tim> puts(mapped);
There is a bug here, BTW; if the length of the file is an exact
multiple of the system page size, the puts() call will get SIGSEGV.
(If you replace "length" with "length+1" in the mmap call, then it
should get SIGBUS instead, but I think some implementations give
SIGSEGV instead.)
Otherwise you're depending on the behaviour of mmap() when applied to
partial pages; the length of the mapped area is rounded up to whole
pages. Then you're depending on the fact that the partial page
containing the end of file is supposed to be padded with zeros by the
system (at least one Linux filesystem is known to ignore this
requirement). It looks like your OS is not handling this case
correctly.
OS bugs aside, this technique (treating an mmaped file as a
null-terminated string) is bad practice, because it breaks on files
that happen to fit in whole pages, and also because it doesn't cope
well with null characters appearing in the file.
--
Andrew.
comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
or <URL: http://www.whitefang.com/unix/>