2 // Mono.Posix/PosixFile.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004 Jonathan Pryor
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
34 namespace Mono
.Posix
{
36 public struct PosixPipes
38 public PosixPipes (PosixStream reading
, PosixStream writing
)
44 public PosixStream Reading
;
45 public PosixStream Writing
;
48 public sealed /* static */ class PosixFile
50 private PosixFile () {}
52 public static bool CanAccess (string path
, AccessMode mode
)
54 int r
= Syscall
.access (path
, mode
);
58 public static void Delete (string path
)
60 int r
= Syscall
.unlink (path
);
61 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
64 public static bool Exists (string path
)
66 int r
= Syscall
.access (path
, AccessMode
.F_OK
);
72 public static long GetConfigurationValue (string path
, PathConf name
)
74 Syscall
.SetLastError ((Error
) 0);
75 long r
= Syscall
.pathconf (path
, name
);
76 if (r
== -1 && Syscall
.GetLastError() != (Error
) 0)
77 PosixMarshal
.ThrowExceptionForLastError ();
81 public static DateTime
GetLastAccessTime (string path
)
83 return new PosixFileInfo (path
).LastAccessTime
;
86 public static Stat
GetFileStatus (string path
)
89 int r
= Syscall
.stat (path
, out stat
);
90 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
94 public static DateTime
GetLastWriteTime (string path
)
96 return new PosixFileInfo(path
).LastWriteTime
;
99 public static DateTime
GetLastStatusChangeTime (string path
)
101 return new PosixFileInfo (path
).LastStatusChangeTime
;
104 public static FilePermissions
GetPermissions (string path
)
106 return new PosixFileInfo (path
).Permissions
;
109 public static string ReadLink (string path
)
111 string r
= TryReadLink (path
);
113 PosixMarshal
.ThrowExceptionForLastError ();
117 public static string TryReadLink (string path
)
119 // Who came up with readlink(2)? There doesn't seem to be a way to
120 // properly handle it.
121 StringBuilder sb
= new StringBuilder (512);
122 int r
= Syscall
.readlink (path
, sb
);
125 return sb
.ToString (0, r
);
128 public static void SetPermissions (string path
, FilePermissions perms
)
130 int r
= Syscall
.chmod (path
, perms
);
131 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
134 public static PosixStream
Create (string path
)
136 FilePermissions mode
= // 0644
137 FilePermissions
.S_IRUSR
| FilePermissions
.S_IWUSR
|
138 FilePermissions
.S_IRGRP
| FilePermissions
.S_IROTH
;
139 return Create (path
, mode
);
142 public static PosixStream
Create (string path
, FilePermissions mode
)
144 int fd
= Syscall
.creat (path
, mode
);
146 PosixMarshal
.ThrowExceptionForLastError ();
147 return new PosixStream (fd
);
150 public static PosixPipes
CreatePipes ()
152 int reading
, writing
;
153 int r
= Syscall
.pipe (out reading
, out writing
);
154 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
155 return new PosixPipes (new PosixStream (reading
), new PosixStream (writing
));
158 public static PosixStream
Open (string path
, OpenFlags flags
)
160 int fd
= Syscall
.open (path
, flags
);
162 PosixMarshal
.ThrowExceptionForLastError ();
163 return new PosixStream (fd
);
166 public static PosixStream
Open (string path
, OpenFlags flags
, FilePermissions mode
)
168 int fd
= Syscall
.open (path
, flags
, mode
);
170 PosixMarshal
.ThrowExceptionForLastError ();
171 return new PosixStream (fd
);
174 public static PosixStream
Open (string path
, FileMode mode
)
176 OpenFlags flags
= ToOpenFlags (mode
, FileAccess
.ReadWrite
);
177 int fd
= Syscall
.open (path
, flags
);
179 PosixMarshal
.ThrowExceptionForLastError ();
180 return new PosixStream (fd
);
183 public static PosixStream
Open (string path
, FileMode mode
, FileAccess access
)
185 OpenFlags flags
= ToOpenFlags (mode
, access
);
186 int fd
= Syscall
.open (path
, flags
);
188 PosixMarshal
.ThrowExceptionForLastError ();
189 return new PosixStream (fd
);
192 public static PosixStream
Open (string path
, FileMode mode
, FileAccess access
, FilePermissions perms
)
194 OpenFlags flags
= ToOpenFlags (mode
, access
);
195 int fd
= Syscall
.open (path
, flags
, perms
);
197 PosixMarshal
.ThrowExceptionForLastError ();
198 return new PosixStream (fd
);
201 public static PosixStream
OpenRead (string path
)
203 return Open (path
, FileMode
.Open
, FileAccess
.Read
);
206 public static PosixStream
OpenWrite (string path
)
208 return Open (path
, FileMode
.OpenOrCreate
, FileAccess
.Write
);
211 public static void SetOwner (string path
, uint owner
, uint group)
213 int r
= Syscall
.chown (path
, owner
, group);
214 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
217 public static void SetOwner (string path
, string owner
)
219 Passwd pw
= Syscall
.getpwnam (owner
);
221 throw new ArgumentException (Locale
.GetText ("invalid username"), "owner");
222 uint uid
= pw
.pw_uid
;
223 uint gid
= pw
.pw_gid
;
224 SetOwner (path
, uid
, gid
);
227 public static void SetOwner (string path
, string owner
, string group)
229 uint uid
= PosixUser
.GetUserId (owner
);
230 uint gid
= PosixGroup
.GetGroupId (group);
232 SetOwner (path
, uid
, gid
);
235 public static void SetLinkOwner (string path
, uint owner
, uint group)
237 int r
= Syscall
.lchown (path
, owner
, group);
238 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
241 public static void SetLinkOwner (string path
, string owner
)
243 Passwd pw
= Syscall
.getpwnam (owner
);
245 throw new ArgumentException (Locale
.GetText ("invalid username"), "owner");
246 uint uid
= pw
.pw_uid
;
247 uint gid
= pw
.pw_gid
;
248 SetLinkOwner (path
, uid
, gid
);
251 public static void SetLinkOwner (string path
, string owner
, string group)
253 uint uid
= PosixUser
.GetUserId (owner
);
254 uint gid
= PosixGroup
.GetGroupId (group);
256 SetLinkOwner (path
, uid
, gid
);
259 public static OpenFlags
ToOpenFlags (FileMode mode
, FileAccess access
)
263 case FileMode
.CreateNew
:
264 flags
= OpenFlags
.O_CREAT
| OpenFlags
.O_EXCL
;
266 case FileMode
.Create
:
267 flags
= OpenFlags
.O_CREAT
| OpenFlags
.O_TRUNC
;
272 case FileMode
.OpenOrCreate
:
273 flags
= OpenFlags
.O_CREAT
;
275 case FileMode
.Truncate
:
276 flags
= OpenFlags
.O_TRUNC
;
278 case FileMode
.Append
:
279 flags
= OpenFlags
.O_APPEND
;
282 throw new ArgumentException (Locale
.GetText ("Unsupported mode value"), "mode");
285 // Is O_LARGEFILE supported?
287 if (PosixConvert
.TryFromOpenFlags (OpenFlags
.O_LARGEFILE
, out _v
))
288 flags
|= OpenFlags
.O_LARGEFILE
;
291 case FileAccess
.Read
:
292 flags
|= OpenFlags
.O_RDONLY
;
294 case FileAccess
.Write
:
295 flags
|= OpenFlags
.O_WRONLY
;
297 case FileAccess
.ReadWrite
:
298 flags
|= OpenFlags
.O_RDWR
;
301 throw new ArgumentException (Locale
.GetText ("Unsupported access value"), "access");
307 public static void AdviseNormalAccess (int fd
, long offset
, long len
)
309 int r
= Syscall
.posix_fadvise (fd
, offset
, len
,
310 PosixFadviseAdvice
.POSIX_FADV_NORMAL
);
311 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
314 public static void AdviseNormalAccess (int fd
)
316 AdviseNormalAccess (fd
, 0, 0);
319 public static void AdviseNormalAccess (FileStream file
, long offset
, long len
)
321 AdviseNormalAccess (file
.Handle
.ToInt32(), offset
, len
);
324 public static void AdviseNormalAccess (FileStream file
)
326 AdviseNormalAccess (file
.Handle
.ToInt32());
329 public static void AdviseNormalAccess (PosixStream stream
, long offset
, long len
)
331 AdviseNormalAccess (stream
.FileDescriptor
, offset
, len
);
334 public static void AdviseNormalAccess (PosixStream stream
)
336 AdviseNormalAccess (stream
.FileDescriptor
);
339 public static void AdviseSequentialAccess (int fd
, long offset
, long len
)
341 int r
= Syscall
.posix_fadvise (fd
, offset
, len
,
342 PosixFadviseAdvice
.POSIX_FADV_SEQUENTIAL
);
343 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
346 public static void AdviseSequentialAccess (int fd
)
348 AdviseSequentialAccess (fd
, 0, 0);
351 public static void AdviseSequentialAccess (FileStream file
, long offset
, long len
)
353 AdviseSequentialAccess (file
.Handle
.ToInt32(), offset
, len
);
356 public static void AdviseSequentialAccess (FileStream file
)
358 AdviseSequentialAccess (file
.Handle
.ToInt32());
361 public static void AdviseSequentialAccess (PosixStream stream
, long offset
, long len
)
363 AdviseSequentialAccess (stream
.FileDescriptor
, offset
, len
);
366 public static void AdviseSequentialAccess (PosixStream stream
)
368 AdviseSequentialAccess (stream
.FileDescriptor
);
371 public static void AdviseRandomAccess (int fd
, long offset
, long len
)
373 int r
= Syscall
.posix_fadvise (fd
, offset
, len
,
374 PosixFadviseAdvice
.POSIX_FADV_RANDOM
);
375 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
378 public static void AdviseRandomAccess (int fd
)
380 AdviseRandomAccess (fd
, 0, 0);
383 public static void AdviseRandomAccess (FileStream file
, long offset
, long len
)
385 AdviseRandomAccess (file
.Handle
.ToInt32(), offset
, len
);
388 public static void AdviseRandomAccess (FileStream file
)
390 AdviseRandomAccess (file
.Handle
.ToInt32());
393 public static void AdviseRandomAccess (PosixStream stream
, long offset
, long len
)
395 AdviseRandomAccess (stream
.FileDescriptor
, offset
, len
);
398 public static void AdviseRandomAccess (PosixStream stream
)
400 AdviseRandomAccess (stream
.FileDescriptor
);
403 public static void AdviseNeedAccess (int fd
, long offset
, long len
)
405 int r
= Syscall
.posix_fadvise (fd
, offset
, len
,
406 PosixFadviseAdvice
.POSIX_FADV_WILLNEED
);
407 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
410 public static void AdviseNeedAccess (int fd
)
412 AdviseNeedAccess (fd
, 0, 0);
415 public static void AdviseNeedAccess (FileStream file
, long offset
, long len
)
417 AdviseNeedAccess (file
.Handle
.ToInt32(), offset
, len
);
420 public static void AdviseNeedAccess (FileStream file
)
422 AdviseNeedAccess (file
.Handle
.ToInt32());
425 public static void AdviseNeedAccess (PosixStream stream
, long offset
, long len
)
427 AdviseNeedAccess (stream
.FileDescriptor
, offset
, len
);
430 public static void AdviseNeedAccess (PosixStream stream
)
432 AdviseNeedAccess (stream
.FileDescriptor
);
435 public static void AdviseNoAccess (int fd
, long offset
, long len
)
437 int r
= Syscall
.posix_fadvise (fd
, offset
, len
,
438 PosixFadviseAdvice
.POSIX_FADV_DONTNEED
);
439 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
442 public static void AdviseNoAccess (int fd
)
444 AdviseNoAccess (fd
, 0, 0);
447 public static void AdviseNoAccess (FileStream file
, long offset
, long len
)
449 AdviseNoAccess (file
.Handle
.ToInt32(), offset
, len
);
452 public static void AdviseNoAccess (FileStream file
)
454 AdviseNoAccess (file
.Handle
.ToInt32());
457 public static void AdviseNoAccess (PosixStream stream
, long offset
, long len
)
459 AdviseNoAccess (stream
.FileDescriptor
, offset
, len
);
462 public static void AdviseNoAccess (PosixStream stream
)
464 AdviseNoAccess (stream
.FileDescriptor
);
467 public static void AdviseOnceAccess (int fd
, long offset
, long len
)
469 int r
= Syscall
.posix_fadvise (fd
, offset
, len
,
470 PosixFadviseAdvice
.POSIX_FADV_NOREUSE
);
471 PosixMarshal
.ThrowExceptionForLastErrorIf (r
);
474 public static void AdviseOnceAccess (int fd
)
476 AdviseOnceAccess (fd
, 0, 0);
479 public static void AdviseOnceAccess (FileStream file
, long offset
, long len
)
481 AdviseOnceAccess (file
.Handle
.ToInt32(), offset
, len
);
484 public static void AdviseOnceAccess (FileStream file
)
486 AdviseOnceAccess (file
.Handle
.ToInt32());
489 public static void AdviseOnceAccess (PosixStream stream
, long offset
, long len
)
491 AdviseOnceAccess (stream
.FileDescriptor
, offset
, len
);
494 public static void AdviseOnceAccess (PosixStream stream
)
496 AdviseOnceAccess (stream
.FileDescriptor
);