Merge pull request #2522 from ludovic-henry/test-socketresponder-task
[mono.git] / mcs / class / System.Core / System.IO.MemoryMappedFiles / MemoryMappedFile.cs
index 20973c00c6549f335cc00dce8069ff044925efc7..5bba4d9209b21555441b2a1620e3efbd62864ca5 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_0
-
 using System;
 using System.IO;
 using System.Collections.Generic;
 using Microsoft.Win32.SafeHandles;
 using System.Runtime.InteropServices;
-
-
-#if !MOBILE
-using Mono.Unix.Native;
-using Mono.Unix;
-#else
 using System.Runtime.CompilerServices;
-#endif
+
 
 namespace System.IO.MemoryMappedFiles
 {
-#if !MOBILE
-       internal static class MemoryMapImpl {
-               //
-               // Turns the FileMode into the first half of open(2) flags
-               //
-               static OpenFlags ToUnixMode (FileMode mode)
-               {
-                       switch (mode){
-                       case FileMode.CreateNew:
-                               return OpenFlags.O_CREAT | OpenFlags.O_EXCL;
-                               
-                       case FileMode.Create:
-                               return OpenFlags.O_CREAT | OpenFlags.O_TRUNC;
-                               
-                       case FileMode.OpenOrCreate:
-                               return OpenFlags.O_CREAT;
-                               
-                       case FileMode.Truncate:
-                               return OpenFlags.O_TRUNC;
-                               
-                       case FileMode.Append:
-                               return OpenFlags.O_APPEND;
-                       default:
-                       case FileMode.Open:
-                               return 0;
-                       }
-               }
-
-               //
-               // Turns the MemoryMappedFileAccess into the second half of open(2) flags
-               //
-               static OpenFlags ToUnixMode (MemoryMappedFileAccess access)
-               {
-                       switch (access){
-                       case MemoryMappedFileAccess.CopyOnWrite:
-                       case MemoryMappedFileAccess.ReadWriteExecute:
-                       case MemoryMappedFileAccess.ReadWrite:
-                               return OpenFlags.O_RDWR;
-                               
-                       case MemoryMappedFileAccess.Write:
-                               return OpenFlags.O_WRONLY;
-
-                       case MemoryMappedFileAccess.ReadExecute:
-                       case MemoryMappedFileAccess.Read:
-                       default:
-                               return OpenFlags.O_RDONLY;
-                       }
-               }
-
-               static MmapProts ToUnixProts (MemoryMappedFileAccess access)
-               {
-                       switch (access){
-                       case MemoryMappedFileAccess.ReadWrite:
-                               return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
-                               
-                       case MemoryMappedFileAccess.Write:
-                               return MmapProts.PROT_WRITE;
-                               
-                       case MemoryMappedFileAccess.CopyOnWrite:
-                               return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
-                               
-                       case MemoryMappedFileAccess.ReadExecute:
-                               return MmapProts.PROT_EXEC;
-                               
-                       case MemoryMappedFileAccess.ReadWriteExecute:
-                               return MmapProts.PROT_WRITE | MmapProts.PROT_READ | MmapProts.PROT_EXEC;
-                               
-                       case MemoryMappedFileAccess.Read:
-                       default:
-                               return MmapProts.PROT_READ;
-                       }
-               }
-
-               internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
-               {
-                       if (MonoUtil.IsUnix){
-                               Stat buf;
-                               if (Syscall.stat (path, out buf) == -1)
-                                       UnixMarshal.ThrowExceptionForLastError ();
-
-                               if (capacity == 0) {
-                                       // Special files such as FIFOs, sockets, and devices can
-                                       // have a size of 0. Specifying a capacity for these
-                                       // also makes little sense, so don't do the check if the
-                                       // file is one of these.
-                                       if (buf.st_size == 0 &&
-                                               (buf.st_mode & (FilePermissions.S_IFCHR |
-                                                               FilePermissions.S_IFBLK |
-                                                               FilePermissions.S_IFIFO |
-                                                               FilePermissions.S_IFSOCK)) == 0) {
-                                               throw new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
-                                       }
-
-                                       capacity = buf.st_size;
-                               } else if (capacity < buf.st_size) {
-                                       throw new ArgumentException ("The capacity may not be smaller than the file size.");
-                               }
-
-                               int fd = Syscall.open (path, ToUnixMode (mode) | ToUnixMode (access), FilePermissions.DEFFILEMODE);
-
-                               if (fd == -1)
-                                       UnixMarshal.ThrowExceptionForLastError ();
-                               return fd;
-                       }
-
-                       throw new NotImplementedException ();
-               }
-               
-               internal static void CloseFD (int fd) {
-                       Syscall.close (fd);
-               }
-
-               internal static void Flush (int fd) {
-                       if (MonoUtil.IsUnix)
-                               Syscall.fsync (fd);
-                       else
-                               throw new NotImplementedException ("Not implemented on Windows");
-                       
-               }
-
-               static int pagesize;
-
-               internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
-               {
-                       if (!MonoUtil.IsUnix)
-                               throw new NotImplementedException ("Not implemented on windows.");
-
-                       if (pagesize == 0)
-                               pagesize = Syscall.getpagesize ();
-
-                       Stat buf;
-                       Syscall.fstat (file_handle, out buf);
-                       long fsize = buf.st_size;
-
-                       if (size == 0 || size > fsize)
-                               size = fsize;
-                       
-                       // Align offset
-                       long real_offset = offset & ~(pagesize - 1);
-
-                       offset_diff = (int)(offset - real_offset);
-
-                       // FIXME: Need to determine the unix fd for the file, Handle is only
-                       // equal to it by accident
-                       //
-                       // The new API no longer uses FileStream everywhere, but exposes instead
-                       // the filename (with one exception), we could move this API to use
-                       // file descriptors instead of the FileStream plus its Handle.
-                       //
-                       map_addr = Syscall.mmap (IntPtr.Zero, (ulong) size,
-                                                ToUnixProts (access),
-                                                access == MemoryMappedFileAccess.CopyOnWrite ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED,
-                                                file_handle, real_offset);
-
-                       if (map_addr == (IntPtr)(-1))
-                               throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
-               }
-
-               internal static bool Unmap (IntPtr map_addr, ulong map_size)
-               {
-                       if (!MonoUtil.IsUnix)
-                               return false;
-                       return Syscall.munmap (map_addr, map_size) == 0;
-               }
-
-               static void ConfigureUnixFD (IntPtr handle, HandleInheritability h)
-               {
-                       // TODO: Mono.Posix is lacking O_CLOEXEC definitions for fcntl.
-               }
-
-
-               [DllImport("kernel32", SetLastError = true)]
-               static extern bool SetHandleInformation (IntPtr hObject, int dwMask, int dwFlags);
-               static void ConfigureWindowsFD (IntPtr handle, HandleInheritability h)
-               {
-                       SetHandleInformation (handle, 1 /* FLAG_INHERIT */, h == HandleInheritability.None ? 0 : 1);
-               }
-               
-               internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
-               {
-                       if (MonoUtil.IsUnix)
-                               ConfigureUnixFD (handle, inheritability);
-                       else
-                               ConfigureWindowsFD (handle, inheritability);
-               }
-
-       }
-#else
        internal static class MemoryMapImpl {
-               [DllImport ("libc")]
-               static extern int fsync (int fd);
-
-               [DllImport ("libc")]
-               static extern int close (int fd);
-
-               [DllImport ("libc")]
-               static extern int fcntl (int fd, int cmd, int arg0);
-
-               //XXX check if android off_t is 64bits or not. on iOS / darwin it is.
-               [DllImport ("libc")]
-               static extern IntPtr mmap (IntPtr addr, IntPtr len, int prot, int flags, int fd, long offset);
-
-               [DllImport ("libc")]
-               static extern int munmap (IntPtr addr, IntPtr size);
-
-               [DllImport ("libc", SetLastError=true)]
-               static extern int open (string path, int flags, int access);
-
-#if MONODROID
-               [DllImport ("__Internal")]
-               static extern int monodroid_getpagesize ();
-
-               static int getpagesize ()
-               {
-                       return monodroid_getpagesize ();
-               }
-#else
-               [DllImport ("libc")]
-               static extern int getpagesize ();
-#endif
-
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               static extern long mono_filesize_from_path (string str);
+               static extern IntPtr OpenFileInternal (string path, FileMode mode, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, out int error);
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               static extern long mono_filesize_from_fd (int fd);
-
-               //Values valid on iOS/OSX and android ndk r6
-               const int F_GETFD = 1;
-               const int F_SETFD = 2;
-               const int FD_CLOEXEC = 1;
-               const int DEFFILEMODE = 0x666;
-
-               const int O_RDONLY = 0x0;
-               const int O_WRONLY = 0x1;
-               const int O_RDWR   = 0x2;
+               static extern IntPtr OpenHandleInternal (IntPtr handle, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, out int error);
 
-               const int PROT_READ  = 0x1;
-               const int PROT_WRITE = 0x2;
-               const int PROT_EXEC  = 0x4;
-
-               const int MAP_PRIVATE = 0x2;
-               const int MAP_SHARED  = 0x1;
-
-               const int EINVAL = 22;
-
-#if MONODROID
-               const int O_CREAT = 0x040;
-               const int O_TRUNC = 0x080;
-               const int O_EXCL  = 0x200;
-
-               const int ENAMETOOLONG = 63;
-#else
-               /* MONOTOUCH - usr/include/sys/fcntl.h */
-               const int O_CREAT = 0x0200;
-               const int O_TRUNC = 0x0400;
-               const int O_EXCL  = 0x0800;
-
-               // usr/include/sys/errno.h
-               const int ENAMETOOLONG = 63;
-#endif
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static void CloseMapping (IntPtr handle);
 
-               static int ToUnixMode (FileMode mode)
-               {
-                       switch (mode) {
-                       case FileMode.CreateNew:
-                               return O_CREAT | O_EXCL;
-                               
-                       case FileMode.Create:
-                               return O_CREAT | O_TRUNC;
-                               
-                       case FileMode.OpenOrCreate:
-                               return O_CREAT;
-                               
-                       case FileMode.Truncate:
-                               return O_TRUNC;
-                       default:
-                       case FileMode.Open:
-                               return 0;
-                       }
-               }
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static void Flush (IntPtr file_handle);
 
-               //
-               // Turns the MemoryMappedFileAccess into the second half of open(2) flags
-               //
-               static int ToUnixMode (MemoryMappedFileAccess access)
-               {
-                       switch (access) {
-                       case MemoryMappedFileAccess.CopyOnWrite:
-                       case MemoryMappedFileAccess.ReadWriteExecute:
-                       case MemoryMappedFileAccess.ReadWrite:
-                               return O_RDWR;
-                               
-                       case MemoryMappedFileAccess.Write:
-                               return O_WRONLY;
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static void ConfigureHandleInheritability (IntPtr handle, HandleInheritability inheritability);
 
-                       case MemoryMappedFileAccess.ReadExecute:
-                       case MemoryMappedFileAccess.Read:
-                       default:
-                               return O_RDONLY;
-                       }
-               }
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static bool Unmap (IntPtr mmap_handle);
 
-               static int ToUnixProts (MemoryMappedFileAccess access)
-               {
-                       switch (access){
-                       case MemoryMappedFileAccess.ReadWrite:
-                               return PROT_WRITE | PROT_READ;
-                               
-                       case MemoryMappedFileAccess.Write:
-                               return PROT_WRITE;
-                               
-                       case MemoryMappedFileAccess.CopyOnWrite:
-                               return PROT_WRITE | PROT_READ;
-                               
-                       case MemoryMappedFileAccess.ReadExecute:
-                               return PROT_EXEC;
-                               
-                       case MemoryMappedFileAccess.ReadWriteExecute:
-                               return PROT_WRITE | PROT_READ | PROT_EXEC;
-                               
-                       case MemoryMappedFileAccess.Read:
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern static int MapInternal (IntPtr handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr mmap_handle, out IntPtr base_address);
+
+               internal static void Map (IntPtr handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr mmap_handle, out IntPtr base_address)
+               {
+                       int error = MapInternal (handle, offset, ref size, access, out mmap_handle, out base_address);
+                       if (error != 0)
+                               throw CreateException (error, "<none>");
+               }
+
+               static Exception CreateException (int error, string path) {
+                       switch (error){
+                       case 1:
+                               return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
+                       case 2:
+                               return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size.");
+                       case 3:
+                               return new FileNotFoundException (path);
+                       case 4:
+                               return new IOException ("The file already exists");
+                       case 5:
+                               return new PathTooLongException ();
+                       case 6:
+                               return new IOException ("Could not open file");
+                       case 7:
+                               return new ArgumentException ("Capacity must be bigger than zero for non-file mappings");
+                       case 8:
+                               return new ArgumentException ("Invalid FileMode value.");
+                       case 9:
+                               return new IOException ("Could not map file");
                        default:
-                               return PROT_READ;
+                               return new IOException ("Failed with unknown error code " + error);
                        }
                }
 
-               static void ThrowErrorFromErrno (int errno) 
-               {
-                       switch (errno) {
-                       case EINVAL:            throw new ArgumentException ();
-                       case ENAMETOOLONG:      throw new PathTooLongException ();
-                       default: throw new IOException ("Failed with errno " + errno);
-                       }
-               }
-
-               internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
-               {
-                       long file_size = mono_filesize_from_path (path);
-                       if (file_size < 0)
-                               throw new FileNotFoundException (path);
-
-                       if (capacity > file_size)
-                               throw new ArgumentException ("capacity");
-
-                       int fd = open (path, ToUnixMode (mode) | ToUnixMode (access), DEFFILEMODE);
-
-                       if (fd == -1)
-                               ThrowErrorFromErrno (Marshal.GetLastWin32Error ());
-                       return fd;
-               }
-
-               internal static void CloseFD (int fd)
-               {
-                       close (fd);
-               }
-
-               internal static void Flush (int fd)
-               {
-                       fsync (fd);
-               }
-
-               internal static bool Unmap (IntPtr map_addr, ulong map_size)
-               {
-                       return munmap (map_addr, (IntPtr)map_size) == 0;
-               }
-
-               static int pagesize;
-
-               internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
+               internal static IntPtr OpenFile (string path, FileMode mode, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options)
                {
-                       if (pagesize == 0)
-                               pagesize = getpagesize ();
-
-                       long fsize = mono_filesize_from_fd (file_handle);
-                       if (fsize < 0)
-                               throw new FileNotFoundException ();
-
-                       if (size == 0 || size > fsize)
-                               size = fsize;
-                       
-                       // Align offset
-                       long real_offset = offset & ~(pagesize - 1);
-
-                       offset_diff = (int)(offset - real_offset);
-
-                       map_addr = mmap (IntPtr.Zero, (IntPtr) size,
-                                                ToUnixProts (access),
-                                                access == MemoryMappedFileAccess.CopyOnWrite ? MAP_PRIVATE : MAP_SHARED,
-                                                file_handle, real_offset);
-
-                       if (map_addr == (IntPtr)(-1))
-                               throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
+                       int error = 0;
+                       IntPtr res = OpenFileInternal (path, mode, mapName, out capacity, access, options, out error);
+                       if (error != 0)
+                               throw CreateException (error, path);
+                       return res;
                }
 
-               internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
+               internal static IntPtr OpenHandle (IntPtr handle, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options)
                {
-                       int fd = (int)handle;
-                       int flags = fcntl (fd, F_GETFD, 0);
-                       if (inheritability == HandleInheritability.None)
-                               flags &= ~FD_CLOEXEC;
-                       else
-                               flags |= FD_CLOEXEC;
-                       fcntl (fd, F_SETFD, flags);
+                       int error = 0;
+                       IntPtr res = OpenHandleInternal (handle, mapName, out capacity, access, options, out error);
+                       if (error != 0)
+                               throw CreateException (error, "<none>");
+                       return res;
                }
-
        }
-#endif
+
 
        public class MemoryMappedFile : IDisposable {
                MemoryMappedFileAccess fileAccess;
@@ -466,7 +123,7 @@ namespace System.IO.MemoryMappedFiles
                //
                FileStream stream;
                bool keepOpen;
-               int unix_fd;
+               IntPtr handle;
 
                public static MemoryMappedFile CreateFromFile (string path)
                {
@@ -475,7 +132,21 @@ namespace System.IO.MemoryMappedFiles
 
                public static MemoryMappedFile CreateFromFile (string path, FileMode mode)
                {
-                       return CreateFromFile (path, mode, null, 0, MemoryMappedFileAccess.ReadWrite);
+                       long capacity = 0;
+                       if (path == null)
+                               throw new ArgumentNullException ("path");
+                       if (path.Length == 0)
+                               throw new ArgumentException ("path");
+                       if (mode == FileMode.Append)
+                               throw new ArgumentException ("mode");
+
+                       IntPtr handle = MemoryMapImpl.OpenFile (path, mode, null, out capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages);
+
+                       return new MemoryMappedFile () {
+                               handle = handle,
+                               fileAccess = MemoryMappedFileAccess.ReadWrite,
+                               fileCapacity = capacity
+                       };
                }
 
                public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName)
@@ -501,26 +172,21 @@ namespace System.IO.MemoryMappedFiles
                        if (capacity < 0)
                                throw new ArgumentOutOfRangeException ("capacity");
 
-                       int fd = MemoryMapImpl.Open (path, mode, ref capacity, access);
+                       IntPtr handle = MemoryMapImpl.OpenFile (path, mode, mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages);
                        
                        return new MemoryMappedFile () {
-                               unix_fd = fd,
+                               handle = handle,
                                fileAccess = access,
                                name = mapName,
                                fileCapacity = capacity
                        };
                }
 
-#if MOBILE
-               public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
-                                                              HandleInheritability inheritability,
-                                                              bool leaveOpen)
-#else
+
                [MonoLimitation ("memoryMappedFileSecurity is currently ignored")]
                public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
                                                               MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability,
                                                               bool leaveOpen)
-#endif
                {
                        if (fileStream == null)
                                throw new ArgumentNullException ("fileStream");
@@ -529,86 +195,92 @@ namespace System.IO.MemoryMappedFiles
                        if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length))
                                throw new ArgumentException ("capacity");
 
