OSDN Git Service

=====================================
authorcorinna <corinna>
Thu, 5 Oct 2000 13:07:02 +0000 (13:07 +0000)
committercorinna <corinna>
Thu, 5 Oct 2000 13:07:02 +0000 (13:07 +0000)
        These changes require rebuilding all.
        =====================================
        * fhandler.h: Add mmap(), munmap() and msync() to fhandler_base
        and fhandler_disk_file.
        * mmem.cc (mmap): Eliminated device dependent implementation details.
        These are moved to the appropriate fhandler class.
        (munmap): Ditto.
        (msync): Ditto.
        (fhandler_base::mmap): New method.
        (fhandler_base::munmap): Ditto.
        (fhandler_base::msync): Ditto.
        (fhandler_disk_file::mmap): Ditto.
        (fhandler_disk_file::munmap): Ditto.
        (fhandler_disk_file::msync): Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.h
winsup/cygwin/mmap.cc

index 121163e..21b0818 100644 (file)
@@ -1,3 +1,18 @@
+Thu Oct  5 14:58:00 2000  Corinna Vinschen <corinna@vinschen.de>
+
+       * fhandler.h: Add mmap(), munmap() and msync() to fhandler_base
+       and fhandler_disk_file.
+       * mmem.cc (mmap): Eliminated device dependent implementation details.
+       These are moved to the appropriate fhandler class.
+       (munmap): Ditto.
+       (msync): Ditto.
+       (fhandler_base::mmap): New method.
+       (fhandler_base::munmap): Ditto.
+       (fhandler_base::msync): Ditto.
+       (fhandler_disk_file::mmap): Ditto.
+       (fhandler_disk_file::munmap): Ditto.
+       (fhandler_disk_file::msync): Ditto.
+
 Thu Oct  5 01:52:43 2000  Christopher Faylor <cgf@cygnus.com>
 
        * net.cc: General cleanup.
index 3660451..16b0e73 100644 (file)
@@ -263,6 +263,11 @@ public:
   virtual void dump ();
   virtual int dup (fhandler_base *child);
 
+  virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
+                       int flags, off_t off);
+  virtual int munmap (HANDLE h, caddr_t addr, size_t len);
+  virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
+
   void *operator new (size_t, void *p) {return p;}
 
   virtual void init (HANDLE, DWORD, mode_t);
@@ -461,6 +466,11 @@ public:
   int lock (int, struct flock *);
   BOOL is_device () { return FALSE; }
   int fstat (struct stat *buf);
+
+  virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
+                       int flags, off_t off);
+  virtual int munmap (HANDLE h, caddr_t addr, size_t len);
+  virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
 };
 
 class fhandler_serial: public fhandler_base
index cb86a84..7c7d84c 100644 (file)
@@ -166,15 +166,25 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
   syscall_printf ("addr %x, len %d, prot %x, flags %x, fd %d, off %d",
                  addr, len, prot, flags, fd, off);
 
+  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
   /* Windows 95 does not have fixed addresses */
+  /*
+   * CV: This assumption isn't correct. See Microsoft Platform SDK, Memory,
+   * description of call `MapViewOfFileEx'.
+   */
   if ((os_being_run != winNT) && (flags & MAP_FIXED))
     {
       set_errno (EINVAL);
       syscall_printf ("-1 = mmap(): win95 and MAP_FIXED");
       return (caddr_t) -1;
     }
+#endif
 
   if (mmapped_areas == 0)
     {
@@ -188,22 +198,16 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
        }
     }
 
-  DWORD access = (prot & PROT_WRITE) ? FILE_MAP_WRITE : FILE_MAP_READ;
-  if (flags & MAP_PRIVATE)
-    access = FILE_MAP_COPY;
-  DWORD protect;
-
-  if (access & FILE_MAP_COPY)
-    protect = PAGE_WRITECOPY;
-  else if (access & FILE_MAP_WRITE)
-    protect = PAGE_READWRITE;
-  else
-    protect = PAGE_READONLY;
-
-  HANDLE hFile;
+  fhandler_disk_file fh_paging_file (NULL);
+  fhandler_base *fh;
+  caddr_t base = addr;
+  HANDLE h;
 
   if (fd == -1)
