* mmap.cc (mmap): Add more parameter checking. Change error output

in case of EINVAL. Treat mmapping /dev/zero like MAP_ANONYMOUS.
This commit is contained in:
Corinna Vinschen 2001-01-15 22:18:14 +00:00
parent c6dd43f263
commit 9334c89c1d
2 changed files with 47 additions and 27 deletions

View File

@ -1,3 +1,8 @@
Mon Jan 15 23:15:00 2001 Corinna Vinschen <corinna@vinschen.de>
* mmap.cc (mmap): Add more parameter checking. Change error output
in case of EINVAL. Treat mmapping /dev/zero like MAP_ANONYMOUS.
Mon Jan 15 20:34:00 2001 Corinna Vinschen <corinna@vinschen.de>
* mmap.cc: include <unistd.h>. Define some bit operations for

View File

@ -332,20 +332,23 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
granularity = si.dwAllocationGranularity;
}
DWORD access = (prot & PROT_WRITE) ? FILE_MAP_WRITE : FILE_MAP_READ;
if (flags & MAP_PRIVATE)
access = FILE_MAP_COPY;
/* Error conditions according to SUSv2 */
if (off % getpagesize ()
|| (!(flags & MAP_SHARED) && !(flags & MAP_PRIVATE))
|| ((flags & MAP_SHARED) && (flags & MAP_PRIVATE))
|| ((flags & MAP_SHARED) && (flags & MAP_ANONYMOUS))
|| ((flags & MAP_FIXED) && ((DWORD)addr % granularity))
|| !len)
{
set_errno (EINVAL);
syscall_printf ("-1 = mmap(): Invalid parameters");
syscall_printf ("-1 = mmap(): EINVAL");
return MAP_FAILED;
}
DWORD access = (prot & PROT_WRITE) ? FILE_MAP_WRITE : FILE_MAP_READ;
if (flags & MAP_PRIVATE)
access = FILE_MAP_COPY;
SetResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
#if 0
@ -378,22 +381,6 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
if (flags & MAP_ANONYMOUS)
fd = -1;
/* First check if this mapping matches into the chunk of another
already performed mapping. */
list *l = mmapped_areas->get_list_by_fd (fd);
if (l)
{
mmap_record *rec;
if ((rec = l->match (off, len)) != NULL)
{
off = rec->map_map (off, len);
caddr_t ret = rec->get_address () + off;
syscall_printf ("%x = mmap() succeeded", ret);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return ret;
}
}
/* Map always in multipliers of `granularity'-sized chunks. */
DWORD gran_off = off & ~(granularity - 1);
DWORD gran_len = howmany (len, granularity) * granularity;
@ -403,12 +390,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
caddr_t base = addr;
HANDLE h;
if (fd == -1)
{
fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
fh = &fh_paging_file;
}
else
if (fd != -1)
{
/* Ensure that fd is open */
if (fdtab.not_open (fd))
@ -426,6 +408,39 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
if (gran_len > fsiz)
gran_len = fsiz;
}
else if (fh->get_device () == FH_ZERO)
{
/* mmap /dev/zero is like MAP_ANONYMOUS. */
if (flags & MAP_SHARED)
{
set_errno (EINVAL);
syscall_printf ("-1 = mmap(): EINVAL");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return MAP_FAILED;
}
fd = -1;
}
}
if (fd == -1)
{
fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
fh = &fh_paging_file;
}
/* First check if this mapping matches into the chunk of another
already performed mapping. */
list *l = mmapped_areas->get_list_by_fd (fd);
if (l)
{
mmap_record *rec;
if ((rec = l->match (off, len)) != NULL)
{
off = rec->map_map (off, len);
caddr_t ret = rec->get_address () + off;
syscall_printf ("%x = mmap() succeeded", ret);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return ret;
}
}
h = fh->mmap (&base, gran_len, access, flags, gran_off);