-                       MemoryMapImpl.ConfigureFD (fileStream.Handle, inheritability);
+                       IntPtr handle = MemoryMapImpl.OpenHandle (fileStream.Handle, mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages);
+                       
+                       MemoryMapImpl.ConfigureHandleInheritability (handle, inheritability);
                                
                        return new MemoryMappedFile () {
-                               stream = fileStream,
+                               handle = handle,
                                fileAccess = access,
                                name = mapName,
                                fileCapacity = capacity,
+
+                               stream = fileStream,
                                keepOpen = leaveOpen
                        };
                }
 
-               [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
+
+               static MemoryMappedFile CoreShmCreate (string mapName, long capacity, MemoryMappedFileAccess access,
+                                                         MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity,
+                                                         HandleInheritability inheritability, FileMode mode)
+               {
+                       if (mapName != null && mapName.Length == 0)
+                               throw new ArgumentException ("mapName");
+                       if (capacity < 0)
+                               throw new ArgumentOutOfRangeException ("capacity");
+
+                       IntPtr handle = MemoryMapImpl.OpenFile (null, mode, mapName, out capacity, access, options);
+                       
+                       return new MemoryMappedFile () {
+                               handle = handle,
+                               fileAccess = access,
+                               name = mapName,
+                               fileCapacity = capacity
+                       };                      
+               }
+
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateNew (string mapName, long capacity)
                {
-#if MOBILE
-                       return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, 0);
-#else
-                       return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
-#endif
+                       return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
                }
 