-    hFile = (HANDLE) 0xFFFFFFFF;
+    {
+      fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
+      fh = &fh_paging_file;
+    }
   else
     {
       /* Ensure that fd is open */
@@ -214,69 +218,38 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
          ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
          return (caddr_t) -1;
        }
-      hFile = fdtab[fd]->get_handle ();
-    }
-
-  HANDLE h = CreateFileMapping (hFile, &sec_none, protect, 0, len, NULL);
-  if (h == 0)
-    {
-      __seterrno ();
-      syscall_printf ("-1 = mmap(): CreateFileMapping failed with %E");
-      ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
-      return (caddr_t) -1;
+      fh = fdtab[fd];
     }
 
-  void *base;
+  h = fh->mmap (&base, len, access, flags, off);
 
-  if (flags & MAP_FIXED)
-    {
-      base = MapViewOfFileEx (h, access, 0, off, len, addr);
-      if (base != addr)
-       {
-         __seterrno ();
-         syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
-         CloseHandle (h);
-         ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
-         return (caddr_t) -1;
-       }
-    }
-  else
+  if (h == INVALID_HANDLE_VALUE)
     {
-      base = MapViewOfFile (h, access, 0, off, len);
-      if (base == 0)
-       {
-         __seterrno ();
-         syscall_printf ("-1 = mmap(): MapViewOfFile failed with %E");
-         CloseHandle (h);
-         ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
-         return (caddr_t) -1;
-       }
+      ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
+      return MAP_FAILED;
     }
 
   /* Now we should have a successfully mmaped area.
      Need to save it so forked children can reproduce it.
   */
-
   mmap_record mmap_rec (h, access, off, len, base);
 
   /* Get list of mmapped areas for this fd, create a new one if
      one does not exist yet.
   */
-
   list *l = mmapped_areas->get_list_by_fd (fd);
   if (l == 0)
     {
       /* Create a new one */
       l = new list;
       if (l == 0)
-       {
-         UnmapViewOfFile (base);
-         CloseHandle (h);
-         set_errno (ENOMEM);
-         syscall_printf ("-1 = mmap(): ENOMEM");
-         ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
-         return (caddr_t) -1;
-       }
+        {
+          fh->munmap (h, base, len);
+          set_errno (ENOMEM);
+          syscall_printf ("-1 = mmap(): ENOMEM");
+          ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
+          return MAP_FAILED;
+        }
       l = mmapped_areas->add_list (l, fd);
   }
 
@@ -285,7 +258,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
 
   syscall_printf ("%x = mmap() succeeded", base);
   ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
-  return (caddr_t) base;
+  return base;
 }
 
 /* munmap () removes an mmapped area.  It insists that base area
@@ -322,9 +295,19 @@ munmap (caddr_t addr, size_t len)
              mmap_record rec = l->recs[li];
              if (rec.get_address () == addr)
                {
-                 /* Unmap the area */
-                 UnmapViewOfFile (addr);
-                 CloseHandle (rec.get_handle ());
+                  int fd = l->fd;
+                  fhandler_disk_file fh_paging_file (NULL);
+                  fhandler_base *fh;
+
+                  if (fd == -1 || fdtab.not_open (fd))
+                    {
+                      fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
+                      fh = &fh_paging_file;
+                    }
+                  else
+                    fh = fdtab[fd];
+                  fh->munmap (rec.get_handle (), addr, len);
+
                  /* Delete the entry. */
                  l->erase (li);
                  syscall_printf ("0 = munmap(): %x", addr);
@@ -334,8 +317,8 @@ munmap (caddr_t addr, size_t len)
             }
         }
      }
-  set_errno (EINVAL);
 
+  set_errno (EINVAL);
   syscall_printf ("-1 = munmap(): EINVAL");
 
   ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
@@ -351,13 +334,161 @@ msync (caddr_t addr, size_t len, int flags)
   syscall_printf ("addr = %x, len = %d, flags = %x",
                  addr, len, flags);
 
