New test.
[mono.git] / mcs / class / Mono.Posix / Mono.Posix / Syscall.cs
1 //
2 // Mono.Posix.Syscall.cs: System calls to Posix subsystem features
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@novell.com)
6 //
7 // (C) 2003 Novell, Inc.
8 //
9 // This file implements the low-level syscall interface to the POSIX
10 // subsystem.
11 //
12 // This file tries to stay close to the low-level API as much as possible
13 // using enumerations, structures and in a few cases, using existing .NET
14 // data types.
15 //
16 // Implementation notes:
17 //
18 //    Since the values for the various constants on the API changes
19 //    from system to system (even Linux on different architectures will
20 //    have different values), we define our own set of values, and we
21 //    use a set of C helper routines to map from the constants we define
22 //    to the values of the native OS.
23 //
24 //    Bitfields were flagged with the [Map] attribute, and a helper program
25 //    generates a set of map_XXXX routines that we can call to convert
26 //    from our value definitions to the value definitions expected by the
27 //    OS.
28 //
29 //    Methods that require tuning are bound as `internal syscal_NAME' methods
30 //    and then a `NAME' method is exposed.
31 //
32 // Deprecated Warning:
33 //
34 //    This class is deprecated, and exists only for backward compatibility.
35 //    Please use and maintain Mono.Unix.Native.Syscall.
36 //
37 //    The [Map] attributes have been removed.  The naming and methodology of
38 //    the mapping routines has changed.  The old map functions still exist in
39 //    MonoPosixHelper, but they will not be updated any further.
40 //    Consequently, there is little point in maintaining the [Map] attributes
41 //    in this file, as they would only bloat MonoPosixHelper.
42 //
43
44 //
45 // Permission is hereby granted, free of charge, to any person obtaining
46 // a copy of this software and associated documentation files (the
47 // "Software"), to deal in the Software without restriction, including
48 // without limitation the rights to use, copy, modify, merge, publish,
49 // distribute, sublicense, and/or sell copies of the Software, and to
50 // permit persons to whom the Software is furnished to do so, subject to
51 // the following conditions:
52 // 
53 // The above copyright notice and this permission notice shall be
54 // included in all copies or substantial portions of the Software.
55 // 
56 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
57 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
58 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
59 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
60 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
61 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
62 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
63 //
64
65 using System;
66 using System.Text;
67 using System.Runtime.InteropServices;
68
69 namespace Mono.Posix {
70
71         [Flags]
72         [CLSCompliant (false)]
73         [Obsolete ("Use Mono.Unix.Native.OpenFlags")]
74         public enum OpenFlags {
75                 //
76                 // One of these
77                 //
78                 O_RDONLY    = 0,
79                 O_WRONLY    = 1,
80                 O_RDWR      = 2,
81
82                 //
83                 // Or-ed with zero or more of these
84                 //
85                 O_CREAT     = 4,
86                 O_EXCL      = 8,
87                 O_NOCTTY    = 16,
88                 O_TRUNC     = 32,
89                 O_APPEND    = 64,
90                 O_NONBLOCK  = 128,
91                 O_SYNC      = 256,
92
93                 //
94                 // These are non-Posix, think of a way of exposing
95                 // this for Linux users.
96                 //
97                 
98                 // O_NOFOLLOW  = 512,
99                 // O_DIRECTORY = 1024,
100                 // O_DIRECT    = 2048,
101                 // O_ASYNC     = 4096,
102                 // O_LARGEFILE = 8192
103         }
104         
105         [Flags]
106         [CLSCompliant (false)]
107         [Obsolete ("Use Mono.Unix.Native.FilePermissions")]
108         public enum FileMode {
109                 S_ISUID   = 2048,
110                 S_ISGID   = 1024,
111                 S_ISVTX   = 512,
112                 S_IRUSR   = 256,
113                 S_IWUSR   = 128,
114                 S_IXUSR   = 64,
115                 S_IRGRP   = 32,
116                 S_IWGRP   = 16,
117                 S_IXGRP   = 8,
118                 S_IROTH   = 4,
119                 S_IWOTH   = 2,
120                 S_IXOTH   = 1
121         }
122
123         [Flags]
124         [CLSCompliant (false)]
125         [Obsolete ("Use Mono.Unix.Native.WaitOptions")]
126         public enum WaitOptions {
127                 WNOHANG,
128                 WUNTRACED
129         }
130
131         [Flags]
132         [CLSCompliant (false)]
133         [Obsolete ("Use Mono.Unix.Native.AccessModes")]
134         public enum AccessMode {
135                 R_OK = 1,
136                 W_OK = 2,
137                 X_OK = 4,
138                 F_OK = 8
139         }
140
141         
142         [CLSCompliant (false)]
143         [Obsolete ("Use Mono.Unix.Native.Signum")]
144         public enum Signals {
145                 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS,
146                 SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE,
147                 SIGALRM, SIGTERM, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
148                 SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
149                 SIGPROF, SIGWINCH, SIGIO,
150                 
151                 // SIGPWR,
152                 SIGSYS,
153                 // SIGRTMIN
154         }
155         
156         [CLSCompliant (false)]
157         [Obsolete ("Use Mono.Unix.Native.Syscall.")]
158         public class Syscall {
159                 [DllImport ("libc", SetLastError=true)]
160                 public static extern int exit (int status);
161
162                 [DllImport ("libc", SetLastError=true)]
163                 public static extern int fork ();
164
165                 [DllImport ("libc", SetLastError=true)]
166                 public unsafe static extern IntPtr read (int fileDescriptor, void *buf, IntPtr count);
167
168                 [DllImport ("libc", SetLastError=true)]
169                 public unsafe static extern IntPtr write (int fileDescriptor, void *buf, IntPtr count);
170
171                 [DllImport ("libc", EntryPoint="open", SetLastError=true)]
172                 internal static extern int syscall_open (string pathname, int flags, int mode);
173
174                 [DllImport ("MonoPosixHelper")]
175                 internal extern static int map_Mono_Posix_OpenFlags (OpenFlags flags);
176                 [DllImport ("MonoPosixHelper")]
177                 internal extern static int map_Mono_Posix_FileMode (FileMode mode);
178                 
179                 public static int open (string pathname, OpenFlags flags)
180                 {
181                         if ((flags & OpenFlags.O_CREAT) != 0)
182                                 throw new ArgumentException ("If you pass O_CREAT, you must call the method with the mode flag");
183                         
184                         int posix_flags = map_Mono_Posix_OpenFlags (flags);
185                         return syscall_open (pathname, posix_flags, 0);
186                 }
187
188                 public static int open (string pathname, OpenFlags flags, FileMode mode)
189                 {
190                         int posix_flags = map_Mono_Posix_OpenFlags (flags);
191                         int posix_mode = map_Mono_Posix_FileMode (mode);
192
193                         return syscall_open (pathname, posix_flags, posix_mode);
194                 }
195                 
196
197                 [DllImport ("libc", SetLastError=true)]
198                 public static extern int close (int fileDescriptor);
199
200                 [DllImport ("libc", EntryPoint="waitpid", SetLastError=true)]
201                 unsafe internal static extern int syscall_waitpid (int pid, int * status, int options);
202
203                 [DllImport ("MonoPosixHelper")]
204                 internal extern static int map_Mono_Posix_WaitOptions (WaitOptions wait_options);
205                 
206                 public static int waitpid (int pid, out int status, WaitOptions options)
207                 {
208                         unsafe {
209                                 int s = 0;
210                                 int r = syscall_waitpid (pid, &s, map_Mono_Posix_WaitOptions (options));
211                                 status = s;
212                                 return r;
213                         }
214                 }
215                 
216                 public static int waitpid (int pid, WaitOptions options)
217                 {
218                         unsafe {
219                                 return syscall_waitpid (pid, null, map_Mono_Posix_WaitOptions (options));
220                         }
221                 }
222
223                 [DllImport ("MonoPosixHelper", EntryPoint="wifexited")]
224                 public static extern int WIFEXITED (int status);
225                 [DllImport ("MonoPosixHelper", EntryPoint="wexitstatus")]
226                 public static extern int WEXITSTATUS (int status);
227                 [DllImport ("MonoPosixHelper", EntryPoint="wifsignaled")]
228                 public static extern int WIFSIGNALED (int status);
229                 [DllImport ("MonoPosixHelper", EntryPoint="wtermsig")]
230                 public static extern int WTERMSIG (int status);
231                 [DllImport ("MonoPosixHelper", EntryPoint="wifstopped")]
232                 public static extern int WIFSTOPPED (int status);
233                 [DllImport ("MonoPosixHelper", EntryPoint="wstopsig")]
234                 public static extern int WSTOPSIG (int status);
235
236                 [DllImport ("libc", EntryPoint="creat", SetLastError=true)]
237                 internal static extern int syscall_creat (string pathname, int flags);
238
239                 public static int creat (string pathname, FileMode flags)
240                 {
241                         return syscall_creat (pathname, map_Mono_Posix_FileMode (flags));
242                 }
243
244                 [DllImport ("libc", SetLastError=true)]
245                 public static extern int link (string oldPath, string newPath);
246
247                 [DllImport ("libc", SetLastError=true)]
248                 public static extern int unlink (string path);
249
250                 [DllImport ("libc", SetLastError=true)]
251                 public static extern int symlink (string oldpath, string newpath);
252                 
253                 // TODO: execve
254
255                 [DllImport ("libc", SetLastError=true)]
256                 public static extern int chdir (string path);
257
258                 // TODO: time
259                 // TODO: mknod
260
261                 
262                 [DllImport ("libc", EntryPoint="chmod", SetLastError=true)]
263                 internal static extern int syscall_chmod (string path, int mode);
264
265                 public static int chmod (string path, FileMode mode)
266                 {
267                         return syscall_chmod (path, map_Mono_Posix_FileMode (mode));
268                 }
269
270                 [DllImport ("libc", SetLastError=true)]
271                 public static extern int chown (string path, int owner, int group);
272                 [DllImport ("libc", SetLastError=true)]
273                 public static extern int lchown (string path, int owner, int group);
274                 
275                 [DllImport ("libc", SetLastError=true)]
276                 public static extern int lseek (int fileDescriptor, int offset, int whence);
277
278                 [DllImport ("libc", SetLastError=true)]
279                 public static extern int getpid ();
280                 
281                 // TODO: mount
282                 // TODO: umount
283
284                 [DllImport ("libc", SetLastError=true)]
285                 public static extern int setuid (int uid);
286                 
287                 [DllImport ("libc", SetLastError=true)]
288                 public static extern int getuid ();
289
290                 // TODO: stime
291                 // TODO: ptrace
292                 
293                 [DllImport ("libc")]
294                 public static extern uint alarm (uint seconds);
295
296                 [DllImport ("libc", SetLastError=true)]
297                 public static extern int pause ();
298
299                 // TODO: utime
300
301                 [DllImport ("libc", EntryPoint="access", SetLastError=true)]
302                 internal extern static int syscall_access (string pathname, int mode);
303
304                 [DllImport ("MonoPosixHelper")]
305                 internal extern static int map_Mono_Posix_AccessMode (AccessMode mode);
306
307                 public static int access (string pathname, AccessMode mode)
308                 {
309                         return syscall_access (pathname, map_Mono_Posix_AccessMode (mode));
310                 }
311
312                 [DllImport ("libc", SetLastError=true)]
313                 public static extern int nice (int increment);
314
315                 // TODO: ftime
316
317                 [DllImport ("libc")]
318                 public static extern void sync ();
319
320                 [DllImport ("libc", SetLastError=true)]
321                 public static extern void kill (int pid, int sig);
322
323                 [DllImport ("libc", SetLastError=true)]
324                 public static extern int rename (string oldPath, string newPath);
325                 
326                 [DllImport ("libc", EntryPoint="mkdir", SetLastError=true)]
327                 internal extern static int syscall_mkdir (string pathname, int mode);
328
329                 public static int mkdir (string pathname, FileMode mode)
330                 {
331                         return syscall_mkdir (pathname, map_Mono_Posix_FileMode (mode));
332                 }
333
334                 [DllImport ("libc", SetLastError=true)]
335                 public static extern int rmdir (string path);
336
337                 [DllImport ("libc", SetLastError=true)]
338                 public static extern int dup (int fileDescriptor);
339
340                 // TODO: pipe
341                 // TODO: times
342
343                 [DllImport ("libc", SetLastError=true)]
344                 public static extern int setgid (int gid);
345                 [DllImport ("libc", SetLastError=true)]
346                 public static extern int getgid ();
347
348                 
349                 public delegate void sighandler_t (int v);
350                 
351                 [DllImport ("libc", SetLastError=true)]
352                 public static extern int signal (int signum, sighandler_t handler);
353                 
354                 [DllImport ("libc", SetLastError=true)]
355                 public static extern int geteuid ();
356                 
357                 [DllImport ("libc", SetLastError=true)]
358                 public static extern int getegid ();
359
360                 // TODO: fcntl
361                 
362                 [DllImport ("libc", SetLastError=true)]
363                 public static extern int setpgid (int pid, int pgid);
364
365                 // TODO: ulimit
366
367                 [DllImport ("libc")]
368                 public static extern int umask (int umask);
369
370                 [DllImport ("libc", SetLastError=true)]
371                 public static extern int chroot (string path);
372
373                 [DllImport ("libc", SetLastError=true)]
374                 public static extern int dup2 (int oldFileDescriptor, int newFileDescriptor);
375
376                 [DllImport ("libc", SetLastError=true)]
377                 public static extern int getppid ();
378
379                 [DllImport ("libc", SetLastError=true)]
380                 public static extern int getpgrp ();
381
382                 [DllImport ("libc", SetLastError=true)]
383                 public static extern int setsid ();
384                 
385                 // TODO: sigaction
386                 
387                 [DllImport ("libc", SetLastError=true)]
388                 public static extern int setreuid (int ruid, int euid);
389
390                 [DllImport ("libc", SetLastError=true)]
391                 public static extern int setregid (int rgid, int egid);
392
393                 // these don't exactly match POSIX, but it's a nice way to get user/group names
394                 
395                 [DllImport ("MonoPosixHelper", SetLastError=true)]
396                 private static extern string helper_Mono_Posix_GetUserName (int uid);
397
398                 [DllImport ("MonoPosixHelper", SetLastError=true)]
399                 private static extern string helper_Mono_Posix_GetGroupName (int gid);
400                 
401                 public static string getusername(int uid) { return helper_Mono_Posix_GetUserName(uid); }
402                 public static string getgroupname(int gid) { return helper_Mono_Posix_GetGroupName(gid); }
403                 
404                 // TODO: sigsuspend
405                 // TODO: sigpending
406                 // TODO: setrlimit
407                 // TODO: getrlimit
408                 // TODO: getrusage
409                 // TODO: gettimeofday
410                 // TODO: settimeofday
411                 
412                 [DllImport ("libc", EntryPoint="gethostname", SetLastError=true)]
413                 static extern int syscall_gethostname (byte[] p, int len);
414
415                 public static string GetHostName ()
416                 {
417                         byte [] buf = new byte [256];
418                         int res = syscall_gethostname (buf, buf.Length);
419                         if (res == -1)
420                                 return "localhost";
421                         for (res = 0; res < buf.Length; ++res) {
422                                 if (buf [res] == 0)
423                                         break;
424                         }
425                                 
426                         return Encoding.UTF8.GetString (buf, 0, res);
427                 }
428
429                 [CLSCompliant (false)]
430                 public static string gethostname ()
431                 {
432                         return GetHostName ();
433                 }
434                 
435
436                 [DllImport ("libc", EntryPoint="isatty")]
437                 static extern int syscall_isatty (int desc);
438                 
439                 public static bool isatty (int desc)
440                 {
441                         int res = syscall_isatty (desc);
442                         if (res == 1)
443                                 return true;
444                         else
445                                 return false;
446                 }
447                 
448
449                 [DllImport ("MonoPosixHelper")]
450                 internal extern static int helper_Mono_Posix_Stat (string filename, bool dereference,
451                         out int device, out int inode, out int mode,
452                         out int nlinks, out int uid, out int gid,
453                         out int rdev, out long size, out long blksize, out long blocks,
454                         out long atime, out long mtime, out long ctime);
455                 
456                 private static int stat2(string filename, bool dereference, out Stat stat) {
457                         int device, inode, mode;
458                         int nlinks, uid, gid, rdev;
459                         long size, blksize, blocks;
460                         long atime, mtime, ctime;
461
462                         int ret = helper_Mono_Posix_Stat(filename, dereference,
463                                 out device, out inode, out mode,
464                                 out nlinks, out uid, out gid,
465                                 out rdev, out size, out blksize, out blocks,
466                                 out atime, out mtime, out ctime);
467                                 
468                         stat = new Stat(
469                                 device, inode, mode,
470                                 nlinks, uid, gid,
471                                 rdev, size, blksize, blocks,
472                                 atime, mtime, ctime);
473
474                         if (ret != 0) return ret;
475
476                         return 0;
477                 }
478
479                 public static int stat(string filename, out Stat stat) {
480                         return stat2(filename, false, out stat);
481                 }
482
483                 public static int lstat(string filename, out Stat stat) {
484                         return stat2(filename, true, out stat);
485                 }
486                 
487                 [DllImport ("libc")]
488                 private static extern int readlink(string path, byte[] buffer, int buflen);
489
490                 public static string readlink(string path) {
491                         byte[] buf = new byte[512];
492                         int ret = readlink(path, buf, buf.Length);
493                         if (ret == -1) return null;
494                         char[] cbuf = new char[512];
495                         int chars = System.Text.Encoding.Default.GetChars(buf, 0, ret, cbuf, 0);
496                         return new String(cbuf, 0, chars);
497                 }
498
499                 [DllImport ("libc", EntryPoint="strerror")]
500                 static extern IntPtr _strerror(int errnum);
501
502                 public static string strerror (int errnum)
503                 {
504                         return Marshal.PtrToStringAnsi (_strerror (errnum));
505                 }
506
507                 [DllImport ("libc")]
508                 public static extern IntPtr opendir(string path);
509
510                 [DllImport ("libc")]
511                 public static extern int closedir(IntPtr dir);
512                 
513                 [DllImport ("MonoPosixHelper", EntryPoint="helper_Mono_Posix_readdir")]
514                 public static extern string readdir(IntPtr dir);
515                 
516         }
517         
518         [Obsolete ("Use Mono.Unix.Native.FilePermissions")]
519         public enum StatModeMasks {
520                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFMT")]
521                 TypeMask = 0xF000, // bitmask for the file type bitfields
522                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_RWXU")]
523                 OwnerMask = 0x1C0, // mask for file owner permissions
524                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_RWXG")]
525                 GroupMask = 0x38, // mask for group permissions
526                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_RWXO")]
527                 OthersMask = 0x7, // mask for permissions for others (not in group)
528         }
529         
530         [Flags]
531         [Obsolete ("Use Mono.Unix.Native.FilePermissions")]
532         public enum StatMode {
533                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFSOCK")]
534                 Socket = 0xC000, // socket
535                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFLNK")]
536                 SymLink = 0xA000, // symbolic link
537                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFREG")]
538                 Regular = 0x8000, // regular file
539                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFBLK")]
540                 BlockDevice = 0x6000, // block device
541                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFDIR")]
542                 Directory = 0x4000, // directory
543                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFCHR")]
544                 CharDevice = 0x2000, // character device
545                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IFIFO")]
546                 FIFO = 0x1000, // fifo
547                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_ISUID")]
548                 SUid = 0x800, // set UID bit
549                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_ISGID")]
550                 SGid = 0x400, // set GID bit
551                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_ISVTX")]
552                 Sticky = 0x200, // sticky bit
553                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IRUSR")]
554                 OwnerRead = 0x100, // owner has read permission
555                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IWUSR")]
556                 OwnerWrite = 0x80, // owner has write permission
557                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IXUSR")]
558                 OwnerExecute = 0x40, // owner has execute permission
559                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IRGRP")]
560                 GroupRead = 0x20, // group has read permission
561                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IWGRP")]
562                 GroupWrite = 0x10, // group has write permission
563                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IXGRP")]
564                 GroupExecute = 0x8, // group has execute permission
565                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IROTH")]
566                 OthersRead = 0x4, // others have read permission
567                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IWOTH")]
568                 OthersWrite = 0x2, // others have write permisson
569                 [Obsolete ("Use Mono.Unix.Native.FilePermissions.S_IXOTH")]
570                 OthersExecute = 0x1, // others have execute permission  
571         }
572         
573         [Obsolete ("Use Mono.Unix.Native.Stat")]
574         public struct Stat {
575                 [Obsolete ("Use Mono.Unix.Native.Stat.st_dev")]
576                 public readonly int Device;
577                 [Obsolete ("Use Mono.Unix.Native.Stat.st_ino")]
578                 public readonly int INode;
579                 [Obsolete ("Use Mono.Unix.Native.Stat.st_mode")]
580                 public readonly StatMode Mode;
581                 [Obsolete ("Use Mono.Unix.Native.Stat.st_nlink")]
582                 public readonly int NLinks;
583                 [Obsolete ("Use Mono.Unix.Native.Stat.st_uid")]
584                 public readonly int Uid;
585                 [Obsolete ("Use Mono.Unix.Native.Stat.st_gid")]
586                 public readonly int Gid;
587                 [Obsolete ("Use Mono.Unix.Native.Stat.st_rdev")]
588                 public readonly long DeviceType;
589                 [Obsolete ("Use Mono.Unix.Native.Stat.st_size")]
590                 public readonly long Size;
591                 [Obsolete ("Use Mono.Unix.Native.Stat.st_blksize")]
592                 public readonly long BlockSize;
593                 [Obsolete ("Use Mono.Unix.Native.Stat.st_blocks")]
594                 public readonly long Blocks;
595                 [Obsolete ("Use Mono.Unix.Native.Stat.st_atime")]
596                 public readonly DateTime ATime;
597                 [Obsolete ("Use Mono.Unix.Native.Stat.st_mtime")]
598                 public readonly DateTime MTime;
599                 [Obsolete ("Use Mono.Unix.Native.Stat.st_ctime")]
600                 public readonly DateTime CTime;
601                 
602                 [Obsolete ("Use Mono.Unix.Native.NativeConvert.LocalUnixEpoch")]
603                 public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
604                 
605                 [Obsolete ("Use Mono.Unix.Native.NativeConvert.ToDateTime")]
606                 public static DateTime UnixToDateTime(long unix) {
607                         return UnixEpoch.Add(TimeSpan.FromSeconds(unix)).ToLocalTime();
608                 }
609
610                 internal Stat(
611                         int device, int inode, int mode,
612                         int nlinks, int uid, int gid,
613                         int rdev, long size, long blksize, long blocks,
614                         long atime, long mtime, long ctime) {
615                         Device = device;
616                         INode = inode;
617                         Mode = (StatMode)mode;
618                         NLinks = nlinks;
619                         Uid = uid;
620                         Gid = gid;
621                         DeviceType = rdev;
622                         Size = size;
623                         BlockSize = blksize;
624                         Blocks = blocks;
625                         if (atime != 0)
626                                 ATime = UnixToDateTime(atime);
627                         else
628                                 ATime = new DateTime();
629                         if (mtime != 0)
630                                 MTime = UnixToDateTime(mtime);
631                         else
632                                 MTime = new DateTime();
633                         if (ctime != 0)
634                                 CTime = UnixToDateTime(ctime);
635                         else
636                                 CTime = new DateTime();
637                 }
638         }
639         
640
641 }