-               [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access) 
                {
-#if MOBILE
-                       return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, 0);
-#else
-                       return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
-#endif
+                       return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
                }
 
-#if MOBILE
-               public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
-                                                         MemoryMappedFileOptions options, 
-                                                         HandleInheritability handleInheritability)
-#else
-               [MonoLimitation ("CreateNew requires that mapName be a file name on Unix; options and memoryMappedFileSecurity are ignored")]
+               [MonoLimitation ("Named mappings scope is process local; options and memoryMappedFileSecurity are ignored")]
                public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
                                                          MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity,
                                                          HandleInheritability inheritability)
-#endif
                {
-                       return CreateFromFile (mapName, FileMode.CreateNew, mapName, capacity, access);
+                       return CoreShmCreate (mapName, capacity, access, options, memoryMappedFileSecurity, inheritability, FileMode.CreateNew);
                }
 
-               [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateOrOpen (string mapName, long capacity)
                {
                        return CreateOrOpen (mapName, capacity, MemoryMappedFileAccess.ReadWrite);
                }
 
-               [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access)
                {
-                       return CreateFromFile (mapName, FileMode.OpenOrCreate, mapName, capacity, access); 
+                       return CreateOrOpen (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None);
                }
 
-               [MonoTODO]
-#if MOBILE
-               public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability)
-#else
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability)
-#endif
                {
-                       throw new NotImplementedException ();
+                       return CoreShmCreate (mapName, capacity, access, options, memoryMappedFileSecurity, inheritability, FileMode.OpenOrCreate);
                }
 
