Add various methods and flags to Syscall
[mono.git] / mcs / class / Mono.Posix / Mono.Unix.Native / Syscall.cs
index 4785de33aab220e2bcf0607f5f57cf11450adbc6..083fb6c40936b97f6f5c93b46802743d012668c7 100644 (file)
@@ -55,6 +55,7 @@
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.Security;
 using System.Text;
@@ -148,7 +149,19 @@ namespace Mono.Unix.Native {
                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
@@ -646,13 +659,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]
@@ -714,6 +730,7 @@ namespace Mono.Unix.Native {
 
        #region Structures
 
+       [Map ("struct flock")]
        public struct Flock
 #if NET_2_0
                : IEquatable <Flock>
@@ -736,7 +753,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 && 
@@ -815,9 +832,10 @@ namespace Mono.Unix.Native {
                [ino_t]     public  ulong   st_ino;     // inode
                [CLSCompliant (false)]
                public  FilePermissions     st_mode;    // protection
-               [CLSCompliant (false)]
                [NonSerialized]
+#pragma warning disable 169            
                private uint                _padding_;  // padding for structure alignment
+#pragma warning restore 169            
                [CLSCompliant (false)]
                [nlink_t]   public  ulong   st_nlink;   // number of hard links
                [CLSCompliant (false)]
@@ -1022,7 +1040,9 @@ namespace Mono.Unix.Native {
 #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 ()
                {
@@ -1053,6 +1073,7 @@ namespace Mono.Unix.Native {
                }
        }
 
+       [Map ("struct utimbuf")]
        public struct Utimbuf
 #if NET_2_0
                : IEquatable <Utimbuf>
@@ -1090,6 +1111,96 @@ namespace Mono.Unix.Native {
                }
        }
 
+       [Map ("struct timespec")]
+       public struct Timespec
+#if NET_2_0
+               : IEquatable <Timespec>
+#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);
+               }
+       }
+
+       [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,
+               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
@@ -1342,6 +1453,58 @@ namespace Mono.Unix.Native {
                }
        }
 
+       public sealed class Utsname
+#if NET_2_0
+               : IEquatable <Utsname>
+#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.
@@ -1862,6 +2025,9 @@ namespace Mono.Unix.Native {
 
                [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
@@ -1925,6 +2091,40 @@ namespace Mono.Unix.Native {
                [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
@@ -2048,11 +2248,52 @@ namespace Mono.Unix.Native {
                //
                // <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 exists",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);
 
@@ -2480,6 +2721,12 @@ namespace Mono.Unix.Native {
                        }
                }
 
+               [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
@@ -2489,6 +2736,16 @@ namespace Mono.Unix.Native {
                [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 ();
 
@@ -2525,6 +2782,48 @@ namespace Mono.Unix.Native {
 
                #endregion
 
+               #region <sys/epoll.h> 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 <sys/mman.h> Declarations
                //
                // <sys/mman.h>
@@ -2754,6 +3053,100 @@ namespace Mono.Unix.Native {
                        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
@@ -2875,7 +3268,49 @@ namespace Mono.Unix.Native {
                // <sys/utsname.h>
                //
 
-               // 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 <sys/wait.h> Declarations
                //
@@ -3039,6 +3474,12 @@ namespace Mono.Unix.Native {
                // <time.h>
                //
 
+               // 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,
@@ -3704,6 +4145,74 @@ namespace Mono.Unix.Native {
                        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)
+               //    int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize);
+               [DllImport (MPH, SetLastError=true,
+                               EntryPoint="Mono_Posix_Syscall_readlinkat")]
+               public static extern int readlinkat (int dirfd,
+                               [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))]
+                               string pathname, [Out] StringBuilder buf, ulong bufsiz);
+
+               public static int readlinkat (int dirfd, string pathname, [Out] StringBuilder buf)
+               {
+                       return readlinkat (dirfd, pathname, buf, (ulong) buf.Capacity);
+               }
+
+               [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
@@ -3728,6 +4237,56 @@ namespace Mono.Unix.Native {
                        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