Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2001-01-16 01:18:14 +0300
committerCorinna Vinschen <corinna@vinschen.de>2001-01-16 01:18:14 +0300
commit9334c89c1da674a01df89be9e8e0afeb8f062c57 (patch)
tree6494ab818bb20c036b8d8ff6a57ddb2f1bd6dd12 /winsup/cygwin/mmap.cc
parentc6dd43f2632c846acdc7596e405c7b9681ccc606 (diff)
* mmap.cc (mmap): Add more parameter checking. Change error output
in case of EINVAL. Treat mmapping /dev/zero like MAP_ANONYMOUS.
Diffstat (limited to 'winsup/cygwin/mmap.cc')
-rw-r--r--winsup/cygwin/mmap.cc69
1 files changed, 42 insertions, 27 deletions
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 5e6277635..efb2718b9 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -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);