-               [MonoTODO]
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile OpenExisting (string mapName)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoLimitation ("Named mappings scope is process local")]
                public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
                {
                        throw new NotImplementedException ();
@@ -616,7 +288,7 @@ namespace System.IO.MemoryMappedFiles
 
                public MemoryMappedViewStream CreateViewStream ()
                {
-                       return CreateViewStream (0, 0);
+                       return CreateViewStream (0, 0);//FIXME this is wrong
                }
 
                public MemoryMappedViewStream CreateViewStream (long offset, long size)
@@ -626,7 +298,8 @@ namespace System.IO.MemoryMappedFiles
 
                public MemoryMappedViewStream CreateViewStream (long offset, long size, MemoryMappedFileAccess access)
                {
-                       return new MemoryMappedViewStream (stream != null ? (int)stream.Handle : unix_fd, offset, size, access);
+                       var view = MemoryMappedView.Create (handle, offset, size, access);
+                       return new MemoryMappedViewStream (view);
                }
 
                public MemoryMappedViewAccessor CreateViewAccessor ()
@@ -641,9 +314,8 @@ namespace System.IO.MemoryMappedFiles
 
                public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size, MemoryMappedFileAccess access)
                {
-                       int file_handle = stream != null ? (int) stream.Handle : unix_fd;
-                       
-                       return new MemoryMappedViewAccessor (file_handle, offset, size, access);
+                       var view = MemoryMappedView.Create (handle, offset, size, access);
+                       return new MemoryMappedViewAccessor (view);
                }
 
                MemoryMappedFile ()
