* Stdlib.cs: Cache delegates passed to Stdlib.signal() so that they survive
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / UnixFile.cs
1 //
2 // Mono.Unix/UnixFile.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004 Jonathan Pryor
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
29 using System;
30 using System.IO;
31 using System.Text;
32 using Mono.Unix;
33
34 namespace Mono.Unix {
35
36         public struct UnixPipes
37         {
38                 public UnixPipes (UnixStream reading, UnixStream writing)
39                 {
40                         Reading = reading;
41                         Writing = writing;
42                 }
43
44                 public UnixStream Reading;
45                 public UnixStream Writing;
46         }
47
48         public sealed /* static */ class UnixFile
49         {
50                 private UnixFile () {}
51
52                 public static bool CanAccess (string path, AccessMode mode)
53                 {
54                         int r = Syscall.access (path, mode);
55                         return r == 0;
56                 }
57
58                 public static void Delete (string path)
59                 {
60                         int r = Syscall.unlink (path);
61                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
62                 }
63
64                 public static bool Exists (string path)
65                 {
66                         int r = Syscall.access (path, AccessMode.F_OK);
67                         if (r == 0)
68                                 return true;
69                         return false;
70                 }
71
72                 public static long GetConfigurationValue (string path, PathConf name)
73                 {
74                         Syscall.SetLastError ((Error) 0);
75                         long r = Syscall.pathconf (path, name);
76                         if (r == -1 && Syscall.GetLastError() != (Error) 0)
77                                 UnixMarshal.ThrowExceptionForLastError ();
78                         return r;
79                 }
80
81                 public static DateTime GetLastAccessTime (string path)
82                 {
83                         return new UnixFileInfo (path).LastAccessTime;
84                 }
85
86                 public static Stat GetFileStatus (string path)
87                 {
88                         Stat stat;
89                         int r = Syscall.stat (path, out stat);
90                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
91                         return stat;
92                 }
93
94                 public static DateTime GetLastWriteTime (string path)
95                 {
96                         return new UnixFileInfo(path).LastWriteTime;
97                 }
98
99                 public static DateTime GetLastStatusChangeTime (string path)
100                 {
101                         return new UnixFileInfo (path).LastStatusChangeTime;
102                 }
103
104                 public static FilePermissions GetPermissions (string path)
105                 {
106                         return new UnixFileInfo (path).Permissions;
107                 }
108
109                 public static string ReadLink (string path)
110                 {
111                         string r = TryReadLink (path);
112                         if (r == null)
113                                 UnixMarshal.ThrowExceptionForLastError ();
114                         return r;
115                 }
116
117                 public static string TryReadLink (string path)
118                 {
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);
123                         if (r == -1)
124                                 return null;
125                         return sb.ToString (0, r);
126                 }
127
128                 public static void SetPermissions (string path, FilePermissions perms)
129                 {
130                         int r = Syscall.chmod (path, perms);
131                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
132                 }
133
134                 public static UnixStream Create (string path)
135                 {
136                         FilePermissions mode = // 0644
137                                 FilePermissions.S_IRUSR | FilePermissions.S_IWUSR |
138                                 FilePermissions.S_IRGRP | FilePermissions.S_IROTH; 
139                         return Create (path, mode);
140                 }
141
142                 public static UnixStream Create (string path, FilePermissions mode)
143                 {
144                         int fd = Syscall.creat (path, mode);
145                         if (fd < 0)
146                                 UnixMarshal.ThrowExceptionForLastError ();
147                         return new UnixStream (fd);
148                 }
149
150                 public static UnixPipes CreatePipes ()
151                 {
152                         int reading, writing;
153                         int r = Syscall.pipe (out reading, out writing);
154                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
155                         return new UnixPipes (new UnixStream (reading), new UnixStream (writing));
156                 }
157
158                 public static UnixStream Open (string path, OpenFlags flags)
159                 {
160                         int fd = Syscall.open (path, flags);
161                         if (fd < 0)
162                                 UnixMarshal.ThrowExceptionForLastError ();
163                         return new UnixStream (fd);
164                 }
165
166                 public static UnixStream Open (string path, OpenFlags flags, FilePermissions mode)
167                 {
168                         int fd = Syscall.open (path, flags, mode);
169                         if (fd < 0)
170                                 UnixMarshal.ThrowExceptionForLastError ();
171                         return new UnixStream (fd);
172                 }
173
174                 public static UnixStream Open (string path, FileMode mode)
175                 {
176                         OpenFlags flags = UnixConvert.ToOpenFlags (mode, FileAccess.ReadWrite);
177                         int fd = Syscall.open (path, flags);
178                         if (fd < 0)
179                                 UnixMarshal.ThrowExceptionForLastError ();
180                         return new UnixStream (fd);
181                 }
182
183                 public static UnixStream Open (string path, FileMode mode, FileAccess access)
184                 {
185                         OpenFlags flags = UnixConvert.ToOpenFlags (mode, access);
186                         int fd = Syscall.open (path, flags);
187                         if (fd < 0)
188                                 UnixMarshal.ThrowExceptionForLastError ();
189                         return new UnixStream (fd);
190                 }
191
192                 public static UnixStream Open (string path, FileMode mode, FileAccess access, FilePermissions perms)
193                 {
194                         OpenFlags flags = UnixConvert.ToOpenFlags (mode, access);
195                         int fd = Syscall.open (path, flags, perms);
196                         if (fd < 0)
197                                 UnixMarshal.ThrowExceptionForLastError ();
198                         return new UnixStream (fd);
199                 }
200
201                 public static UnixStream OpenRead (string path)
202                 {
203                         return Open (path, FileMode.Open, FileAccess.Read);
204                 }
205
206                 public static UnixStream OpenWrite (string path)
207                 {
208                         return Open (path, FileMode.OpenOrCreate, FileAccess.Write);
209                 }
210
211                 public static void SetOwner (string path, uint owner, uint group)
212                 {
213                         int r = Syscall.chown (path, owner, group);
214                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
215                 }
216
217                 public static void SetOwner (string path, string owner)
218                 {
219                         Passwd pw = Syscall.getpwnam (owner);
220                         if (pw == null)
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);
225                 }
226
227                 public static void SetOwner (string path, string owner, string group)
228                 {
229                         uint uid = UnixUser.GetUserId (owner);
230                         uint gid = UnixGroup.GetGroupId (group);
231
232                         SetOwner (path, uid, gid);
233                 }
234
235                 public static void SetLinkOwner (string path, uint owner, uint group)
236                 {
237                         int r = Syscall.lchown (path, owner, group);
238                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
239                 }
240
241                 public static void SetLinkOwner (string path, string owner)
242                 {
243                         Passwd pw = Syscall.getpwnam (owner);
244                         if (pw == null)
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);
249                 }
250
251                 public static void SetLinkOwner (string path, string owner, string group)
252                 {
253                         uint uid = UnixUser.GetUserId (owner);
254                         uint gid = UnixGroup.GetGroupId (group);
255
256                         SetLinkOwner (path, uid, gid);
257                 }
258
259                 public static void AdviseNormalAccess (int fd, long offset, long len)
260                 {
261                         int r = Syscall.posix_fadvise (fd, offset, len,
262                                 PosixFadviseAdvice.POSIX_FADV_NORMAL);
263                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
264                 }
265
266                 public static void AdviseNormalAccess (int fd)
267                 {
268                         AdviseNormalAccess (fd, 0, 0);
269                 }
270
271                 public static void AdviseNormalAccess (FileStream file, long offset, long len)
272                 {
273                         AdviseNormalAccess (file.Handle.ToInt32(), offset, len);
274                 }
275
276                 public static void AdviseNormalAccess (FileStream file)
277                 {
278                         AdviseNormalAccess (file.Handle.ToInt32());
279                 }
280
281                 public static void AdviseNormalAccess (UnixStream stream, long offset, long len)
282                 {
283                         AdviseNormalAccess (stream.Handle, offset, len);
284                 }
285
286                 public static void AdviseNormalAccess (UnixStream stream)
287                 {
288                         AdviseNormalAccess (stream.Handle);
289                 }
290
291                 public static void AdviseSequentialAccess (int fd, long offset, long len)
292                 {
293                         int r = Syscall.posix_fadvise (fd, offset, len,
294                                 PosixFadviseAdvice.POSIX_FADV_SEQUENTIAL);
295                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
296                 }
297
298                 public static void AdviseSequentialAccess (int fd)
299                 {
300                         AdviseSequentialAccess (fd, 0, 0);
301                 }
302
303                 public static void AdviseSequentialAccess (FileStream file, long offset, long len)
304                 {
305                         AdviseSequentialAccess (file.Handle.ToInt32(), offset, len);
306                 }
307
308                 public static void AdviseSequentialAccess (FileStream file)
309                 {
310                         AdviseSequentialAccess (file.Handle.ToInt32());
311                 }
312
313                 public static void AdviseSequentialAccess (UnixStream stream, long offset, long len)
314                 {
315                         AdviseSequentialAccess (stream.Handle, offset, len);
316                 }
317
318                 public static void AdviseSequentialAccess (UnixStream stream)
319                 {
320                         AdviseSequentialAccess (stream.Handle);
321                 }
322
323                 public static void AdviseRandomAccess (int fd, long offset, long len)
324                 {
325                         int r = Syscall.posix_fadvise (fd, offset, len,
326                                 PosixFadviseAdvice.POSIX_FADV_RANDOM);
327                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
328                 }
329
330                 public static void AdviseRandomAccess (int fd)
331                 {
332                         AdviseRandomAccess (fd, 0, 0);
333                 }
334
335                 public static void AdviseRandomAccess (FileStream file, long offset, long len)
336                 {
337                         AdviseRandomAccess (file.Handle.ToInt32(), offset, len);
338                 }
339
340                 public static void AdviseRandomAccess (FileStream file)
341                 {
342                         AdviseRandomAccess (file.Handle.ToInt32());
343                 }
344
345                 public static void AdviseRandomAccess (UnixStream stream, long offset, long len)
346                 {
347                         AdviseRandomAccess (stream.Handle, offset, len);
348                 }
349
350                 public static void AdviseRandomAccess (UnixStream stream)
351                 {
352                         AdviseRandomAccess (stream.Handle);
353                 }
354
355                 public static void AdviseNeedAccess (int fd, long offset, long len)
356                 {
357                         int r = Syscall.posix_fadvise (fd, offset, len,
358                                 PosixFadviseAdvice.POSIX_FADV_WILLNEED);
359                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
360                 }
361
362                 public static void AdviseNeedAccess (int fd)
363                 {
364                         AdviseNeedAccess (fd, 0, 0);
365                 }
366
367                 public static void AdviseNeedAccess (FileStream file, long offset, long len)
368                 {
369                         AdviseNeedAccess (file.Handle.ToInt32(), offset, len);
370                 }
371
372                 public static void AdviseNeedAccess (FileStream file)
373                 {
374                         AdviseNeedAccess (file.Handle.ToInt32());
375                 }
376
377                 public static void AdviseNeedAccess (UnixStream stream, long offset, long len)
378                 {
379                         AdviseNeedAccess (stream.Handle, offset, len);
380                 }
381
382                 public static void AdviseNeedAccess (UnixStream stream)
383                 {
384                         AdviseNeedAccess (stream.Handle);
385                 }
386
387                 public static void AdviseNoAccess (int fd, long offset, long len)
388                 {
389                         int r = Syscall.posix_fadvise (fd, offset, len,
390                                 PosixFadviseAdvice.POSIX_FADV_DONTNEED);
391                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
392                 }
393
394                 public static void AdviseNoAccess (int fd)
395                 {
396                         AdviseNoAccess (fd, 0, 0);
397                 }
398
399                 public static void AdviseNoAccess (FileStream file, long offset, long len)
400                 {
401                         AdviseNoAccess (file.Handle.ToInt32(), offset, len);
402                 }
403
404                 public static void AdviseNoAccess (FileStream file)
405                 {
406                         AdviseNoAccess (file.Handle.ToInt32());
407                 }
408
409                 public static void AdviseNoAccess (UnixStream stream, long offset, long len)
410                 {
411                         AdviseNoAccess (stream.Handle, offset, len);
412                 }
413
414                 public static void AdviseNoAccess (UnixStream stream)
415                 {
416                         AdviseNoAccess (stream.Handle);
417                 }
418
419                 public static void AdviseOnceAccess (int fd, long offset, long len)
420                 {
421                         int r = Syscall.posix_fadvise (fd, offset, len,
422                                 PosixFadviseAdvice.POSIX_FADV_NOREUSE);
423                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
424                 }
425
426                 public static void AdviseOnceAccess (int fd)
427                 {
428                         AdviseOnceAccess (fd, 0, 0);
429                 }
430
431                 public static void AdviseOnceAccess (FileStream file, long offset, long len)
432                 {
433                         AdviseOnceAccess (file.Handle.ToInt32(), offset, len);
434                 }
435
436                 public static void AdviseOnceAccess (FileStream file)
437                 {
438                         AdviseOnceAccess (file.Handle.ToInt32());
439                 }
440
441                 public static void AdviseOnceAccess (UnixStream stream, long offset, long len)
442                 {
443                         AdviseOnceAccess (stream.Handle, offset, len);
444                 }
445
446                 public static void AdviseOnceAccess (UnixStream stream)
447                 {
448                         AdviseOnceAccess (stream.Handle);
449                 }
450         }
451 }
452
453 // vim: noexpandtab