2 // Mono.Posix.Syscall.cs: System calls to Posix subsystem features
5 // Miguel de Icaza (miguel@novell.com)
7 // (C) 2003 Novell, Inc.
9 // This file implements the low-level syscall interface to the POSIX
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
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
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.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:
53 // The above copyright notice and this permission notice shall be
54 // included in all copies or substantial portions of the Software.
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.
67 using System.Runtime.InteropServices;
69 namespace Mono.Posix {
72 public enum OpenFlags {
81 // Or-ed with zero or more of these
92 // These are non-Posix, think of a way of exposing
93 // this for Linux users.
97 // O_DIRECTORY = 1024,
100 // O_LARGEFILE = 8192
104 public enum FileMode {
120 public enum WaitOptions {
126 public enum AccessMode {
134 public enum Signals {
135 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS,
136 SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE,
137 SIGALRM, SIGTERM, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
138 SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
139 SIGPROF, SIGWINCH, SIGIO,
146 [Obsolete ("Syscall is unmaintained. Please use Mono.Unix.Syscall.")]
147 public class Syscall {
148 [DllImport ("libc", SetLastError=true)]
149 public static extern int exit (int status);
151 [DllImport ("libc", SetLastError=true)]
152 public static extern int fork ();
154 [DllImport ("libc", SetLastError=true)]
155 public unsafe static extern IntPtr read (int fileDescriptor, void *buf, IntPtr count);
157 [DllImport ("libc", SetLastError=true)]
158 public unsafe static extern IntPtr write (int fileDescriptor, void *buf, IntPtr count);
160 [DllImport ("libc", EntryPoint="open", SetLastError=true)]
161 internal static extern int syscall_open (string pathname, int flags, int mode);
163 [DllImport ("MonoPosixHelper")]
164 internal extern static int map_Mono_Posix_OpenFlags (OpenFlags flags);
165 [DllImport ("MonoPosixHelper")]
166 internal extern static int map_Mono_Posix_FileMode (FileMode mode);
168 public static int open (string pathname, OpenFlags flags)
170 if ((flags & OpenFlags.O_CREAT) != 0)
171 throw new ArgumentException ("If you pass O_CREAT, you must call the method with the mode flag");
173 int posix_flags = map_Mono_Posix_OpenFlags (flags);
174 return syscall_open (pathname, posix_flags, 0);
177 public static int open (string pathname, OpenFlags flags, FileMode mode)
179 int posix_flags = map_Mono_Posix_OpenFlags (flags);
180 int posix_mode = map_Mono_Posix_FileMode (mode);
182 return syscall_open (pathname, posix_flags, posix_mode);
186 [DllImport ("libc", SetLastError=true)]
187 public static extern int close (int fileDescriptor);
189 [DllImport ("libc", EntryPoint="waitpid", SetLastError=true)]
190 unsafe internal static extern int syscall_waitpid (int pid, int * status, int options);
192 [DllImport ("MonoPosixHelper")]
193 internal extern static int map_Mono_Posix_WaitOptions (WaitOptions wait_options);
195 public static int waitpid (int pid, out int status, WaitOptions options)
199 int r = syscall_waitpid (pid, &s, map_Mono_Posix_WaitOptions (options));
205 public static int waitpid (int pid, WaitOptions options)
208 return syscall_waitpid (pid, null, map_Mono_Posix_WaitOptions (options));
212 [DllImport ("MonoPosixHelper", EntryPoint="wifexited")]
213 public static extern int WIFEXITED (int status);
214 [DllImport ("MonoPosixHelper", EntryPoint="wexitstatus")]
215 public static extern int WEXITSTATUS (int status);
216 [DllImport ("MonoPosixHelper", EntryPoint="wifsignaled")]
217 public static extern int WIFSIGNALED (int status);
218 [DllImport ("MonoPosixHelper", EntryPoint="wtermsig")]
219 public static extern int WTERMSIG (int status);
220 [DllImport ("MonoPosixHelper", EntryPoint="wifstopped")]
221 public static extern int WIFSTOPPED (int status);
222 [DllImport ("MonoPosixHelper", EntryPoint="wstopsig")]
223 public static extern int WSTOPSIG (int status);
225 [DllImport ("libc", EntryPoint="creat", SetLastError=true)]
226 internal static extern int syscall_creat (string pathname, int flags);
228 public static int creat (string pathname, FileMode flags)
230 return syscall_creat (pathname, map_Mono_Posix_FileMode (flags));
233 [DllImport ("libc", SetLastError=true)]
234 public static extern int link (string oldPath, string newPath);
236 [DllImport ("libc", SetLastError=true)]
237 public static extern int unlink (string path);
239 [DllImport ("libc", SetLastError=true)]
240 public static extern int symlink (string oldpath, string newpath);
244 [DllImport ("libc", SetLastError=true)]
245 public static extern int chdir (string path);
251 [DllImport ("libc", EntryPoint="chmod", SetLastError=true)]
252 internal static extern int syscall_chmod (string path, int mode);
254 public static int chmod (string path, FileMode mode)
256 return syscall_chmod (path, map_Mono_Posix_FileMode (mode));
259 [DllImport ("libc", SetLastError=true)]
260 public static extern int chown (string path, int owner, int group);
261 [DllImport ("libc", SetLastError=true)]
262 public static extern int lchown (string path, int owner, int group);
264 [DllImport ("libc", SetLastError=true)]
265 public static extern int lseek (int fileDescriptor, int offset, int whence);
267 [DllImport ("libc", SetLastError=true)]
268 public static extern int getpid ();
273 [DllImport ("libc", SetLastError=true)]
274 public static extern int setuid (int uid);
276 [DllImport ("libc", SetLastError=true)]
277 public static extern int getuid ();
283 public static extern uint alarm (uint seconds);
285 [DllImport ("libc", SetLastError=true)]
286 public static extern int pause ();
290 [DllImport ("libc", EntryPoint="access", SetLastError=true)]
291 internal extern static int syscall_access (string pathname, int mode);
293 [DllImport ("MonoPosixHelper")]
294 internal extern static int map_Mono_Posix_AccessMode (AccessMode mode);
296 public static int access (string pathname, AccessMode mode)
298 return syscall_access (pathname, map_Mono_Posix_AccessMode (mode));
301 [DllImport ("libc", SetLastError=true)]
302 public static extern int nice (int increment);
307 public static extern void sync ();
309 [DllImport ("libc", SetLastError=true)]
310 public static extern void kill (int pid, int sig);
312 [DllImport ("libc", SetLastError=true)]
313 public static extern int rename (string oldPath, string newPath);
315 [DllImport ("libc", EntryPoint="mkdir", SetLastError=true)]
316 internal extern static int syscall_mkdir (string pathname, int mode);
318 public static int mkdir (string pathname, FileMode mode)
320 return syscall_mkdir (pathname, map_Mono_Posix_FileMode (mode));
323 [DllImport ("libc", SetLastError=true)]
324 public static extern int rmdir (string path);
326 [DllImport ("libc", SetLastError=true)]
327 public static extern int dup (int fileDescriptor);
332 [DllImport ("libc", SetLastError=true)]
333 public static extern int setgid (int gid);
334 [DllImport ("libc", SetLastError=true)]
335 public static extern int getgid ();
338 public delegate void sighandler_t (int v);
340 [DllImport ("libc", SetLastError=true)]
341 public static extern int signal (int signum, sighandler_t handler);
343 [DllImport ("libc", SetLastError=true)]
344 public static extern int geteuid ();
346 [DllImport ("libc", SetLastError=true)]
347 public static extern int getegid ();
351 [DllImport ("libc", SetLastError=true)]
352 public static extern int setpgid (int pid, int pgid);
357 public static extern int umask (int umask);
359 [DllImport ("libc", SetLastError=true)]
360 public static extern int chroot (string path);
362 [DllImport ("libc", SetLastError=true)]
363 public static extern int dup2 (int oldFileDescriptor, int newFileDescriptor);
365 [DllImport ("libc", SetLastError=true)]
366 public static extern int getppid ();
368 [DllImport ("libc", SetLastError=true)]
369 public static extern int getpgrp ();
371 [DllImport ("libc", SetLastError=true)]
372 public static extern int setsid ();
376 [DllImport ("libc", SetLastError=true)]
377 public static extern int setreuid (int ruid, int euid);
379 [DllImport ("libc", SetLastError=true)]
380 public static extern int setregid (int rgid, int egid);
382 // these don't exactly match POSIX, but it's a nice way to get user/group names
384 [DllImport ("MonoPosixHelper", SetLastError=true)]
385 private static extern string helper_Mono_Posix_GetUserName (int uid);
387 [DllImport ("MonoPosixHelper", SetLastError=true)]
388 private static extern string helper_Mono_Posix_GetGroupName (int gid);
390 public static string getusername(int uid) { return helper_Mono_Posix_GetUserName(uid); }
391 public static string getgroupname(int gid) { return helper_Mono_Posix_GetGroupName(gid); }
398 // TODO: gettimeofday
399 // TODO: settimeofday
401 [DllImport ("libc", EntryPoint="gethostname", SetLastError=true)]
402 static extern int syscall_gethostname (byte[] p, int len);
404 public static string GetHostName ()
406 byte [] buf = new byte [256];
407 int res = syscall_gethostname (buf, buf.Length);
410 for (res = 0; res < buf.Length; ++res) {
415 return Encoding.UTF8.GetString (buf, 0, res);
418 public static string gethostname ()
420 return GetHostName ();
424 [DllImport ("libc", EntryPoint="isatty")]
425 static extern int syscall_isatty (int desc);
427 public static bool isatty (int desc)
429 int res = syscall_isatty (desc);
437 [DllImport ("MonoPosixHelper")]
438 internal extern static int helper_Mono_Posix_Stat (string filename, bool dereference,
439 out int device, out int inode, out int mode,
440 out int nlinks, out int uid, out int gid,
441 out int rdev, out long size, out long blksize, out long blocks,
442 out long atime, out long mtime, out long ctime);
444 private static int stat2(string filename, bool dereference, out Stat stat) {
445 int device, inode, mode;
446 int nlinks, uid, gid, rdev;
447 long size, blksize, blocks;
448 long atime, mtime, ctime;
450 int ret = helper_Mono_Posix_Stat(filename, dereference,
451 out device, out inode, out mode,
452 out nlinks, out uid, out gid,
453 out rdev, out size, out blksize, out blocks,
454 out atime, out mtime, out ctime);
459 rdev, size, blksize, blocks,
460 atime, mtime, ctime);
462 if (ret != 0) return ret;
467 public static int stat(string filename, out Stat stat) {
468 return stat2(filename, false, out stat);
471 public static int lstat(string filename, out Stat stat) {
472 return stat2(filename, true, out stat);
476 private static extern int readlink(string path, byte[] buffer, int buflen);
478 public static string readlink(string path) {
479 byte[] buf = new byte[512];
480 int ret = readlink(path, buf, buf.Length);
481 if (ret == -1) return null;
482 char[] cbuf = new char[512];
483 int chars = System.Text.Encoding.Default.GetChars(buf, 0, ret, cbuf, 0);
484 return new String(cbuf, 0, chars);
487 [DllImport ("libc", EntryPoint="strerror")]
488 static extern IntPtr _strerror(int errnum);
490 public static string strerror (int errnum)
492 return Marshal.PtrToStringAnsi (_strerror (errnum));
496 public static extern IntPtr opendir(string path);
499 public static extern int closedir(IntPtr dir);
501 [DllImport ("MonoPosixHelper", EntryPoint="helper_Mono_Posix_readdir")]
502 public static extern string readdir(IntPtr dir);
506 public enum StatModeMasks {
507 TypeMask = 0xF000, // bitmask for the file type bitfields
508 OwnerMask = 0x1C0, // mask for file owner permissions
509 GroupMask = 0x38, // mask for group permissions
510 OthersMask = 0x7, // mask for permissions for others (not in group)
514 public enum StatMode {
515 Socket = 0xC000, // socket
516 SymLink = 0xA000, // symbolic link
517 Regular = 0x8000, // regular file
518 BlockDevice = 0x6000, // block device
519 Directory = 0x4000, // directory
520 CharDevice = 0x2000, // character device
521 FIFO = 0x1000, // fifo
522 SUid = 0x800, // set UID bit
523 SGid = 0x400, // set GID bit
524 Sticky = 0x200, // sticky bit
525 OwnerRead = 0x100, // owner has read permission
526 OwnerWrite = 0x80, // owner has write permission
527 OwnerExecute = 0x40, // owner has execute permission
528 GroupRead = 0x20, // group has read permission
529 GroupWrite = 0x10, // group has write permission
530 GroupExecute = 0x8, // group has execute permission
531 OthersRead = 0x4, // others have read permission
532 OthersWrite = 0x2, // others have write permisson
533 OthersExecute = 0x1, // others have execute permission
537 public readonly int Device;
538 public readonly int INode;
539 public readonly StatMode Mode;
540 public readonly int NLinks;
541 public readonly int Uid;
542 public readonly int Gid;
543 public readonly long DeviceType;
544 public readonly long Size;
545 public readonly long BlockSize;
546 public readonly long Blocks;
547 public readonly DateTime ATime;
548 public readonly DateTime MTime;
549 public readonly DateTime CTime;
551 public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1).ToLocalTime();
553 public static DateTime UnixToDateTime(long unix) {
554 return UnixEpoch.Add(TimeSpan.FromSeconds(unix));
558 int device, int inode, int mode,
559 int nlinks, int uid, int gid,
560 int rdev, long size, long blksize, long blocks,
561 long atime, long mtime, long ctime) {
564 Mode = (StatMode)mode;
573 ATime = UnixToDateTime(atime);
575 ATime = new DateTime();
577 MTime = UnixToDateTime(mtime);
579 MTime = new DateTime();
581 CTime = UnixToDateTime(ctime);
583 CTime = new DateTime();