@@ -661,17 +333,15 @@ namespace System.IO.MemoryMappedFiles
                                if (stream != null){
                                        if (keepOpen == false)
                                                stream.Close ();
-                                       unix_fd = -1;
                                        stream = null;
                                }
-                               if (unix_fd != -1) {
-                                       MemoryMapImpl.CloseFD (unix_fd);
-                                       unix_fd = -1;
+                               if (handle != IntPtr.Zero) {
+                                       MemoryMapImpl.CloseMapping (handle);
+                                       handle = IntPtr.Zero;
                                }
                        }
                }
 
-#if !MOBILE
                [MonoTODO]
                public MemoryMappedFileSecurity GetAccessControl ()
                {
@@ -683,7 +353,6 @@ namespace System.IO.MemoryMappedFiles
                {
                        throw new NotImplementedException ();
                }
-#endif
 
                [MonoTODO]
                public SafeMemoryMappedFileHandle SafeMemoryMappedFileHandle {
@@ -691,7 +360,34 @@ namespace System.IO.MemoryMappedFiles
                                throw new NotImplementedException ();
                        }
                }
+
+               // This converts a MemoryMappedFileAccess to a FileAccess. MemoryMappedViewStream and
+               // MemoryMappedViewAccessor subclass UnmanagedMemoryStream and UnmanagedMemoryAccessor, which both use
+               // FileAccess to determine whether they are writable and/or readable.
+               internal static FileAccess GetFileAccess (MemoryMappedFileAccess access) {
+
+                       if (access == MemoryMappedFileAccess.Read) {
+                               return FileAccess.Read;
+                       }
+                       if (access == MemoryMappedFileAccess.Write) {
+                               return FileAccess.Write;
+                       }
+                       else if (access == MemoryMappedFileAccess.ReadWrite) {
+                               return FileAccess.ReadWrite;
+                       }
+                       else if (access == MemoryMappedFileAccess.CopyOnWrite) {
+                               return FileAccess.ReadWrite;
+                       }
+                       else if (access == MemoryMappedFileAccess.ReadExecute) {
+                               return FileAccess.Read;
+                       }
+                       else if (access == MemoryMappedFileAccess.ReadWriteExecute) {
+                               return FileAccess.ReadWrite;
+                       }
+
+                       // If we reached here, access was invalid.
+                       throw new ArgumentOutOfRangeException ("access");
+               }
        }
 }
 
-#endif