using System;
using System.Collections;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
O_DIRECTORY = 0x00010000,
O_DIRECT = 0x00004000,
O_ASYNC = 0x00002000,
- O_LARGEFILE = 0x00008000
+ O_LARGEFILE = 0x00008000,
+ O_CLOEXEC = 0x00080000,
+ O_PATH = 0x00200000
+ }
+
+ [Map][Flags]
+ [CLSCompliant (false)]
+ public enum AtFlags : int {
+ AT_SYMLINK_NOFOLLOW = 0x00000100,
+ AT_REMOVEDIR = 0x00000200,
+ AT_SYMLINK_FOLLOW = 0x00000400,
+ AT_NO_AUTOMOUNT = 0x00000800,
+ AT_EMPTY_PATH = 0x00001000
}
// mode_t
}
}
- [Map ("struct stat")]
+ // Use manually written To/From methods to handle fields st_atime_nsec etc.
public struct Stat
#if NET_2_0
: IEquatable <Stat>
[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 long st_atime_nsec; // Timespec.tv_nsec partner to st_atime
+ public long st_mtime_nsec; // Timespec.tv_nsec partner to st_mtime
+ public long st_ctime_nsec; // Timespec.tv_nsec partner to st_ctime
+
+ public Timespec st_atim {
+ get {
+ return new Timespec { tv_sec = st_atime, tv_nsec = st_atime_nsec };
+ }
+ set {
+ st_atime = value.tv_sec;
+ st_atime_nsec = value.tv_nsec;
+ }
+ }
+
+ public Timespec st_mtim {
+ get {
+ return new Timespec { tv_sec = st_mtime, tv_nsec = st_mtime_nsec };
+ }
+ set {
+ st_mtime = value.tv_sec;
+ st_mtime_nsec = value.tv_nsec;
+ }
+ }
+
+ public Timespec st_ctim {
+ get {
+ return new Timespec { tv_sec = st_ctime, tv_nsec = st_ctime_nsec };
+ }
+ set {
+ st_ctime = value.tv_sec;
+ st_ctime_nsec = value.tv_nsec;
+ }
+ }
public override int GetHashCode ()
{
st_blocks.GetHashCode () ^
st_atime.GetHashCode () ^
st_mtime.GetHashCode () ^
- st_ctime.GetHashCode ();
+ st_ctime.GetHashCode () ^
+ st_atime_nsec.GetHashCode () ^
+ st_mtime_nsec.GetHashCode () ^
+ st_ctime_nsec.GetHashCode ();
}
public override bool Equals (object obj)
value.st_blocks == st_blocks &&
value.st_atime == st_atime &&
value.st_mtime == st_mtime &&
- value.st_ctime == st_ctime;
+ value.st_ctime == st_ctime &&
+ value.st_atime_nsec == st_atime_nsec &&
+ value.st_mtime_nsec == st_mtime_nsec &&
+ value.st_ctime_nsec == st_ctime_nsec;
}
public bool Equals (Stat value)
value.st_blocks == st_blocks &&
value.st_atime == st_atime &&
value.st_mtime == st_mtime &&
- value.st_ctime == st_ctime;
+ value.st_ctime == st_ctime &&
+ value.st_atime_nsec == st_atime_nsec &&
+ value.st_mtime_nsec == st_mtime_nsec &&
+ value.st_ctime_nsec == st_ctime_nsec;
}
public static bool operator== (Stat lhs, Stat rhs)
}
}
+ [Map ("struct iovec")]
+ public struct Iovec
+ {
+ public IntPtr iov_base; // Starting address
+ [CLSCompliant (false)]
+ public ulong iov_len; // Number of bytes to transfer
+ }
+
[Flags][Map]
public enum EpollFlags {
EPOLL_CLOEXEC = 02000000,
}
[Flags][Map]
+ [CLSCompliant (false)]
public enum EpollEvents : uint {
EPOLLIN = 0x001,
EPOLLPRI = 0x002,
}
[StructLayout (LayoutKind.Explicit, Size=12, Pack=1)]
+ [CLSCompliant (false)]
public struct EpollEvent {
[FieldOffset (0)]
public EpollEvents events;
[DllImport (LIBC, SetLastError=true)]
public static extern int dirfd (IntPtr dir);
+
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern IntPtr fdopendir (int fd);
#endregion
#region <fcntl.h> Declarations
[DllImport (MPH, SetLastError=true,
EntryPoint="Mono_Posix_Syscall_posix_fallocate")]
public static extern int posix_fallocate (int fd, long offset, ulong len);
+
+ [DllImport (LIBC, SetLastError=true,
+ EntryPoint="openat")]
+ private static extern int sys_openat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int flags);
+
+ // openat(2)
+ // int openat(int dirfd, const char *pathname, int flags, mode_t mode);
+ [DllImport (LIBC, SetLastError=true,
+ EntryPoint="openat")]
+ private static extern int sys_openat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int flags, uint mode);
+
+ public static int openat (int dirfd, string pathname, OpenFlags flags)
+ {
+ int _flags = NativeConvert.FromOpenFlags (flags);
+ return sys_openat (dirfd, pathname, _flags);
+ }
+
+ public static int openat (int dirfd, string pathname, OpenFlags flags, FilePermissions mode)
+ {
+ int _flags = NativeConvert.FromOpenFlags (flags);
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ return sys_openat (dirfd, pathname, _flags, _mode);
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_get_at_fdcwd")]
+ private static extern int get_at_fdcwd ();
+
+ public static readonly int AT_FDCWD = get_at_fdcwd ();
+
#endregion
#region <fstab.h> Declarations
//
// <grp.h>
//
- // TODO: putgrent(3), fgetgrent_r(), getgrouplist(2), initgroups(3)
+ // TODO: putgrent(3), fgetgrent_r(), initgroups(3)
+
+ // getgrouplist(2)
+ [DllImport (LIBC, SetLastError=true, EntryPoint="getgrouplist")]
+ private static extern int sys_getgrouplist (string user, uint grp, uint [] groups,ref int ngroups);
+
+ public static Group [] getgrouplist (string username)
+ {
+ if (username == null)
+ throw new ArgumentNullException ("username");
+ if (username.Trim () == "")
+ throw new ArgumentException ("Username cannot be empty", "username");
+ // Syscall to getpwnam to retrieve user uid
+ Passwd pw = Syscall.getpwnam (username);
+ if (pw == null)
+ throw new ArgumentException (string.Format ("User {0} does not exist", username), "username");
+ return getgrouplist (pw);
+ }
+
+ public static Group [] getgrouplist (Passwd user)
+ {
+ if (user == null)
+ throw new ArgumentNullException ("user");
+ // initializing ngroups by 16 to get the group count
+ int ngroups = 8;
+ int res = -1;
+ // allocating buffer to store group uid's
+ uint [] groups=null;
+ do {
+ Array.Resize (ref groups, ngroups*=2);
+ res = sys_getgrouplist (user.pw_name, user.pw_gid, groups, ref ngroups);
+ }
+ while (res == -1);
+ List<Group> result = new List<Group> ();
+ Group gr = null;
+ for (int i = 0; i < res; i++) {
+ gr = Syscall.getgrgid (groups [i]);
+ if (gr != null)
+ result.Add (gr);
+ }
+ return result.ToArray ();
+ }
// setgroups(2)
// int setgroups (size_t size, const gid_t *list);
- [DllImport (MPH, SetLastError=true,
+ [DllImport (MPH, SetLastError=true,
EntryPoint="Mono_Posix_Syscall_setgroups")]
public static extern int setgroups (ulong size, uint[] list);
}
}
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern int renameat (int olddirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, int newdirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string newpath);
#endregion
#region <stdlib.h> Declarations
[DllImport (LIBC, SetLastError=true)]
public static extern int mkstemp (StringBuilder template);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="mkdtemp")]
+ private static extern IntPtr sys_mkdtemp (StringBuilder template);
+
+ public static StringBuilder mkdtemp (StringBuilder template)
+ {
+ if (sys_mkdtemp (template) == IntPtr.Zero)
+ return null;
+ return template;
+ }
+
[DllImport (LIBC, SetLastError=true)]
public static extern int ttyslot ();
return sys_mkfifo (pathname, _mode);
}
+ // fchmodat(2)
+ // int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="fchmodat")]
+ private static extern int sys_fchmodat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, uint mode, int flags);
+
+ public static int fchmodat (int dirfd, string pathname, FilePermissions mode, AtFlags flags)
+ {
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_fchmodat (dirfd, pathname, _mode, _flags);
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_fstatat")]
+ public static extern int fstatat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string file_name, out Stat buf, AtFlags flags);
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_get_utime_now")]
+ private static extern long get_utime_now ();
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_get_utime_omit")]
+ private static extern long get_utime_omit ();
+
+ public static readonly long UTIME_NOW = get_utime_now ();
+
+ public static readonly long UTIME_OMIT = get_utime_omit ();
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_futimens")]
+ private static extern int sys_futimens (int fd, Timespec[] times);
+
+ public static int futimens (int fd, Timespec[] times)
+ {
+ if (times != null && times.Length != 2) {
+ SetLastError (Errno.EINVAL);
+ return -1;
+ }
+ return sys_futimens (fd, times);
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_utimensat")]
+ private static extern int sys_utimensat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, Timespec[] times, int flags);
+
+ public static int utimensat (int dirfd, string pathname, Timespec[] times, AtFlags flags)
+ {
+ if (times != null && times.Length != 2) {
+ SetLastError (Errno.EINVAL);
+ return -1;
+ }
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_utimensat (dirfd, pathname, times, _flags);
+ }
+
+ // mkdirat(2)
+ // int mkdirat(int dirfd, const char *pathname, mode_t mode);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="mkdirat")]
+ private static extern int sys_mkdirat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, uint mode);
+
+ public static int mkdirat (int dirfd, string oldpath, FilePermissions mode)
+ {
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ return sys_mkdirat (dirfd, oldpath, _mode);
+ }
+
+ // mknodat(2)
+ // int mknodat (int dirfd, const char *pathname, mode_t mode, dev_t dev);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_mknodat")]
+ public static extern int mknodat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, FilePermissions mode, ulong dev);
+
+ // mkfifoat(3)
+ // int mkfifoat(int dirfd, const char *pathname, mode_t mode);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="mkfifoat")]
+ private static extern int sys_mkfifoat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, uint mode);
+
+ public static int mkfifoat (int dirfd, string pathname, FilePermissions mode)
+ {
+ uint _mode = NativeConvert.FromFilePermissions (mode);
+ return sys_mkfifoat (dirfd, pathname, _mode);
+ }
#endregion
#region <sys/stat.h> Declarations
[MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
string newpath);
+ delegate long DoReadlinkFun (byte[] target);
+
+ // Helper function for readlink(string, StringBuilder) and readlinkat (int, string, StringBuilder)
+ static int ReadlinkIntoStringBuilder (DoReadlinkFun doReadlink, [Out] StringBuilder buf, ulong bufsiz)
+ {
+ // bufsiz > int.MaxValue can't work because StringBuilder can store only int.MaxValue chars
+ int bufsizInt = checked ((int) bufsiz);
+ var target = new byte [bufsizInt];
+
+ var r = doReadlink (target);
+ if (r < 0)
+ return checked ((int) r);
+
+ buf.Length = 0;
+ var chars = UnixEncoding.Instance.GetChars (target, 0, checked ((int) r));
+ // Make sure that at more bufsiz chars are written
+ buf.Append (chars, 0, System.Math.Min (bufsizInt, chars.Length));
+ if (r == bufsizInt) {
+ // may not have read full contents; fill 'buf' so that caller can properly check
+ buf.Append (new string ('\x00', bufsizInt - buf.Length));
+ }
+ return buf.Length;
+ }
+
// readlink(2)
- // int readlink(const char *path, char *buf, size_t bufsize);
+ // ssize_t readlink(const char *path, char *buf, size_t bufsize);
+ public static int readlink (string path, [Out] StringBuilder buf, ulong bufsiz)
+ {
+ return ReadlinkIntoStringBuilder (target => readlink (path, target), buf, bufsiz);
+ }
+
+ public static int readlink (string path, [Out] StringBuilder buf)
+ {
+ return readlink (path, buf, (ulong) buf.Capacity);
+ }
+
[DllImport (MPH, SetLastError=true,
EntryPoint="Mono_Posix_Syscall_readlink")]
- public static extern int readlink (
+ private static extern long readlink (
[MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
- string path, [Out] StringBuilder buf, ulong bufsiz);
+ string path, byte[] buf, ulong bufsiz);
- public static int readlink (string path, [Out] StringBuilder buf)
+ public static long readlink (string path, byte[] buf)
{
- return readlink (path, buf, (ulong) buf.Capacity);
+ return readlink (path, buf, (ulong) buf.LongLength);
}
[DllImport (LIBC, SetLastError=true)]
swab ((IntPtr) from, (IntPtr) to, n);
}
+ [DllImport (LIBC, SetLastError=true, EntryPoint="faccessat")]
+ private static extern int sys_faccessat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int mode, int flags);
+
+ public static int faccessat (int dirfd, string pathname, AccessModes mode, AtFlags flags)
+ {
+ int _mode = NativeConvert.FromAccessModes (mode);
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_faccessat (dirfd, pathname, _mode, _flags);
+ }
+
+ // fchownat(2)
+ // int fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags);
+ [DllImport (LIBC, SetLastError=true, EntryPoint="fchownat")]
+ private static extern int sys_fchownat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, uint owner, uint group, int flags);
+
+ public static int fchownat (int dirfd, string pathname, uint owner, uint group, AtFlags flags)
+ {
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_fchownat (dirfd, pathname, owner, group, _flags);
+ }
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="linkat")]
+ private static extern int sys_linkat (int olddirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, int newdirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string newpath, int flags);
+
+ public static int linkat (int olddirfd, string oldpath, int newdirfd, string newpath, AtFlags flags)
+ {
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_linkat (olddirfd, oldpath, newdirfd, newpath, _flags);
+ }
+
+ // readlinkat(2)
+ // ssize_t readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize);
+ public static int readlinkat (int dirfd, string pathname, [Out] StringBuilder buf, ulong bufsiz)
+ {
+ return ReadlinkIntoStringBuilder (target => readlinkat (dirfd, pathname, target), buf, bufsiz);
+ }
+
+ public static int readlinkat (int dirfd, string pathname, [Out] StringBuilder buf)
+ {
+ return readlinkat (dirfd, pathname, buf, (ulong) buf.Capacity);
+ }
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_readlinkat")]
+ private static extern long readlinkat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, byte[] buf, ulong bufsiz);
+
+ public static long readlinkat (int dirfd, string pathname, byte[] buf)
+ {
+ return readlinkat (dirfd, pathname, buf, (ulong) buf.LongLength);
+ }
+
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern int symlinkat (
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string oldpath, int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string newpath);
+
+ [DllImport (LIBC, SetLastError=true, EntryPoint="unlinkat")]
+ private static extern int sys_unlinkat (int dirfd,
+ [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+ string pathname, int flags);
+
+ public static int unlinkat (int dirfd, string pathname, AtFlags flags)
+ {
+ int _flags = NativeConvert.FromAtFlags (flags);
+ return sys_unlinkat (dirfd, pathname, _flags);
+ }
#endregion
#region <utime.h> Declarations
return sys_utime (filename, ref buf, 0);
}
#endregion
+
+ #region <sys/uio.h> Declarations
+ //
+ // <sys/uio.h> -- COMPLETE
+ //
+
+ // readv(2)
+ // ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_readv")]
+ private static extern long sys_readv (int fd, Iovec[] iov, int iovcnt);
+
+ public static long readv (int fd, Iovec[] iov)
+ {
+ return sys_readv (fd, iov, iov.Length);
+ }
+
+ // writev(2)
+ // ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_writev")]
+ private static extern long sys_writev (int fd, Iovec[] iov, int iovcnt);
+
+ public static long writev (int fd, Iovec[] iov)
+ {
+ return sys_writev (fd, iov, iov.Length);
+ }
+
+ // preadv(2)
+ // ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_preadv")]
+ private static extern long sys_preadv (int fd, Iovec[] iov, int iovcnt, long offset);
+
+ public static long preadv (int fd, Iovec[] iov, long offset)
+ {
+ return sys_preadv (fd, iov, iov.Length, offset);
+ }
+
+ // pwritev(2)
+ // ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_pwritev")]
+ private static extern long sys_pwritev (int fd, Iovec[] iov, int iovcnt, long offset);
+
+ public static long pwritev (int fd, Iovec[] iov, long offset)
+ {
+ return sys_pwritev (fd, iov, iov.Length, offset);
+ }
+ #endregion
}
#endregion