X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMono.Posix%2FMono.Unix.Native%2FSyscall.cs;h=a95c5ee670991e0508aefb0f7fda765e694d9e2f;hb=1afdb2bead4045a55774d96c7b10d35cc6fc7f83;hp=6d8dd0def0895c6bcd17885b125be1e35f639241;hpb=64f85a65b023522d3f34e9932e6a843e0ad8fc3b;p=mono.git diff --git a/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs b/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs index 6d8dd0def08..a95c5ee6709 100644 --- a/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs +++ b/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs @@ -6,7 +6,7 @@ // Jonathan Pryor (jonpryor@vt.edu) // // (C) 2003 Novell, Inc. -// (C) 2004-2005 Jonathan Pryor +// (C) 2004-2006 Jonathan Pryor // // This file implements the low-level syscall interface to the POSIX // subsystem. @@ -60,27 +60,6 @@ using System.Security; using System.Text; using Mono.Unix.Native; -[assembly:Mono.Unix.Native.HeaderAttribute ( - Includes= - "sys/types.h," + - "sys/stat.h," + - "ah:sys/poll.h," + - "ah:sys/wait.h," + - "ah:sys/statvfs.h," + - "ah:sys/xattr.h," + - "ah:sys/mman.h," + - "unistd.h," + - "fcntl.h," + - "signal.h," + - "ah:poll.h," + - "ah:grp.h," + - "errno.h," + - "ah:syslog.h", - Defines= - "_GNU_SOURCE," + - "_XOPEN_SOURCE" -)] - namespace Mono.Unix.Native { #region Enumerations @@ -199,12 +178,19 @@ namespace Mono.Unix.Native { // Device types // Why these are held in "mode_t" is beyond me... S_IFMT = 0xF000, // Bits which determine file type + [Map(SuppressFlags="S_IFMT")] S_IFDIR = 0x4000, // Directory + [Map(SuppressFlags="S_IFMT")] S_IFCHR = 0x2000, // Character device + [Map(SuppressFlags="S_IFMT")] S_IFBLK = 0x6000, // Block device + [Map(SuppressFlags="S_IFMT")] S_IFREG = 0x8000, // Regular file + [Map(SuppressFlags="S_IFMT")] S_IFIFO = 0x1000, // FIFO + [Map(SuppressFlags="S_IFMT")] S_IFLNK = 0xA000, // Symbolic link + [Map(SuppressFlags="S_IFMT")] S_IFSOCK = 0xC000, // Socket } @@ -660,13 +646,16 @@ namespace Mono.Unix.Native { ST_RDONLY = 1, // Mount read-only ST_NOSUID = 2, // Ignore suid and sgid bits ST_NODEV = 4, // Disallow access to device special files + ST_NOEXEC = 8, // Disallow program execution ST_SYNCHRONOUS = 16, // Writes are synced at once + ST_REMOUNT = 32, // Alter flags of a mounted FS ST_MANDLOCK = 64, // Allow mandatory locks on an FS ST_WRITE = 128, // Write on file/directory/symlink ST_APPEND = 256, // Append-only file ST_IMMUTABLE = 512, // Immutable file ST_NOATIME = 1024, // Do not update access times ST_NODIRATIME = 2048, // Do not update directory access times + ST_BIND = 4096, // Bind directory at different place } [Map][Flags] @@ -728,6 +717,7 @@ namespace Mono.Unix.Native { #region Structures + [Map ("struct flock")] public struct Flock #if NET_2_0 : IEquatable @@ -737,9 +727,9 @@ namespace Mono.Unix.Native { public LockType l_type; // Type of lock: F_RDLCK, F_WRLCK, F_UNLCK [CLSCompliant (false)] public SeekFlags l_whence; // How to interpret l_start - public /* off_t */ long l_start; // Starting offset for lock - public /* off_t */ long l_len; // Number of bytes to lock - public /* pid_t */ int l_pid; // PID of process blocking our lock (F_GETLK only) + [off_t] public long l_start; // Starting offset for lock + [off_t] public long l_len; // Number of bytes to lock + [pid_t] public int l_pid; // PID of process blocking our lock (F_GETLK only) public override int GetHashCode () { @@ -750,7 +740,7 @@ namespace Mono.Unix.Native { public override bool Equals (object obj) { - if (obj.GetType() != GetType()) + if ((obj == null) || (obj.GetType () != GetType ())) return false; Flock value = (Flock) obj; return l_type == value.l_type && l_whence == value.l_whence && @@ -776,6 +766,7 @@ namespace Mono.Unix.Native { } } + [Map ("struct pollfd")] public struct Pollfd #if NET_2_0 : IEquatable @@ -816,33 +807,36 @@ namespace Mono.Unix.Native { } } + [Map ("struct stat")] public struct Stat #if NET_2_0 : IEquatable #endif { [CLSCompliant (false)] - public /* dev_t */ ulong st_dev; // device - [CLSCompliant (false)] - public /* ino_t */ ulong st_ino; // inode + [dev_t] public ulong st_dev; // device [CLSCompliant (false)] - public FilePermissions st_mode; // protection + [ino_t] public ulong st_ino; // inode [CLSCompliant (false)] - private uint _padding_; // padding for structure alignment + public FilePermissions st_mode; // protection + [NonSerialized] +#pragma warning disable 169 + private uint _padding_; // padding for structure alignment +#pragma warning restore 169 [CLSCompliant (false)] - public /* nlink_t */ ulong st_nlink; // number of hard links + [nlink_t] public ulong st_nlink; // number of hard links [CLSCompliant (false)] - public /* uid_t */ uint st_uid; // user ID of owner + [uid_t] public uint st_uid; // user ID of owner [CLSCompliant (false)] - public /* gid_t */ uint st_gid; // group ID of owner + [gid_t] public uint st_gid; // group ID of owner [CLSCompliant (false)] - public /* dev_t */ ulong st_rdev; // device type (if inode device) - public /* off_t */ long st_size; // total size, in bytes - public /* blksize_t */ long st_blksize; // blocksize for filesystem I/O - public /* blkcnt_t */ long st_blocks; // number of blocks allocated - public /* time_t */ long st_atime; // time of last access - public /* time_t */ long st_mtime; // time of last modification - public /* time_t */ long st_ctime; // time of last status change + [dev_t] public ulong st_rdev; // device type (if inode device) + [off_t] public long st_size; // total size, in bytes + [blksize_t] public long st_blksize; // blocksize for filesystem I/O + [blkcnt_t] public long st_blocks; // number of blocks allocated + [time_t] public long st_atime; // time of last access + [time_t] public long st_mtime; // time of last modification + [time_t] public long st_ctime; // time of last status change public override int GetHashCode () { @@ -909,6 +903,8 @@ namespace Mono.Unix.Native { } } + // `struct statvfs' isn't portable, so don't generate To/From methods. + [Map] [CLSCompliant (false)] public struct Statvfs #if NET_2_0 @@ -917,12 +913,12 @@ namespace Mono.Unix.Native { { public ulong f_bsize; // file system block size public ulong f_frsize; // fragment size - public /* fsblkcnt_t */ ulong f_blocks; // size of fs in f_frsize units - public /* fsblkcnt_t */ ulong f_bfree; // # free blocks - public /* fsblkcnt_t */ ulong f_bavail; // # free blocks for non-root - public /* fsfilcnt_t */ ulong f_files; // # inodes - public /* fsfilcnt_t */ ulong f_ffree; // # free inodes - public /* fsfilcnt_t */ ulong f_favail; // # free inodes for non-root + [fsblkcnt_t] public ulong f_blocks; // size of fs in f_frsize units + [fsblkcnt_t] public ulong f_bfree; // # free blocks + [fsblkcnt_t] public ulong f_bavail; // # free blocks for non-root + [fsfilcnt_t] public ulong f_files; // # inodes + [fsfilcnt_t] public ulong f_ffree; // # free inodes + [fsfilcnt_t] public ulong f_favail; // # free inodes for non-root public ulong f_fsid; // file system id public MountFlags f_flag; // mount flags public ulong f_namemax; // maximum filename length @@ -986,13 +982,14 @@ namespace Mono.Unix.Native { } } + [Map ("struct timeval")] public struct Timeval #if NET_2_0 : IEquatable #endif { - public /* time_t */ long tv_sec; // seconds - public /* suseconds_t */ long tv_usec; // microseconds + [time_t] public long tv_sec; // seconds + [suseconds_t] public long tv_usec; // microseconds public override int GetHashCode () { @@ -1023,13 +1020,16 @@ namespace Mono.Unix.Native { } } + [Map ("struct timezone")] public struct Timezone #if NET_2_0 : IEquatable #endif { public int tz_minuteswest; // minutes W of Greenwich +#pragma warning disable 169 private int tz_dsttime; // type of dst correction (OBSOLETE) +#pragma warning restore 169 public override int GetHashCode () { @@ -1060,13 +1060,14 @@ namespace Mono.Unix.Native { } } + [Map ("struct utimbuf")] public struct Utimbuf #if NET_2_0 : IEquatable #endif { - public /* time_t */ long actime; // access time - public /* time_t */ long modtime; // modification time + [time_t] public long actime; // access time + [time_t] public long modtime; // modification time public override int GetHashCode () { @@ -1097,6 +1098,88 @@ namespace Mono.Unix.Native { } } + [Map ("struct timespec")] + public struct Timespec +#if NET_2_0 + : IEquatable +#endif + { + [time_t] public long tv_sec; // Seconds. + public long tv_nsec; // Nanoseconds. + + public override int GetHashCode () + { + return tv_sec.GetHashCode () ^ tv_nsec.GetHashCode (); + } + + public override bool Equals (object obj) + { + if (obj == null || obj.GetType () != GetType ()) + return false; + Timespec value = (Timespec) obj; + return value.tv_sec == tv_sec && value.tv_nsec == tv_nsec; + } + + public bool Equals (Timespec value) + { + return value.tv_sec == tv_sec && value.tv_nsec == tv_nsec; + } + + public static bool operator== (Timespec lhs, Timespec rhs) + { + return lhs.Equals (rhs); + } + + public static bool operator!= (Timespec lhs, Timespec rhs) + { + return !lhs.Equals (rhs); + } + } + + [Flags][Map] + public enum EpollFlags { + EPOLL_CLOEXEC = 02000000, + EPOLL_NONBLOCK = 04000, + } + + [Flags][Map] + [CLSCompliant (false)] + public enum EpollEvents : uint { + EPOLLIN = 0x001, + EPOLLPRI = 0x002, + EPOLLOUT = 0x004, + EPOLLRDNORM = 0x040, + EPOLLRDBAND = 0x080, + EPOLLWRNORM = 0x100, + EPOLLWRBAND = 0x200, + EPOLLMSG = 0x400, + EPOLLERR = 0x008, + EPOLLHUP = 0x010, + EPOLLRDHUP = 0x2000, + EPOLLONESHOT = 1 << 30, + EPOLLET = unchecked ((uint) (1 << 31)) + } + + public enum EpollOp { + EPOLL_CTL_ADD = 1, + EPOLL_CTL_DEL = 2, + EPOLL_CTL_MOD = 3, + } + + [StructLayout (LayoutKind.Explicit, Size=12, Pack=1)] + [CLSCompliant (false)] + public struct EpollEvent { + [FieldOffset (0)] + public EpollEvents events; + [FieldOffset (4)] + public int fd; + [FieldOffset (4)] + public IntPtr ptr; + [FieldOffset (4)] + public uint u32; + [FieldOffset (4)] + public ulong u64; + } #endregion #region Classes @@ -1349,6 +1432,58 @@ namespace Mono.Unix.Native { } } + public sealed class Utsname +#if NET_2_0 + : IEquatable +#endif + { + public string sysname; + public string nodename; + public string release; + public string version; + public string machine; + public string domainname; + + public override int GetHashCode () + { + return sysname.GetHashCode () ^ nodename.GetHashCode () ^ + release.GetHashCode () ^ version.GetHashCode () ^ + machine.GetHashCode () ^ domainname.GetHashCode (); + } + + public override bool Equals (object obj) + { + if (obj == null || GetType() != obj.GetType()) + return false; + Utsname u = (Utsname) obj; + return Equals (u); + } + + public bool Equals (Utsname value) + { + return value.sysname == sysname && value.nodename == nodename && + value.release == release && value.version == version && + value.machine == machine && value.domainname == domainname; + } + + // Generate string in /etc/passwd format + public override string ToString () + { + return string.Format ("{0} {1} {2} {3} {4}", + sysname, nodename, release, version, machine); + } + + public static bool operator== (Utsname lhs, Utsname rhs) + { + return Object.Equals (lhs, rhs); + } + + public static bool operator!= (Utsname lhs, Utsname rhs) + { + return !Object.Equals (lhs, rhs); + } + } + // // Convention: Functions *not* part of the standard C library AND part of // a POSIX and/or Unix standard (X/Open, SUS, XPG, etc.) go here. @@ -1803,8 +1938,8 @@ namespace Mono.Unix.Native { public static extern int rewinddir (IntPtr dir); private struct _Dirent { - public /* ino_t */ ulong d_ino; - public /* off_t */ long d_off; + [ino_t] public ulong d_ino; + [off_t] public long d_off; public ushort d_reclen; public byte d_type; public IntPtr d_name; @@ -1938,6 +2073,7 @@ namespace Mono.Unix.Native { // // -- COMPLETE // + [Map] private struct _Fstab { public IntPtr fs_spec; public IntPtr fs_file; @@ -2067,11 +2203,12 @@ namespace Mono.Unix.Native { return setgroups ((ulong) list.Length, list); } + [Map] private struct _Group { public IntPtr gr_name; public IntPtr gr_passwd; - public /* gid_t */ uint gr_gid; + [gid_t] public uint gr_gid; public int _gr_nmem_; public IntPtr gr_mem; public IntPtr _gr_buf_; @@ -2239,12 +2376,13 @@ namespace Mono.Unix.Native { // // SKIPPING: getpw(3): it's dangerous. Use getpwuid(3) instead. + [Map] private struct _Passwd { public IntPtr pw_name; public IntPtr pw_passwd; - public /* uid_t */ uint pw_uid; - public /* gid_t */ uint pw_gid; + [uid_t] public uint pw_uid; + [gid_t] public uint pw_gid; public IntPtr pw_gecos; public IntPtr pw_dir; public IntPtr pw_shell; @@ -2529,6 +2667,48 @@ namespace Mono.Unix.Native { #endregion + #region Declarations + + public static int epoll_create (int size) + { + return sys_epoll_create (size); + } + + public static int epoll_create (EpollFlags flags) + { + return sys_epoll_create1 (flags); + } + + public static int epoll_ctl (int epfd, EpollOp op, int fd, EpollEvents events) + { + EpollEvent ee = new EpollEvent (); + ee.events = events; + ee.fd = fd; + + return sys_epoll_ctl (epfd, op, fd, ref ee); + } + + public static int epoll_wait (int epfd, EpollEvent [] events, int max_events, int timeout) + { + if (events.Length < max_events) + throw new ArgumentOutOfRangeException ("events", "Must refer to at least 'max_events' elements."); + + return sys_epoll_wait (epfd, events, max_events, timeout); + } + + [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_create")] + private static extern int sys_epoll_create (int size); + + [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_create1")] + private static extern int sys_epoll_create1 (EpollFlags flags); + + [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_ctl")] + private static extern int sys_epoll_ctl (int epfd, EpollOp op, int fd, ref EpollEvent ee); + + [DllImport (LIBC, SetLastError=true, EntryPoint="epoll_wait")] + private static extern int sys_epoll_wait (int epfd, EpollEvent [] ee, int maxevents, int timeout); + #endregion + #region Declarations // // @@ -2879,7 +3059,49 @@ namespace Mono.Unix.Native { // // - // TODO: uname(2) + [Map] + private struct _Utsname + { + public IntPtr sysname; + public IntPtr nodename; + public IntPtr release; + public IntPtr version; + public IntPtr machine; + public IntPtr domainname; + public IntPtr _buf_; + } + + private static void CopyUtsname (ref Utsname to, ref _Utsname from) + { + try { + to = new Utsname (); + to.sysname = UnixMarshal.PtrToString (from.sysname); + to.nodename = UnixMarshal.PtrToString (from.nodename); + to.release = UnixMarshal.PtrToString (from.release); + to.version = UnixMarshal.PtrToString (from.version); + to.machine = UnixMarshal.PtrToString (from.machine); + to.domainname = UnixMarshal.PtrToString (from.domainname); + } + finally { + Stdlib.free (from._buf_); + from._buf_ = IntPtr.Zero; + } + } + + [DllImport (MPH, SetLastError=true, + EntryPoint="Mono_Posix_Syscall_uname")] + private static extern int sys_uname (out _Utsname buf); + + public static int uname (out Utsname buf) + { + _Utsname _buf; + int r = sys_uname (out _buf); + buf = new Utsname (); + if (r == 0) { + CopyUtsname (ref buf, ref _buf); + } + return r; + } #region Declarations // @@ -3043,6 +3265,12 @@ namespace Mono.Unix.Native { // // + // nanosleep(2) + // int nanosleep(const struct timespec *req, struct timespec *rem); + [DllImport (MPH, SetLastError=true, + EntryPoint="Mono_Posix_Syscall_nanosleep")] + public static extern int nanosleep (ref Timespec req, ref Timespec rem); + // stime(2) // int stime(time_t *t); [DllImport (MPH, SetLastError=true,