Added fix for Bug 11630
[mono.git] / mcs / class / System.Core / System.IO.MemoryMappedFiles / MemoryMappedFile.cs
1 //
2 // MemoryMappedFile.cs
3 //
4 // Authors:
5 //      Zoltan Varga (vargaz@gmail.com)
6 //
7 // Copyright (C) 2009, Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 #if NET_4_0
29
30 using System;
31 using System.IO;
32 using System.Collections.Generic;
33 using Microsoft.Win32.SafeHandles;
34 using System.Runtime.InteropServices;
35
36
37 #if !MOBILE
38 using Mono.Unix.Native;
39 using Mono.Unix;
40 #else
41 using System.Runtime.CompilerServices;
42 #endif
43
44 namespace System.IO.MemoryMappedFiles
45 {
46         internal static partial class MemoryMapImpl {
47                 static Exception ArgumentCapacity ()
48                 {
49                         return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
50                 }
51
52                 static Exception CapacitySmallerThanSize ()
53                 {
54                         return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size.");
55                 }
56         }
57         
58         
59 #if !MOBILE
60         partial class MemoryMapImpl {
61                 //
62                 // Turns the FileMode into the first half of open(2) flags
63                 //
64                 static OpenFlags ToUnixMode (FileMode mode)
65                 {
66                         switch (mode){
67                         case FileMode.CreateNew:
68                                 return OpenFlags.O_CREAT | OpenFlags.O_EXCL;
69                                 
70                         case FileMode.Create:
71                                 return OpenFlags.O_CREAT | OpenFlags.O_TRUNC;
72                                 
73                         case FileMode.OpenOrCreate:
74                                 return OpenFlags.O_CREAT;
75                                 
76                         case FileMode.Truncate:
77                                 return OpenFlags.O_TRUNC;
78                                 
79                         case FileMode.Append:
80                                 return OpenFlags.O_APPEND;
81                         default:
82                         case FileMode.Open:
83                                 return 0;
84                         }
85                 }
86
87                 //
88                 // Turns the MemoryMappedFileAccess into the second half of open(2) flags
89                 //
90                 static OpenFlags ToUnixMode (MemoryMappedFileAccess access)
91                 {
92                         switch (access){
93                         case MemoryMappedFileAccess.CopyOnWrite:
94                         case MemoryMappedFileAccess.ReadWriteExecute:
95                         case MemoryMappedFileAccess.ReadWrite:
96                                 return OpenFlags.O_RDWR;
97                                 
98                         case MemoryMappedFileAccess.Write:
99                                 return OpenFlags.O_WRONLY;
100
101                         case MemoryMappedFileAccess.ReadExecute:
102                         case MemoryMappedFileAccess.Read:
103                         default:
104                                 return OpenFlags.O_RDONLY;
105                         }
106                 }
107
108                 static MmapProts ToUnixProts (MemoryMappedFileAccess access)
109                 {
110                         switch (access){
111                         case MemoryMappedFileAccess.ReadWrite:
112                                 return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
113                                 
114                         case MemoryMappedFileAccess.Write:
115                                 return MmapProts.PROT_WRITE;
116                                 
117                         case MemoryMappedFileAccess.CopyOnWrite:
118                                 return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
119                                 
120                         case MemoryMappedFileAccess.ReadExecute:
121                                 return MmapProts.PROT_EXEC;
122                                 
123                         case MemoryMappedFileAccess.ReadWriteExecute:
124                                 return MmapProts.PROT_WRITE | MmapProts.PROT_READ | MmapProts.PROT_EXEC;
125                                 
126                         case MemoryMappedFileAccess.Read:
127                         default:
128                                 return MmapProts.PROT_READ;
129                         }
130                 }
131
132                 internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
133                 {
134                         if (MonoUtil.IsUnix){
135                                 Stat buf;
136
137                                 int result = Syscall.stat (path, out buf);
138
139                                 if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){
140                                         if (result == -1)
141                                                 UnixMarshal.ThrowExceptionForLastError ();
142                                 }
143                                 if (mode == FileMode.CreateNew && result == 0)
144                                         throw new IOException ("The file already exists");
145                                 
146                                 if (result == 0){
147                                         if (capacity == 0) {
148                                                 // Special files such as FIFOs, sockets, and devices can
149                                                 // have a size of 0. Specifying a capacity for these
150                                                 // also makes little sense, so don't do the check if the
151                                                 // file is one of these.
152                                                 if (buf.st_size == 0 &&
153                                                     (buf.st_mode & (FilePermissions.S_IFCHR |
154                                                                     FilePermissions.S_IFBLK |
155                                                                     FilePermissions.S_IFIFO |
156                                                                     FilePermissions.S_IFSOCK)) == 0) {
157                                                         throw ArgumentCapacity ();
158                                                 }
159                                                 
160                                                 capacity = buf.st_size;
161                                         } else if (capacity < buf.st_size) {
162                                                 throw CapacitySmallerThanSize ();
163                                         }
164                                 } else {
165                                         if (mode == FileMode.CreateNew){
166                                                 if (capacity == 0)
167                                                         throw ArgumentCapacity ();
168                                         }
169                                 }
170
171                                 int fd = Syscall.open (path, ToUnixMode (mode) | ToUnixMode (access), FilePermissions.DEFFILEMODE);
172
173                                 if (fd == -1)
174                                         UnixMarshal.ThrowExceptionForLastError ();
175                                 return fd;
176                         }
177
178                         throw new NotImplementedException ();
179                 }
180                 
181                 internal static void CloseFD (int fd) {
182                         Syscall.close (fd);
183                 }
184
185                 internal static void Flush (int fd) {
186                         if (MonoUtil.IsUnix)
187                                 Syscall.fsync (fd);
188                         else
189                                 throw new NotImplementedException ("Not implemented on Windows");
190                         
191                 }
192
193                 static int pagesize;
194
195                 internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
196                 {
197                         if (!MonoUtil.IsUnix)
198                                 throw new NotImplementedException ("Not implemented on windows.");
199
200                         if (pagesize == 0)
201                                 pagesize = Syscall.getpagesize ();
202
203                         Stat buf;
204                         Syscall.fstat (file_handle, out buf);
205                         long fsize = buf.st_size;
206
207                         if (size == 0 || size > fsize)
208                                 size = fsize;
209                         
210                         // Align offset
211                         long real_offset = offset & ~(pagesize - 1);
212
213                         offset_diff = (int)(offset - real_offset);
214
215                         // FIXME: Need to determine the unix fd for the file, Handle is only
216                         // equal to it by accident
217                         //
218                         // The new API no longer uses FileStream everywhere, but exposes instead
219                         // the filename (with one exception), we could move this API to use
220                         // file descriptors instead of the FileStream plus its Handle.
221                         //
222                         map_addr = Syscall.mmap (IntPtr.Zero, (ulong) size,
223                                                  ToUnixProts (access),
224                                                  access == MemoryMappedFileAccess.CopyOnWrite ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED,
225                                                  file_handle, real_offset);
226
227                         if (map_addr == (IntPtr)(-1))
228                                 throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
229                 }
230
231                 internal static bool Unmap (IntPtr map_addr, ulong map_size)
232                 {
233                         if (!MonoUtil.IsUnix)
234                                 return false;
235                         return Syscall.munmap (map_addr, map_size) == 0;
236                 }
237
238                 static void ConfigureUnixFD (IntPtr handle, HandleInheritability h)
239                 {
240                         // TODO: Mono.Posix is lacking O_CLOEXEC definitions for fcntl.
241                 }
242
243
244                 [DllImport("kernel32", SetLastError = true)]
245                 static extern bool SetHandleInformation (IntPtr hObject, int dwMask, int dwFlags);
246                 static void ConfigureWindowsFD (IntPtr handle, HandleInheritability h)
247                 {
248                         SetHandleInformation (handle, 1 /* FLAG_INHERIT */, h == HandleInheritability.None ? 0 : 1);
249                 }
250                 
251                 internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
252                 {
253                         if (MonoUtil.IsUnix)
254                                 ConfigureUnixFD (handle, inheritability);
255                         else
256                                 ConfigureWindowsFD (handle, inheritability);
257                 }
258
259         }
260 #else
261         partial class MemoryMapImpl {
262                 [DllImport ("libc")]
263                 static extern int fsync (int fd);
264
265                 [DllImport ("libc")]
266                 static extern int close (int fd);
267
268                 [DllImport ("libc")]
269                 static extern int fcntl (int fd, int cmd, int arg0);
270
271                 //XXX check if android off_t is 64bits or not. on iOS / darwin it is.
272                 [DllImport ("libc")]
273                 static extern IntPtr mmap (IntPtr addr, IntPtr len, int prot, int flags, int fd, long offset);
274
275                 [DllImport ("libc")]
276                 static extern int munmap (IntPtr addr, IntPtr size);
277
278                 [DllImport ("libc", SetLastError=true)]
279                 static extern int open (string path, int flags, int access);
280
281 #if MONODROID
282                 [DllImport ("__Internal")]
283                 static extern int monodroid_getpagesize ();
284
285                 static int getpagesize ()
286                 {
287                         return monodroid_getpagesize ();
288                 }
289 #else
290                 [DllImport ("libc")]
291                 static extern int getpagesize ();
292 #endif
293
294                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
295                 static extern long mono_filesize_from_path (string str);
296
297                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
298                 static extern long mono_filesize_from_fd (int fd);
299
300                 //Values valid on iOS/OSX and android ndk r6
301                 const int F_GETFD = 1;
302                 const int F_SETFD = 2;
303                 const int FD_CLOEXEC = 1;
304                 const int DEFFILEMODE = 0x666;
305
306                 const int O_RDONLY = 0x0;
307                 const int O_WRONLY = 0x1;
308                 const int O_RDWR   = 0x2;
309
310                 const int PROT_READ  = 0x1;
311                 const int PROT_WRITE = 0x2;
312                 const int PROT_EXEC  = 0x4;
313
314                 const int MAP_PRIVATE = 0x2;
315                 const int MAP_SHARED  = 0x1;
316
317                 const int EINVAL = 22;
318
319 #if MONODROID
320                 const int O_CREAT = 0x040;
321                 const int O_TRUNC = 0x080;
322                 const int O_EXCL  = 0x200;
323
324                 const int ENAMETOOLONG = 63;
325 #else
326                 /* MONOTOUCH - usr/include/sys/fcntl.h */
327                 const int O_CREAT = 0x0200;
328                 const int O_TRUNC = 0x0400;
329                 const int O_EXCL  = 0x0800;
330
331                 // usr/include/sys/errno.h
332                 const int ENAMETOOLONG = 63;
333 #endif
334
335                 static int ToUnixMode (FileMode mode)
336                 {
337                         switch (mode) {
338                         case FileMode.CreateNew:
339                                 return O_CREAT | O_EXCL;
340                                 
341                         case FileMode.Create:
342                                 return O_CREAT | O_TRUNC;
343                                 
344                         case FileMode.OpenOrCreate:
345                                 return O_CREAT;
346                                 
347                         case FileMode.Truncate:
348                                 return O_TRUNC;
349                         default:
350                         case FileMode.Open:
351                                 return 0;
352                         }
353                 }
354
355                 //
356                 // Turns the MemoryMappedFileAccess into the second half of open(2) flags
357                 //
358                 static int ToUnixMode (MemoryMappedFileAccess access)
359                 {
360                         switch (access) {
361                         case MemoryMappedFileAccess.CopyOnWrite:
362                         case MemoryMappedFileAccess.ReadWriteExecute:
363                         case MemoryMappedFileAccess.ReadWrite:
364                                 return O_RDWR;
365                                 
366                         case MemoryMappedFileAccess.Write:
367                                 return O_WRONLY;
368
369                         case MemoryMappedFileAccess.ReadExecute:
370                         case MemoryMappedFileAccess.Read:
371                         default:
372                                 return O_RDONLY;
373                         }
374                 }
375
376                 static int ToUnixProts (MemoryMappedFileAccess access)
377                 {
378                         switch (access){
379                         case MemoryMappedFileAccess.ReadWrite:
380                                 return PROT_WRITE | PROT_READ;
381                                 
382                         case MemoryMappedFileAccess.Write:
383                                 return PROT_WRITE;
384                                 
385                         case MemoryMappedFileAccess.CopyOnWrite:
386                                 return PROT_WRITE | PROT_READ;
387                                 
388                         case MemoryMappedFileAccess.ReadExecute:
389                                 return PROT_EXEC;
390                                 
391                         case MemoryMappedFileAccess.ReadWriteExecute:
392                                 return PROT_WRITE | PROT_READ | PROT_EXEC;
393                                 
394                         case MemoryMappedFileAccess.Read:
395                         default:
396                                 return PROT_READ;
397                         }
398                 }
399
400                 static void ThrowErrorFromErrno (int errno) 
401                 {
402                         switch (errno) {
403                         case EINVAL:            throw new ArgumentException ();
404                         case ENAMETOOLONG:      throw new PathTooLongException ();
405                         default: throw new IOException ("Failed with errno " + errno);
406                         }
407                 }
408
409                 internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
410                 {
411                         long file_size = mono_filesize_from_path (path);
412
413                         Console.WriteLine ("{0} is {1} big", path, file_size);
414                         if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){
415                                 if (file_size < 0)
416                                         throw new FileNotFoundException (path);
417                                 if (capacity == 0)
418                                         capacity = file_size;
419                                 if (capacity < file_size)
420                                         throw CapacitySmallerThanSize ();
421                         } else {
422                                 if (mode == FileMode.CreateNew){
423                                         if (file_size >= 0)
424                                                 throw new IOException ("The file already exists");
425                                         if (capacity == 0)
426                                                 throw ArgumentCapacity ();
427                                 }
428                         }
429
430                         int fd = open (path, ToUnixMode (mode) | ToUnixMode (access), DEFFILEMODE);
431
432                         if (fd == -1)
433                                 ThrowErrorFromErrno (Marshal.GetLastWin32Error ());
434                         return fd;
435                 }
436
437                 internal static void CloseFD (int fd)
438                 {
439                         close (fd);
440                 }
441
442                 internal static void Flush (int fd)
443                 {
444                         fsync (fd);
445                 }
446
447                 internal static bool Unmap (IntPtr map_addr, ulong map_size)
448                 {
449                         return munmap (map_addr, (IntPtr)map_size) == 0;
450                 }
451
452                 static int pagesize;
453
454                 internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
455                 {
456                         if (pagesize == 0)
457                                 pagesize = getpagesize ();
458
459                         long fsize = mono_filesize_from_fd (file_handle);
460                         if (fsize < 0)
461                                 throw new FileNotFoundException ();
462
463                         if (size == 0 || size > fsize)
464                                 size = fsize;
465                         
466                         // Align offset
467                         long real_offset = offset & ~(pagesize - 1);
468
469                         offset_diff = (int)(offset - real_offset);
470
471                         map_addr = mmap (IntPtr.Zero, (IntPtr) size,
472                                                  ToUnixProts (access),
473                                                  access == MemoryMappedFileAccess.CopyOnWrite ? MAP_PRIVATE : MAP_SHARED,
474                                                  file_handle, real_offset);
475
476                         if (map_addr == (IntPtr)(-1))
477                                 throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
478                 }
479
480                 internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
481                 {
482                         int fd = (int)handle;
483                         int flags = fcntl (fd, F_GETFD, 0);
484                         if (inheritability == HandleInheritability.None)
485                                 flags &= ~FD_CLOEXEC;
486                         else
487                                 flags |= FD_CLOEXEC;
488                         fcntl (fd, F_SETFD, flags);
489                 }
490
491         }
492 #endif
493
494         public class MemoryMappedFile : IDisposable {
495                 MemoryMappedFileAccess fileAccess;
496                 string name;
497                 long fileCapacity;
498
499                 //
500                 // We allow the use of either the FileStream/keepOpen combo
501                 // or a Unix file descriptor.  This way we avoid the dependency on
502                 // Mono's io-layer having the Unix file descriptors mapped to
503                 // the same io-layer handle
504                 //
505                 FileStream stream;
506                 bool keepOpen;
507                 int unix_fd;
508
509                 public static MemoryMappedFile CreateFromFile (string path)
510                 {
511                         return CreateFromFile (path, FileMode.Open, null, 0, MemoryMappedFileAccess.ReadWrite);
512                 }
513
514                 public static MemoryMappedFile CreateFromFile (string path, FileMode mode)
515                 {
516                         return CreateFromFile (path, mode, null, 0, MemoryMappedFileAccess.ReadWrite);
517                 }
518
519                 public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName)
520                 {
521                         return CreateFromFile (path, mode, mapName, 0, MemoryMappedFileAccess.ReadWrite);
522                 }
523
524                 public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName, long capacity)
525                 {
526                         return CreateFromFile (path, mode, mapName, capacity, MemoryMappedFileAccess.ReadWrite);
527                 }
528
529                 public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName, long capacity, MemoryMappedFileAccess access)
530                 {
531                         if (path == null)
532                                 throw new ArgumentNullException ("path");
533                         if (path.Length == 0)
534                                 throw new ArgumentException ("path");
535                         if (mapName != null && mapName.Length == 0)
536                                 throw new ArgumentException ("mapName");
537                         if (mode == FileMode.Append)
538                                 throw new ArgumentException ("mode");                   
539                         if (capacity < 0)
540                                 throw new ArgumentOutOfRangeException ("capacity");
541
542                         int fd = MemoryMapImpl.Open (path, mode, ref capacity, access);
543                         
544                         return new MemoryMappedFile () {
545                                 unix_fd = fd,
546                                 fileAccess = access,
547                                 name = mapName,
548                                 fileCapacity = capacity
549                         };
550                 }
551
552 #if MOBILE
553                 public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
554                                                                HandleInheritability inheritability,
555                                                                bool leaveOpen)
556 #else
557                 [MonoLimitation ("memoryMappedFileSecurity is currently ignored")]
558                 public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
559                                                                MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability,
560                                                                bool leaveOpen)
561 #endif
562                 {
563                         if (fileStream == null)
564                                 throw new ArgumentNullException ("fileStream");
565                         if (mapName != null && mapName.Length == 0)
566                                 throw new ArgumentException ("mapName");
567                         if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length))
568                                 throw new ArgumentException ("capacity");
569
570                         MemoryMapImpl.ConfigureFD (fileStream.Handle, inheritability);
571                                 
572                         return new MemoryMappedFile () {
573                                 stream = fileStream,
574                                 fileAccess = access,
575                                 name = mapName,
576                                 fileCapacity = capacity,
577                                 keepOpen = leaveOpen
578                         };
579                 }
580
581                 [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
582                 public static MemoryMappedFile CreateNew (string mapName, long capacity)
583                 {
584 #if MOBILE
585                         return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, 0);
586 #else
587                         return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
588 #endif
589                 }
590
591                 [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
592                 public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access) 
593                 {
594 #if MOBILE
595                         return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, 0);
596 #else
597                         return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
598 #endif
599                 }
600
601 #if MOBILE
602                 public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
603                                                           MemoryMappedFileOptions options, 
604                                                           HandleInheritability handleInheritability)
605 #else
606                 [MonoLimitation ("CreateNew requires that mapName be a file name on Unix; options and memoryMappedFileSecurity are ignored")]
607                 public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
608                                                           MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity,
609                                                           HandleInheritability inheritability)
610 #endif
611                 {
612                         return CreateFromFile (mapName, FileMode.CreateNew, mapName, capacity, access);
613                 }
614
615                 [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
616                 public static MemoryMappedFile CreateOrOpen (string mapName, long capacity)
617                 {
618                         return CreateOrOpen (mapName, capacity, MemoryMappedFileAccess.ReadWrite);
619                 }
620
621                 [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
622                 public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access)
623                 {
624                         return CreateFromFile (mapName, FileMode.OpenOrCreate, mapName, capacity, access); 
625                 }
626
627                 [MonoTODO]
628 #if MOBILE
629                 public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability)
630 #else
631                 public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability)
632 #endif
633                 {
634                         throw new NotImplementedException ();
635                 }
636
637                 [MonoTODO]
638                 public static MemoryMappedFile OpenExisting (string mapName)
639                 {
640                         throw new NotImplementedException ();
641                 }
642
643                 [MonoTODO]
644                 public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights)
645                 {
646                         throw new NotImplementedException ();
647                 }
648
649                 [MonoTODO]
650                 public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
651                 {
652                         throw new NotImplementedException ();
653                 }
654
655                 public MemoryMappedViewStream CreateViewStream ()
656                 {
657                         return CreateViewStream (0, 0);
658                 }
659
660                 public MemoryMappedViewStream CreateViewStream (long offset, long size)
661                 {
662                         return CreateViewStream (offset, size, MemoryMappedFileAccess.ReadWrite);
663                 }
664
665                 public MemoryMappedViewStream CreateViewStream (long offset, long size, MemoryMappedFileAccess access)
666                 {
667                         return new MemoryMappedViewStream (stream != null ? (int)stream.Handle : unix_fd, offset, size, access);
668                 }
669
670                 public MemoryMappedViewAccessor CreateViewAccessor ()
671                 {
672                         return CreateViewAccessor (0, 0);
673                 }
674
675                 public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size)
676                 {
677                         return CreateViewAccessor (offset, size, MemoryMappedFileAccess.ReadWrite);
678                 }
679
680                 public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size, MemoryMappedFileAccess access)
681                 {
682                         int file_handle = stream != null ? (int) stream.Handle : unix_fd;
683                         
684                         return new MemoryMappedViewAccessor (file_handle, offset, size, access);
685                 }
686
687                 MemoryMappedFile ()
688                 {
689                 }
690
691                 public void Dispose ()
692                 {
693                         Dispose (true);
694                 }
695
696                 protected virtual void Dispose (bool disposing)
697                 {
698                         if (disposing){
699                                 if (stream != null){
700                                         if (keepOpen == false)
701                                                 stream.Close ();
702                                         unix_fd = -1;
703                                         stream = null;
704                                 }
705                                 if (unix_fd != -1) {
706                                         MemoryMapImpl.CloseFD (unix_fd);
707                                         unix_fd = -1;
708                                 }
709                         }
710                 }
711
712 #if !MOBILE
713                 [MonoTODO]
714                 public MemoryMappedFileSecurity GetAccessControl ()
715                 {
716                         throw new NotImplementedException ();
717                 }
718
719                 [MonoTODO]
720                 public void SetAccessControl (MemoryMappedFileSecurity memoryMappedFileSecurity)
721                 {
722                         throw new NotImplementedException ();
723                 }
724 #endif
725
726                 [MonoTODO]
727                 public SafeMemoryMappedFileHandle SafeMemoryMappedFileHandle {
728                         get {
729                                 throw new NotImplementedException ();
730                         }
731                 }
732         }
733 }
734
735 #endif