MemoryMappedFile.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. //
  2. // MemoryMappedFile.cs
  3. //
  4. // Authors:
  5. // Zoltan Varga ([email protected])
  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. using System;
  30. using System.IO;
  31. using System.Collections.Generic;
  32. using Microsoft.Win32.SafeHandles;
  33. using System.Runtime.InteropServices;
  34. #if !MOBILE
  35. using Mono.Unix.Native;
  36. using Mono.Unix;
  37. #else
  38. using System.Runtime.CompilerServices;
  39. #endif
  40. namespace System.IO.MemoryMappedFiles
  41. {
  42. internal static partial class MemoryMapImpl {
  43. static Exception ArgumentCapacity ()
  44. {
  45. return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
  46. }
  47. static Exception CapacitySmallerThanSize ()
  48. {
  49. return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size.");
  50. }
  51. }
  52. #if !MOBILE
  53. partial class MemoryMapImpl {
  54. //
  55. // Turns the FileMode into the first half of open(2) flags
  56. //
  57. static OpenFlags ToUnixMode (FileMode mode)
  58. {
  59. switch (mode){
  60. case FileMode.CreateNew:
  61. return OpenFlags.O_CREAT | OpenFlags.O_EXCL;
  62. case FileMode.Create:
  63. return OpenFlags.O_CREAT | OpenFlags.O_TRUNC;
  64. case FileMode.OpenOrCreate:
  65. return OpenFlags.O_CREAT;
  66. case FileMode.Truncate:
  67. return OpenFlags.O_TRUNC;
  68. case FileMode.Append:
  69. return OpenFlags.O_APPEND;
  70. default:
  71. case FileMode.Open:
  72. return 0;
  73. }
  74. }
  75. //
  76. // Turns the MemoryMappedFileAccess into the second half of open(2) flags
  77. //
  78. static OpenFlags ToUnixMode (MemoryMappedFileAccess access)
  79. {
  80. switch (access){
  81. case MemoryMappedFileAccess.CopyOnWrite:
  82. case MemoryMappedFileAccess.ReadWriteExecute:
  83. case MemoryMappedFileAccess.ReadWrite:
  84. return OpenFlags.O_RDWR;
  85. case MemoryMappedFileAccess.Write:
  86. return OpenFlags.O_WRONLY;
  87. case MemoryMappedFileAccess.ReadExecute:
  88. case MemoryMappedFileAccess.Read:
  89. default:
  90. return OpenFlags.O_RDONLY;
  91. }
  92. }
  93. static MmapProts ToUnixProts (MemoryMappedFileAccess access)
  94. {
  95. switch (access){
  96. case MemoryMappedFileAccess.ReadWrite:
  97. return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
  98. case MemoryMappedFileAccess.Write:
  99. return MmapProts.PROT_WRITE;
  100. case MemoryMappedFileAccess.CopyOnWrite:
  101. return MmapProts.PROT_WRITE | MmapProts.PROT_READ;
  102. case MemoryMappedFileAccess.ReadExecute:
  103. return MmapProts.PROT_EXEC;
  104. case MemoryMappedFileAccess.ReadWriteExecute:
  105. return MmapProts.PROT_WRITE | MmapProts.PROT_READ | MmapProts.PROT_EXEC;
  106. case MemoryMappedFileAccess.Read:
  107. default:
  108. return MmapProts.PROT_READ;
  109. }
  110. }
  111. internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
  112. {
  113. if (MonoUtil.IsUnix){
  114. Stat buf;
  115. int result = Syscall.stat (path, out buf);
  116. if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){
  117. if (result == -1)
  118. UnixMarshal.ThrowExceptionForLastError ();
  119. }
  120. if (mode == FileMode.CreateNew && result == 0)
  121. throw new IOException ("The file already exists");
  122. if (result == 0){
  123. if (capacity == 0) {
  124. // Special files such as FIFOs, sockets, and devices can
  125. // have a size of 0. Specifying a capacity for these
  126. // also makes little sense, so don't do the check if the
  127. // file is one of these.
  128. if (buf.st_size == 0 &&
  129. (buf.st_mode & (FilePermissions.S_IFCHR |
  130. FilePermissions.S_IFBLK |
  131. FilePermissions.S_IFIFO |
  132. FilePermissions.S_IFSOCK)) == 0) {
  133. throw ArgumentCapacity ();
  134. }
  135. capacity = buf.st_size;
  136. } else if (capacity < buf.st_size) {
  137. throw CapacitySmallerThanSize ();
  138. }
  139. } else {
  140. if (mode == FileMode.CreateNew){
  141. if (capacity == 0)
  142. throw ArgumentCapacity ();
  143. }
  144. }
  145. int fd = Syscall.open (path, ToUnixMode (mode) | ToUnixMode (access), FilePermissions.DEFFILEMODE);
  146. if (fd == -1)
  147. UnixMarshal.ThrowExceptionForLastError ();
  148. return fd;
  149. }
  150. throw new NotImplementedException ();
  151. }
  152. internal static void CloseFD (int fd) {
  153. Syscall.close (fd);
  154. }
  155. internal static void Flush (int fd) {
  156. if (MonoUtil.IsUnix)
  157. Syscall.fsync (fd);
  158. else
  159. throw new NotImplementedException ("Not implemented on Windows");
  160. }
  161. static int pagesize;
  162. internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
  163. {
  164. if (!MonoUtil.IsUnix)
  165. throw new NotImplementedException ("Not implemented on windows.");
  166. if (pagesize == 0)
  167. pagesize = Syscall.getpagesize ();
  168. Stat buf;
  169. Syscall.fstat (file_handle, out buf);
  170. long fsize = buf.st_size;
  171. if (size == 0 || size > fsize)
  172. size = fsize;
  173. // Align offset
  174. long real_offset = offset & ~(pagesize - 1);
  175. offset_diff = (int)(offset - real_offset);
  176. // FIXME: Need to determine the unix fd for the file, Handle is only
  177. // equal to it by accident
  178. //
  179. // The new API no longer uses FileStream everywhere, but exposes instead
  180. // the filename (with one exception), we could move this API to use
  181. // file descriptors instead of the FileStream plus its Handle.
  182. //
  183. map_addr = Syscall.mmap (IntPtr.Zero, (ulong) size,
  184. ToUnixProts (access),
  185. access == MemoryMappedFileAccess.CopyOnWrite ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED,
  186. file_handle, real_offset);
  187. if (map_addr == (IntPtr)(-1))
  188. throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
  189. }
  190. internal static bool Unmap (IntPtr map_addr, ulong map_size)
  191. {
  192. if (!MonoUtil.IsUnix)
  193. return false;
  194. return Syscall.munmap (map_addr, map_size) == 0;
  195. }
  196. static void ConfigureUnixFD (IntPtr handle, HandleInheritability h)
  197. {
  198. // TODO: Mono.Posix is lacking O_CLOEXEC definitions for fcntl.
  199. }
  200. [DllImport("kernel32", SetLastError = true)]
  201. static extern bool SetHandleInformation (IntPtr hObject, int dwMask, int dwFlags);
  202. static void ConfigureWindowsFD (IntPtr handle, HandleInheritability h)
  203. {
  204. SetHandleInformation (handle, 1 /* FLAG_INHERIT */, h == HandleInheritability.None ? 0 : 1);
  205. }
  206. internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
  207. {
  208. if (MonoUtil.IsUnix)
  209. ConfigureUnixFD (handle, inheritability);
  210. else
  211. ConfigureWindowsFD (handle, inheritability);
  212. }
  213. }
  214. #else
  215. partial class MemoryMapImpl {
  216. [DllImport ("libc")]
  217. static extern int fsync (int fd);
  218. [DllImport ("libc")]
  219. static extern int close (int fd);
  220. [DllImport ("libc")]
  221. static extern int fcntl (int fd, int cmd, int arg0);
  222. //XXX check if android off_t is 64bits or not. on iOS / darwin it is.
  223. [DllImport ("libc")]
  224. static extern IntPtr mmap (IntPtr addr, IntPtr len, int prot, int flags, int fd, long offset);
  225. [DllImport ("libc")]
  226. static extern int munmap (IntPtr addr, IntPtr size);
  227. [DllImport ("libc", SetLastError=true)]
  228. static extern int open (string path, int flags, int access);
  229. #if MONODROID
  230. [DllImport ("__Internal")]
  231. static extern int monodroid_getpagesize ();
  232. static int getpagesize ()
  233. {
  234. return monodroid_getpagesize ();
  235. }
  236. #else
  237. [DllImport ("libc")]
  238. static extern int getpagesize ();
  239. #endif
  240. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  241. static extern long mono_filesize_from_path (string str);
  242. [MethodImplAttribute (MethodImplOptions.InternalCall)]
  243. static extern long mono_filesize_from_fd (int fd);
  244. //Values valid on iOS/OSX and android ndk r6
  245. const int F_GETFD = 1;
  246. const int F_SETFD = 2;
  247. const int FD_CLOEXEC = 1;
  248. const int DEFFILEMODE = 0x666;
  249. const int O_RDONLY = 0x0;
  250. const int O_WRONLY = 0x1;
  251. const int O_RDWR = 0x2;
  252. const int PROT_READ = 0x1;
  253. const int PROT_WRITE = 0x2;
  254. const int PROT_EXEC = 0x4;
  255. const int MAP_PRIVATE = 0x2;
  256. const int MAP_SHARED = 0x1;
  257. const int EINVAL = 22;
  258. #if MONODROID
  259. const int O_CREAT = 0x040;
  260. const int O_TRUNC = 0x080;
  261. const int O_EXCL = 0x200;
  262. const int ENAMETOOLONG = 63;
  263. #else
  264. /* MONOTOUCH - usr/include/sys/fcntl.h */
  265. const int O_CREAT = 0x0200;
  266. const int O_TRUNC = 0x0400;
  267. const int O_EXCL = 0x0800;
  268. // usr/include/sys/errno.h
  269. const int ENAMETOOLONG = 63;
  270. #endif
  271. static int ToUnixMode (FileMode mode)
  272. {
  273. switch (mode) {
  274. case FileMode.CreateNew:
  275. return O_CREAT | O_EXCL;
  276. case FileMode.Create:
  277. return O_CREAT | O_TRUNC;
  278. case FileMode.OpenOrCreate:
  279. return O_CREAT;
  280. case FileMode.Truncate:
  281. return O_TRUNC;
  282. default:
  283. case FileMode.Open:
  284. return 0;
  285. }
  286. }
  287. //
  288. // Turns the MemoryMappedFileAccess into the second half of open(2) flags
  289. //
  290. static int ToUnixMode (MemoryMappedFileAccess access)
  291. {
  292. switch (access) {
  293. case MemoryMappedFileAccess.CopyOnWrite:
  294. case MemoryMappedFileAccess.ReadWriteExecute:
  295. case MemoryMappedFileAccess.ReadWrite:
  296. return O_RDWR;
  297. case MemoryMappedFileAccess.Write:
  298. return O_WRONLY;
  299. case MemoryMappedFileAccess.ReadExecute:
  300. case MemoryMappedFileAccess.Read:
  301. default:
  302. return O_RDONLY;
  303. }
  304. }
  305. static int ToUnixProts (MemoryMappedFileAccess access)
  306. {
  307. switch (access){
  308. case MemoryMappedFileAccess.ReadWrite:
  309. return PROT_WRITE | PROT_READ;
  310. case MemoryMappedFileAccess.Write:
  311. return PROT_WRITE;
  312. case MemoryMappedFileAccess.CopyOnWrite:
  313. return PROT_WRITE | PROT_READ;
  314. case MemoryMappedFileAccess.ReadExecute:
  315. return PROT_EXEC;
  316. case MemoryMappedFileAccess.ReadWriteExecute:
  317. return PROT_WRITE | PROT_READ | PROT_EXEC;
  318. case MemoryMappedFileAccess.Read:
  319. default:
  320. return PROT_READ;
  321. }
  322. }
  323. static void ThrowErrorFromErrno (int errno)
  324. {
  325. switch (errno) {
  326. case EINVAL: throw new ArgumentException ();
  327. case ENAMETOOLONG: throw new PathTooLongException ();
  328. default: throw new IOException ("Failed with errno " + errno);
  329. }
  330. }
  331. internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
  332. {
  333. long file_size = mono_filesize_from_path (path);
  334. Console.WriteLine ("{0} is {1} big", path, file_size);
  335. if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){
  336. if (file_size < 0)
  337. throw new FileNotFoundException (path);
  338. if (capacity == 0)
  339. capacity = file_size;
  340. if (capacity < file_size)
  341. throw CapacitySmallerThanSize ();
  342. } else {
  343. if (mode == FileMode.CreateNew){
  344. if (file_size >= 0)
  345. throw new IOException ("The file already exists");
  346. if (capacity == 0)
  347. throw ArgumentCapacity ();
  348. }
  349. }
  350. int fd = open (path, ToUnixMode (mode) | ToUnixMode (access), DEFFILEMODE);
  351. if (fd == -1)
  352. ThrowErrorFromErrno (Marshal.GetLastWin32Error ());
  353. return fd;
  354. }
  355. internal static void CloseFD (int fd)
  356. {
  357. close (fd);
  358. }
  359. internal static void Flush (int fd)
  360. {
  361. fsync (fd);
  362. }
  363. internal static bool Unmap (IntPtr map_addr, ulong map_size)
  364. {
  365. return munmap (map_addr, (IntPtr)map_size) == 0;
  366. }
  367. static int pagesize;
  368. internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff)
  369. {
  370. if (pagesize == 0)
  371. pagesize = getpagesize ();
  372. long fsize = mono_filesize_from_fd (file_handle);
  373. if (fsize < 0)
  374. throw new FileNotFoundException ();
  375. if (size == 0 || size > fsize)
  376. size = fsize;
  377. // Align offset
  378. long real_offset = offset & ~(pagesize - 1);
  379. offset_diff = (int)(offset - real_offset);
  380. map_addr = mmap (IntPtr.Zero, (IntPtr) size,
  381. ToUnixProts (access),
  382. access == MemoryMappedFileAccess.CopyOnWrite ? MAP_PRIVATE : MAP_SHARED,
  383. file_handle, real_offset);
  384. if (map_addr == (IntPtr)(-1))
  385. throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")");
  386. }
  387. internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability)
  388. {
  389. int fd = (int)handle;
  390. int flags = fcntl (fd, F_GETFD, 0);
  391. if (inheritability == HandleInheritability.None)
  392. flags &= ~FD_CLOEXEC;
  393. else
  394. flags |= FD_CLOEXEC;
  395. fcntl (fd, F_SETFD, flags);
  396. }
  397. }
  398. #endif
  399. public class MemoryMappedFile : IDisposable {
  400. MemoryMappedFileAccess fileAccess;
  401. string name;
  402. long fileCapacity;
  403. //
  404. // We allow the use of either the FileStream/keepOpen combo
  405. // or a Unix file descriptor. This way we avoid the dependency on
  406. // Mono's io-layer having the Unix file descriptors mapped to
  407. // the same io-layer handle
  408. //
  409. FileStream stream;
  410. bool keepOpen;
  411. int unix_fd;
  412. public static MemoryMappedFile CreateFromFile (string path)
  413. {
  414. return CreateFromFile (path, FileMode.Open, null, 0, MemoryMappedFileAccess.ReadWrite);
  415. }
  416. public static MemoryMappedFile CreateFromFile (string path, FileMode mode)
  417. {
  418. return CreateFromFile (path, mode, null, 0, MemoryMappedFileAccess.ReadWrite);
  419. }
  420. public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName)
  421. {
  422. return CreateFromFile (path, mode, mapName, 0, MemoryMappedFileAccess.ReadWrite);
  423. }
  424. public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName, long capacity)
  425. {
  426. return CreateFromFile (path, mode, mapName, capacity, MemoryMappedFileAccess.ReadWrite);
  427. }
  428. public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName, long capacity, MemoryMappedFileAccess access)
  429. {
  430. if (path == null)
  431. throw new ArgumentNullException ("path");
  432. if (path.Length == 0)
  433. throw new ArgumentException ("path");
  434. if (mapName != null && mapName.Length == 0)
  435. throw new ArgumentException ("mapName");
  436. if (mode == FileMode.Append)
  437. throw new ArgumentException ("mode");
  438. if (capacity < 0)
  439. throw new ArgumentOutOfRangeException ("capacity");
  440. int fd = MemoryMapImpl.Open (path, mode, ref capacity, access);
  441. return new MemoryMappedFile () {
  442. unix_fd = fd,
  443. fileAccess = access,
  444. name = mapName,
  445. fileCapacity = capacity
  446. };
  447. }
  448. #if MOBILE
  449. public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
  450. HandleInheritability inheritability,
  451. bool leaveOpen)
  452. #else
  453. [MonoLimitation ("memoryMappedFileSecurity is currently ignored")]
  454. public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access,
  455. MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability,
  456. bool leaveOpen)
  457. #endif
  458. {
  459. if (fileStream == null)
  460. throw new ArgumentNullException ("fileStream");
  461. if (mapName != null && mapName.Length == 0)
  462. throw new ArgumentException ("mapName");
  463. if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length))
  464. throw new ArgumentException ("capacity");
  465. MemoryMapImpl.ConfigureFD (fileStream.Handle, inheritability);
  466. return new MemoryMappedFile () {
  467. stream = fileStream,
  468. fileAccess = access,
  469. name = mapName,
  470. fileCapacity = capacity,
  471. keepOpen = leaveOpen
  472. };
  473. }
  474. [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
  475. public static MemoryMappedFile CreateNew (string mapName, long capacity)
  476. {
  477. #if MOBILE
  478. return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, 0);
  479. #else
  480. return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
  481. #endif
  482. }
  483. [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")]
  484. public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access)
  485. {
  486. #if MOBILE
  487. return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, 0);
  488. #else
  489. return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, 0);
  490. #endif
  491. }
  492. #if MOBILE
  493. public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
  494. MemoryMappedFileOptions options,
  495. HandleInheritability handleInheritability)
  496. #else
  497. [MonoLimitation ("CreateNew requires that mapName be a file name on Unix; options and memoryMappedFileSecurity are ignored")]
  498. public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access,
  499. MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity,
  500. HandleInheritability inheritability)
  501. #endif
  502. {
  503. return CreateFromFile (mapName, FileMode.CreateNew, mapName, capacity, access);
  504. }
  505. [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
  506. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity)
  507. {
  508. return CreateOrOpen (mapName, capacity, MemoryMappedFileAccess.ReadWrite);
  509. }
  510. [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")]
  511. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access)
  512. {
  513. return CreateFromFile (mapName, FileMode.OpenOrCreate, mapName, capacity, access);
  514. }
  515. [MonoTODO]
  516. #if MOBILE
  517. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability)
  518. #else
  519. public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability)
  520. #endif
  521. {
  522. throw new NotImplementedException ();
  523. }
  524. [MonoTODO]
  525. public static MemoryMappedFile OpenExisting (string mapName)
  526. {
  527. throw new NotImplementedException ();
  528. }
  529. [MonoTODO]
  530. public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights)
  531. {
  532. throw new NotImplementedException ();
  533. }
  534. [MonoTODO]
  535. public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability)
  536. {
  537. throw new NotImplementedException ();
  538. }
  539. public MemoryMappedViewStream CreateViewStream ()
  540. {
  541. return CreateViewStream (0, 0);
  542. }
  543. public MemoryMappedViewStream CreateViewStream (long offset, long size)
  544. {
  545. return CreateViewStream (offset, size, MemoryMappedFileAccess.ReadWrite);
  546. }
  547. public MemoryMappedViewStream CreateViewStream (long offset, long size, MemoryMappedFileAccess access)
  548. {
  549. return new MemoryMappedViewStream (stream != null ? (int)stream.Handle : unix_fd, offset, size, access);
  550. }
  551. public MemoryMappedViewAccessor CreateViewAccessor ()
  552. {
  553. return CreateViewAccessor (0, 0);
  554. }
  555. public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size)
  556. {
  557. return CreateViewAccessor (offset, size, MemoryMappedFileAccess.ReadWrite);
  558. }
  559. public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size, MemoryMappedFileAccess access)
  560. {
  561. int file_handle = stream != null ? (int) stream.Handle : unix_fd;
  562. return new MemoryMappedViewAccessor (file_handle, offset, size, access);
  563. }
  564. MemoryMappedFile ()
  565. {
  566. }
  567. public void Dispose ()
  568. {
  569. Dispose (true);
  570. }
  571. protected virtual void Dispose (bool disposing)
  572. {
  573. if (disposing){
  574. if (stream != null){
  575. if (keepOpen == false)
  576. stream.Close ();
  577. unix_fd = -1;
  578. stream = null;
  579. }
  580. if (unix_fd != -1) {
  581. MemoryMapImpl.CloseFD (unix_fd);
  582. unix_fd = -1;
  583. }
  584. }
  585. }
  586. #if !MOBILE
  587. [MonoTODO]
  588. public MemoryMappedFileSecurity GetAccessControl ()
  589. {
  590. throw new NotImplementedException ();
  591. }
  592. [MonoTODO]
  593. public void SetAccessControl (MemoryMappedFileSecurity memoryMappedFileSecurity)
  594. {
  595. throw new NotImplementedException ();
  596. }
  597. #endif
  598. [MonoTODO]
  599. public SafeMemoryMappedFileHandle SafeMemoryMappedFileHandle {
  600. get {
  601. throw new NotImplementedException ();
  602. }
  603. }
  604. }
  605. }
  606. #endif