2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Mono.Posix / Mono.Posix / Syscall.cs
blob33bc8d832b73be57c531e60f8fd4f22f5d82bddf
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.
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.
16 // Implementation notes:
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.
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.
29 // Methods that require tuning are bound as `internal syscal_NAME' methods
30 // and then a `NAME' method is exposed.
32 // Deprecated Warning:
34 // This class is deprecated, and exists only for backward compatibility.
35 // Please use and maintain Mono.Unix.Native.Syscall.
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.
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.
65 using System;
66 using System.Text;
67 using System.Runtime.InteropServices;
69 namespace Mono.Posix {
71 [Flags]
72 [CLSCompliant (false)]
73 [Obsolete ("Use Mono.Unix.Native.OpenFlags")]
74 public enum OpenFlags {
76 // One of these
78 O_RDONLY = 0,
79 O_WRONLY = 1,
80 O_RDWR = 2,
83 // Or-ed with zero or more of these
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,
94 // These are non-Posix, think of a way of exposing
95 // this for Linux users.
98 // O_NOFOLLOW = 512,
99 // O_DIRECTORY = 1024,
100 // O_DIRECT = 2048,
101 // O_ASYNC = 4096,
102 // O_LARGEFILE = 8192
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
123 [Flags]
124 [CLSCompliant (false)]
125 [Obsolete ("Use Mono.Unix.Native.WaitOptions")]
126 public enum WaitOptions {
127 WNOHANG,
128 WUNTRACED
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
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,
151 // SIGPWR,
152 SIGSYS,
153 // SIGRTMIN
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);
162 [DllImport ("libc", SetLastError=true)]
163 public static extern int fork ();
165 [DllImport ("libc", SetLastError=true)]
166 public unsafe static extern IntPtr read (int fileDescriptor, void *buf, IntPtr count);
168 [DllImport ("libc", SetLastError=true)]
169 public unsafe static extern IntPtr write (int fileDescriptor, void *buf, IntPtr count);
171 [DllImport ("libc", EntryPoint="open", SetLastError=true)]
172 internal static extern int syscall_open (string pathname, int flags, int mode);
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);
179 public static int open (string pathname, OpenFlags flags)
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");
184 int posix_flags = map_Mono_Posix_OpenFlags (flags);
185 return syscall_open (pathname, posix_flags, 0);
188 public static int open (string pathname, OpenFlags flags, FileMode mode)
190 int posix_flags = map_Mono_Posix_OpenFlags (flags);
191 int posix_mode = map_Mono_Posix_FileMode (mode);
193 return syscall_open (pathname, posix_flags, posix_mode);
197 [DllImport ("libc", SetLastError=true)]
198 public static extern int close (int fileDescriptor);
200 [DllImport ("libc", EntryPoint="waitpid", SetLastError=true)]
201 unsafe internal static extern int syscall_waitpid (int pid, int * status, int options);
203 [DllImport ("MonoPosixHelper")]
204 internal extern static int map_Mono_Posix_WaitOptions (WaitOptions wait_options);
206 public static int waitpid (int pid, out int status, WaitOptions options)
208 unsafe {
209 int s = 0;
210 int r = syscall_waitpid (pid, &s, map_Mono_Posix_WaitOptions (options));
211 status = s;
212 return r;
216 public static int waitpid (int pid, WaitOptions options)
218 unsafe {
219 return syscall_waitpid (pid, null, map_Mono_Posix_WaitOptions (options));
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);
236 [DllImport ("libc", EntryPoint="creat", SetLastError=true)]
237 internal static extern int syscall_creat (string pathname, int flags);
239 public static int creat (string pathname, FileMode flags)
241 return syscall_creat (pathname, map_Mono_Posix_FileMode (flags));
244 [DllImport ("libc", SetLastError=true)]
245 public static extern int link (string oldPath, string newPath);
247 [DllImport ("libc", SetLastError=true)]
248 public static extern int unlink (string path);
250 [DllImport ("libc", SetLastError=true)]
251 public static extern int symlink (string oldpath, string newpath);
253 // TODO: execve
255 [DllImport ("libc", SetLastError=true)]
256 public static extern int chdir (string path);
258 // TODO: time
259 // TODO: mknod
262 [DllImport ("libc", EntryPoint="chmod", SetLastError=true)]
263 internal static extern int syscall_chmod (string path, int mode);
265 public static int chmod (string path, FileMode mode)
267 return syscall_chmod (path, map_Mono_Posix_FileMode (mode));
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);
275 [DllImport ("libc", SetLastError=true)]
276 public static extern int lseek (int fileDescriptor, int offset, int whence);
278 [DllImport ("libc", SetLastError=true)]
279 public static extern int getpid ();
281 // TODO: mount
282 // TODO: umount
284 [DllImport ("libc", SetLastError=true)]
285 public static extern int setuid (int uid);
287 [DllImport ("libc", SetLastError=true)]
288 public static extern int getuid ();
290 // TODO: stime
291 // TODO: ptrace
293 [DllImport ("libc")]
294 public static extern uint alarm (uint seconds);
296 [DllImport ("libc", SetLastError=true)]
297 public static extern int pause ();
299 // TODO: utime
301 [DllImport ("libc", EntryPoint="access", SetLastError=true)]
302 internal extern static int syscall_access (string pathname, int mode);
304 [DllImport ("MonoPosixHelper")]
305 internal extern static int map_Mono_Posix_AccessMode (AccessMode mode);
307 public static int access (string pathname, AccessMode mode)
309 return syscall_access (pathname, map_Mono_Posix_AccessMode (mode));
312 [DllImport ("libc", SetLastError=true)]
313 public static extern int nice (int increment);
315 // TODO: ftime
317 [DllImport ("libc")]
318 public static extern void sync ();
320 [DllImport ("libc", SetLastError=true)]
321 public static extern void kill (int pid, int sig);
323 [DllImport ("libc", SetLastError=true)]
324 public static extern int rename (string oldPath, string newPath);
326 [DllImport ("libc", EntryPoint="mkdir", SetLastError=true)]
327 internal extern static int syscall_mkdir (string pathname, int mode);
329 public static int mkdir (string pathname, FileMode mode)
331 return syscall_mkdir (pathname, map_Mono_Posix_FileMode (mode));
334 [DllImport ("libc", SetLastError=true)]
335 public static extern int rmdir (string path);
337 [DllImport ("libc", SetLastError=true)]
338 public static extern int dup (int fileDescriptor);
340 // TODO: pipe
341 // TODO: times
343 [DllImport ("libc", SetLastError=true)]
344 public static extern int setgid (int gid);
345 [DllImport ("libc", SetLastError=true)]
346 public static extern int getgid ();
349 public delegate void sighandler_t (int v);
351 [DllImport ("libc", SetLastError=true)]
352 public static extern int signal (int signum, sighandler_t handler);
354 [DllImport ("libc", SetLastError=true)]
355 public static extern int geteuid ();
357 [DllImport ("libc", SetLastError=true)]
358 public static extern int getegid ();
360 // TODO: fcntl
362 [DllImport ("libc", SetLastError=true)]
363 public static extern int setpgid (int pid, int pgid);
365 // TODO: ulimit
367 [DllImport ("libc")]
368 public static extern int umask (int umask);
370 [DllImport ("libc", SetLastError=true)]
371 public static extern int chroot (string path);
373 [DllImport ("libc", SetLastError=true)]
374 public static extern int dup2 (int oldFileDescriptor, int newFileDescriptor);
376 [DllImport ("libc", SetLastError=true)]
377 public static extern int getppid ();
379 [DllImport ("libc", SetLastError=true)]
380 public static extern int getpgrp ();
382 [DllImport ("libc", SetLastError=true)]
383 public static extern int setsid ();
385 // TODO: sigaction
387 [DllImport ("libc", SetLastError=true)]
388 public static extern int setreuid (int ruid, int euid);
390 [DllImport ("libc", SetLastError=true)]
391 public static extern int setregid (int rgid, int egid);
393 // these don't exactly match POSIX, but it's a nice way to get user/group names
395 [DllImport ("MonoPosixHelper", SetLastError=true)]
396 private static extern string helper_Mono_Posix_GetUserName (int uid);
398 [DllImport ("MonoPosixHelper", SetLastError=true)]
399 private static extern string helper_Mono_Posix_GetGroupName (int gid);
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); }
404 // TODO: sigsuspend
405 // TODO: sigpending
406 // TODO: setrlimit
407 // TODO: getrlimit
408 // TODO: getrusage
409 // TODO: gettimeofday
410 // TODO: settimeofday
412 [DllImport ("libc", EntryPoint="gethostname", SetLastError=true)]
413 static extern int syscall_gethostname (byte[] p, int len);
415 public static string GetHostName ()
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;
426 return Encoding.UTF8.GetString (buf, 0, res);
429 [CLSCompliant (false)]
430 public static string gethostname ()
432 return GetHostName ();
436 [DllImport ("libc", EntryPoint="isatty")]
437 static extern int syscall_isatty (int desc);
439 public static bool isatty (int desc)
441 int res = syscall_isatty (desc);
442 if (res == 1)
443 return true;
444 else
445 return false;
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);
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;
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);
468 stat = new Stat(
469 device, inode, mode,
470 nlinks, uid, gid,
471 rdev, size, blksize, blocks,
472 atime, mtime, ctime);
474 if (ret != 0) return ret;
476 return 0;
479 public static int stat(string filename, out Stat stat) {
480 return stat2(filename, false, out stat);
483 public static int lstat(string filename, out Stat stat) {
484 return stat2(filename, true, out stat);
487 [DllImport ("libc")]
488 private static extern int readlink(string path, byte[] buffer, int buflen);
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);
499 [DllImport ("libc", EntryPoint="strerror")]
500 static extern IntPtr _strerror(int errnum);
502 public static string strerror (int errnum)
504 return Marshal.PtrToStringAnsi (_strerror (errnum));
507 [DllImport ("libc")]
508 public static extern IntPtr opendir(string path);
510 [DllImport ("libc")]
511 public static extern int closedir(IntPtr dir);
513 [DllImport ("MonoPosixHelper", EntryPoint="helper_Mono_Posix_readdir")]
514 public static extern string readdir(IntPtr dir);
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)
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
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;
602 [Obsolete ("Use Mono.Unix.Native.NativeConvert.LocalUnixEpoch")]
603 public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
605 [Obsolete ("Use Mono.Unix.Native.NativeConvert.ToDateTime")]
606 public static DateTime UnixToDateTime(long unix) {
607 return UnixEpoch.Add(TimeSpan.FromSeconds(unix)).ToLocalTime();
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();