+  /* However, check flags for validity. */
+  if ((flags & ~(MS_ASYNC | MS_SYNC | MS_INVALIDATE))
+      || ((flags & MS_ASYNC) && (flags & MS_SYNC)))
+    {
+      syscall_printf ("-1 = msync(): Invalid flags");
+      set_errno (EINVAL);
+      return -1;
+    }
+
+  SetResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
+  /* Check if a mmap'ed area was ever created */
+  if (mmapped_areas == 0)
+    {
+      syscall_printf ("-1 = msync(): mmapped_areas == 0");
+      set_errno (EINVAL);
+      ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
+      return -1;
+    }
+
+  /* Iterate through the map, looking for the mmapped area.
+     Error if not found. */
+
+  int it;
+  for (it = 0; it < mmapped_areas->nlists; ++it)
+    {
+      list *l = mmapped_areas->lists[it];
+      if (l != 0)
+       {
+         int li;
+         for (li = 0; li < l->nrecs; ++li)
+           {
+             mmap_record rec = l->recs[li];
+             if (rec.get_address () == addr)
+               {
+                  int fd = l->fd;
+                  fhandler_disk_file fh_paging_file (NULL);
+                  fhandler_base *fh;
+
+                  if (fd == -1 || fdtab.not_open (fd))
+                    {
+                      fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
+                      fh = &fh_paging_file;
+                    }
+                  else
+                    fh = fdtab[fd];
+
+                  int ret = fh->msync (rec.get_handle (), addr, len, flags);
+
+                  if (ret)
+                   syscall_printf ("%d = msync(): %E", ret);
+                  else
+                   syscall_printf ("0 = msync()");
+
+                 ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
+                 return 0;
+               }
+            }
+        }
+     }
+
+  /* SUSv2: Return code if indicated memory was not mapped is ENOMEM. */
+  set_errno (ENOMEM);
+  syscall_printf ("-1 = msync(): ENOMEM");
+
+  ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
+  return -1;
+}
+
+/*
+ * Base implementation:
+ *
+ * `mmap' returns ENODEV as documented in SUSv2.
+ * In contrast to the global function implementation, the member function
+ * `mmap' has to return the mapped base address in `addr' and the handle to
+ * the mapping object as return value. In case of failure, the fhandler
+ * mmap has to close that handle by itself and return INVALID_HANDLE_VALUE.
+ *
+ * `munmap' and `msync' get the handle to the mapping object as first parameter
+ * additionally.
+*/
+HANDLE
+fhandler_base::mmap (caddr_t *addr, size_t len, DWORD access,
+                     int flags, off_t off)
+{
+  set_errno (ENODEV);
+  return INVALID_HANDLE_VALUE;
+}
+
+int
+fhandler_base::munmap (HANDLE h, caddr_t addr, size_t len)
+{
+  set_errno (ENODEV);
+  return -1;
+}
+
+int
+fhandler_base::msync (HANDLE h, caddr_t addr, size_t len, int flags)
+{
+  set_errno (ENODEV);
+  return -1;
+}
+
+/* Implementation for disk files. */
+HANDLE
+fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access,
+                          int flags, off_t off)
+{
+  DWORD protect;
+
+  if (access & FILE_MAP_COPY)
+    protect = PAGE_WRITECOPY;
+  else if (access & FILE_MAP_WRITE)
+    protect = PAGE_READWRITE;
+  else
+    protect = PAGE_READONLY;
+
+  HANDLE h = CreateFileMapping (get_handle(), &sec_none, protect, 0, len, NULL);
+  if (h == 0)
+    {
+      __seterrno ();
+      syscall_printf ("-1 = mmap(): CreateFileMapping failed with %E");
+      return INVALID_HANDLE_VALUE;
+    }
+
+  void *base = MapViewOfFileEx (h, access, 0, off, len,
+                               (flags & MAP_FIXED) ? addr : NULL);
+
+  if (!base || ((flags & MAP_FIXED) && base != addr))
+    {
+      __seterrno ();
+      syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
+      CloseHandle (h);
+      return INVALID_HANDLE_VALUE;
+    }
+
+  *addr = (caddr_t) base;
+  return h;
+}
+
+int
+fhandler_disk_file::munmap (HANDLE h, caddr_t addr, size_t len)
+{
+  UnmapViewOfFile (addr);
+  CloseHandle (h);
+  return 0;
+}
+
+int
+fhandler_disk_file::msync (HANDLE h, caddr_t addr, size_t len, int flags)
+{
   if (FlushViewOfFile (addr, len) == 0)
     {
-      syscall_printf ("-1 = msync: %E");
       __seterrno ();
       return -1;
     }
-  syscall_printf ("0 = msync");
   return 0;
 }