Add various methods and flags to Syscall
authorSteffen Kieß <s-kiess@web.de>
Tue, 26 Mar 2013 20:26:09 +0000 (21:26 +0100)
committerSteffen Kieß <s-kiess@web.de>
Tue, 26 Mar 2013 20:26:09 +0000 (21:26 +0100)
    * Add OpenFlags.O_CLOEXEC and OpenFlags.O_PATH

    * Add AtFlags for AT_* values

    * Add fdopendir, mkdtemp, futimens

    * Add readv, writev, preadv, pwritev

    * Add *at methods: openat, renameat, fchmodat, fstatat, utimensat,
      mkdirat, mknodat, mkfifoat, faccessat, fchownat, linkat, readlinkat,
      symlinkat, unlinkat

    * Add constants AT_FDCWD, UTIME_NOW, UTIME_OMIT

configure.in
mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs
mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs
support/Makefile.am
support/fcntl.c
support/map.c
support/map.h
support/sys-stat.c
support/sys-uio.c [new file with mode: 0644]
support/unistd.c

index 099c56eecf1969e4d14f6102545c32388253cf16..c32d35fc442b6424a2584eef49fd806991de5fa1 100644 (file)
@@ -1959,6 +1959,9 @@ if test x$target_win32 = xno; then
        AC_CHECK_FUNCS(lockf)
        AC_CHECK_FUNCS(swab)
        AC_CHECK_FUNCS(setusershell endusershell)
+       AC_CHECK_FUNCS(futimens utimensat)
+       AC_CHECK_FUNCS(fstatat mknodat readlinkat)
+       AC_CHECK_FUNCS(readv writev preadv pwritev)
        AC_CHECK_SIZEOF(size_t)
        AC_CHECK_TYPES([blksize_t], [AC_DEFINE(HAVE_BLKSIZE_T)], , 
                [#include <sys/types.h>
@@ -1973,6 +1976,8 @@ if test x$target_win32 = xno; then
        AC_CHECK_TYPES([struct flock], [AC_DEFINE(HAVE_STRUCT_FLOCK)], ,
                [#include <unistd.h>
                 #include <fcntl.h>])
+       AC_CHECK_TYPES([struct iovec], [AC_DEFINE(HAVE_STRUCT_IOVEC)], ,
+               [#include <sys/uio.h>])
        AC_CHECK_TYPES([struct pollfd], [AC_DEFINE(HAVE_STRUCT_POLLFD)], ,
                [#include <sys/poll.h>])
        AC_CHECK_TYPES([struct stat], [AC_DEFINE(HAVE_STRUCT_STAT)], ,
index be846a892c168fe195d48e0fc1ed44e677afef18..e5e41cc3b0cc0d1989d1f2a35fcb1491b25aece0 100644 (file)
@@ -54,6 +54,38 @@ namespace Mono.Unix.Native {
                        return rval;
                }
 
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromAtFlags")]
+               private static extern int FromAtFlags (AtFlags value, out Int32 rval);
+
+               public static bool TryFromAtFlags (AtFlags value, out Int32 rval)
+               {
+                       return FromAtFlags (value, out rval) == 0;
+               }
+
+               public static Int32 FromAtFlags (AtFlags value)
+               {
+                       Int32 rval;
+                       if (FromAtFlags (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToAtFlags")]
+               private static extern int ToAtFlags (Int32 value, out AtFlags rval);
+
+               public static bool TryToAtFlags (Int32 value, out AtFlags rval)
+               {
+                       return ToAtFlags (value, out rval) == 0;
+               }
+
+               public static AtFlags ToAtFlags (Int32 value)
+               {
+                       AtFlags rval;
+                       if (ToAtFlags (value, out rval) == -1)
+                               ThrowArgumentException (value);
+                       return rval;
+               }
+
                [DllImport (LIB, EntryPoint="Mono_Posix_FromConfstrName")]
                private static extern int FromConfstrName (ConfstrName value, out Int32 rval);
 
@@ -294,6 +326,22 @@ namespace Mono.Unix.Native {
                        return ToFlock (source, out destination) == 0;
                }
 
+               [DllImport (LIB, EntryPoint="Mono_Posix_FromIovec")]
+               private static extern int FromIovec (ref Iovec source, IntPtr destination);
+
+               public static bool TryCopy (ref Iovec source, IntPtr destination)
+               {
+                       return FromIovec (ref source, destination) == 0;
+               }
+
+               [DllImport (LIB, EntryPoint="Mono_Posix_ToIovec")]
+               private static extern int ToIovec (IntPtr source, out Iovec destination);
+
+               public static bool TryCopy (IntPtr source, out Iovec destination)
+               {
+                       return ToIovec (source, out destination) == 0;
+               }
+
                [DllImport (LIB, EntryPoint="Mono_Posix_FromLockType")]
                private static extern int FromLockType (LockType value, out Int16 rval);
 
index e5ef6c7a93bfc103178b244a163da9624d39668a..083fb6c40936b97f6f5c93b46802743d012668c7 100644 (file)
@@ -149,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
@@ -1137,6 +1149,14 @@ namespace Mono.Unix.Native {
                }
        }
 
+       [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,
@@ -2005,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
@@ -2068,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
@@ -2664,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
@@ -2673,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 ();
 
@@ -2980,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
@@ -3978,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
@@ -4002,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
index 1de8fc77cb7cc9d7c81e813785563d353d63f022..0ae77e769b901db44970c48aa214319b0be1f87f 100644 (file)
@@ -43,6 +43,7 @@ MPH_UNIX_SOURCE =                             \
        sys-stat.c                              \
        sys-statvfs.c                           \
        sys-time.c                              \
+       sys-uio.c                               \
        sys-utsname.c   \
        sys-wait.c                              \
        sys-xattr.c                             \
index 013d9cd416793007bae98ab55c4011339ffa7af7..12947991c00fa9387a9d1b2896e2c008e5313256 100644 (file)
@@ -100,6 +100,16 @@ Mono_Posix_Syscall_open_mode (const char *pathname, gint32 flags, guint32 mode)
        return open (pathname, flags, mode);
 }
 
+gint32
+Mono_Posix_Syscall_get_at_fdcwd ()
+{
+#ifdef AT_FDCWD
+       return AT_FDCWD;
+#else
+       return -1;
+#endif
+}
+
 gint32
 Mono_Posix_Syscall_creat (const char *pathname, guint32 mode)
 {
index cb653bcda9a81e0c8f09b4e26c3da802b1c4ab96..2150cb29bbba031e1ac9d4391df127c569bc96ab 100644 (file)
@@ -292,6 +292,72 @@ int Mono_Posix_ToAccessModes (int x, int *r)
        return 0;
 }
 
+int Mono_Posix_FromAtFlags (int x, int *r)
+{
+       *r = 0;
+       if ((x & Mono_Posix_AtFlags_AT_EMPTY_PATH) == Mono_Posix_AtFlags_AT_EMPTY_PATH)
+#ifdef AT_EMPTY_PATH
+               *r |= AT_EMPTY_PATH;
+#else /* def AT_EMPTY_PATH */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AT_EMPTY_PATH */
+       if ((x & Mono_Posix_AtFlags_AT_NO_AUTOMOUNT) == Mono_Posix_AtFlags_AT_NO_AUTOMOUNT)
+#ifdef AT_NO_AUTOMOUNT
+               *r |= AT_NO_AUTOMOUNT;
+#else /* def AT_NO_AUTOMOUNT */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AT_NO_AUTOMOUNT */
+       if ((x & Mono_Posix_AtFlags_AT_REMOVEDIR) == Mono_Posix_AtFlags_AT_REMOVEDIR)
+#ifdef AT_REMOVEDIR
+               *r |= AT_REMOVEDIR;
+#else /* def AT_REMOVEDIR */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AT_REMOVEDIR */
+       if ((x & Mono_Posix_AtFlags_AT_SYMLINK_FOLLOW) == Mono_Posix_AtFlags_AT_SYMLINK_FOLLOW)
+#ifdef AT_SYMLINK_FOLLOW
+               *r |= AT_SYMLINK_FOLLOW;
+#else /* def AT_SYMLINK_FOLLOW */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AT_SYMLINK_FOLLOW */
+       if ((x & Mono_Posix_AtFlags_AT_SYMLINK_NOFOLLOW) == Mono_Posix_AtFlags_AT_SYMLINK_NOFOLLOW)
+#ifdef AT_SYMLINK_NOFOLLOW
+               *r |= AT_SYMLINK_NOFOLLOW;
+#else /* def AT_SYMLINK_NOFOLLOW */
+               {errno = EINVAL; return -1;}
+#endif /* ndef AT_SYMLINK_NOFOLLOW */
+       if (x == 0)
+               return 0;
+       return 0;
+}
+
+int Mono_Posix_ToAtFlags (int x, int *r)
+{
+       *r = 0;
+       if (x == 0)
+               return 0;
+#ifdef AT_EMPTY_PATH
+       if ((x & AT_EMPTY_PATH) == AT_EMPTY_PATH)
+               *r |= Mono_Posix_AtFlags_AT_EMPTY_PATH;
+#endif /* ndef AT_EMPTY_PATH */
+#ifdef AT_NO_AUTOMOUNT
+       if ((x & AT_NO_AUTOMOUNT) == AT_NO_AUTOMOUNT)
+               *r |= Mono_Posix_AtFlags_AT_NO_AUTOMOUNT;
+#endif /* ndef AT_NO_AUTOMOUNT */
+#ifdef AT_REMOVEDIR
+       if ((x & AT_REMOVEDIR) == AT_REMOVEDIR)
+               *r |= Mono_Posix_AtFlags_AT_REMOVEDIR;
+#endif /* ndef AT_REMOVEDIR */
+#ifdef AT_SYMLINK_FOLLOW
+       if ((x & AT_SYMLINK_FOLLOW) == AT_SYMLINK_FOLLOW)
+               *r |= Mono_Posix_AtFlags_AT_SYMLINK_FOLLOW;
+#endif /* ndef AT_SYMLINK_FOLLOW */
+#ifdef AT_SYMLINK_NOFOLLOW
+       if ((x & AT_SYMLINK_NOFOLLOW) == AT_SYMLINK_NOFOLLOW)
+               *r |= Mono_Posix_AtFlags_AT_SYMLINK_NOFOLLOW;
+#endif /* ndef AT_SYMLINK_NOFOLLOW */
+       return 0;
+}
+
 int Mono_Posix_FromConfstrName (int x, int *r)
 {
        *r = 0;
@@ -2764,6 +2830,38 @@ Mono_Posix_ToFlock (struct flock *from, struct Mono_Posix_Flock *to)
 #endif /* ndef HAVE_STRUCT_FLOCK */
 
 
+#ifdef HAVE_STRUCT_IOVEC
+int
+Mono_Posix_FromIovec (struct Mono_Posix_Iovec *from, struct iovec *to)
+{
+       _cnm_return_val_if_overflow (guint64, from->iov_len, -1);
+
+       memset (to, 0, sizeof(*to));
+
+       to->iov_base = from->iov_base;
+       to->iov_len  = from->iov_len;
+
+       return 0;
+}
+#endif /* ndef HAVE_STRUCT_IOVEC */
+
+
+#ifdef HAVE_STRUCT_IOVEC
+int
+Mono_Posix_ToIovec (struct iovec *from, struct Mono_Posix_Iovec *to)
+{
+       _cnm_return_val_if_overflow (guint64, from->iov_len, -1);
+
+       memset (to, 0, sizeof(*to));
+
+       to->iov_base = from->iov_base;
+       to->iov_len  = from->iov_len;
+
+       return 0;
+}
+#endif /* ndef HAVE_STRUCT_IOVEC */
+
+
 int Mono_Posix_FromLockType (short x, short *r)
 {
        *r = 0;
@@ -3367,6 +3465,12 @@ int Mono_Posix_FromOpenFlags (int x, int *r)
 #else /* def O_ASYNC */
                {errno = EINVAL; return -1;}
 #endif /* ndef O_ASYNC */
+       if ((x & Mono_Posix_OpenFlags_O_CLOEXEC) == Mono_Posix_OpenFlags_O_CLOEXEC)
+#ifdef O_CLOEXEC
+               *r |= O_CLOEXEC;
+#else /* def O_CLOEXEC */
+               {errno = EINVAL; return -1;}
+#endif /* ndef O_CLOEXEC */
        if ((x & Mono_Posix_OpenFlags_O_CREAT) == Mono_Posix_OpenFlags_O_CREAT)
 #ifdef O_CREAT
                *r |= O_CREAT;
@@ -3415,6 +3519,12 @@ int Mono_Posix_FromOpenFlags (int x, int *r)
 #else /* def O_NONBLOCK */
                {errno = EINVAL; return -1;}
 #endif /* ndef O_NONBLOCK */
+       if ((x & Mono_Posix_OpenFlags_O_PATH) == Mono_Posix_OpenFlags_O_PATH)
+#ifdef O_PATH
+               *r |= O_PATH;
+#else /* def O_PATH */
+               {errno = EINVAL; return -1;}
+#endif /* ndef O_PATH */
        if ((x & Mono_Posix_OpenFlags_O_RDONLY) == Mono_Posix_OpenFlags_O_RDONLY)
 #ifdef O_RDONLY
                *r |= O_RDONLY;
@@ -3463,6 +3573,10 @@ int Mono_Posix_ToOpenFlags (int x, int *r)
        if ((x & O_ASYNC) == O_ASYNC)
                *r |= Mono_Posix_OpenFlags_O_ASYNC;
 #endif /* ndef O_ASYNC */
+#ifdef O_CLOEXEC
+       if ((x & O_CLOEXEC) == O_CLOEXEC)
+               *r |= Mono_Posix_OpenFlags_O_CLOEXEC;
+#endif /* ndef O_CLOEXEC */
 #ifdef O_CREAT
        if ((x & O_CREAT) == O_CREAT)
                *r |= Mono_Posix_OpenFlags_O_CREAT;
@@ -3495,6 +3609,10 @@ int Mono_Posix_ToOpenFlags (int x, int *r)
        if ((x & O_NONBLOCK) == O_NONBLOCK)
                *r |= Mono_Posix_OpenFlags_O_NONBLOCK;
 #endif /* ndef O_NONBLOCK */
+#ifdef O_PATH
+       if ((x & O_PATH) == O_PATH)
+               *r |= Mono_Posix_OpenFlags_O_PATH;
+#endif /* ndef O_PATH */
 #ifdef O_RDONLY
        if ((x & O_RDONLY) == O_RDONLY)
                *r |= Mono_Posix_OpenFlags_O_RDONLY;
index aab06b7b9cd87633ac75ad4b535a413d09a946db..77d75db3ad41fe077fb0d1ea0bc5b01a75b6e443 100644 (file)
@@ -35,6 +35,21 @@ enum Mono_Posix_AccessModes {
 int Mono_Posix_FromAccessModes (int x, int *r);
 int Mono_Posix_ToAccessModes (int x, int *r);
 
+enum Mono_Posix_AtFlags {
+       Mono_Posix_AtFlags_AT_EMPTY_PATH             = 0x00001000,
+       #define Mono_Posix_AtFlags_AT_EMPTY_PATH       Mono_Posix_AtFlags_AT_EMPTY_PATH
+       Mono_Posix_AtFlags_AT_NO_AUTOMOUNT           = 0x00000800,
+       #define Mono_Posix_AtFlags_AT_NO_AUTOMOUNT     Mono_Posix_AtFlags_AT_NO_AUTOMOUNT
+       Mono_Posix_AtFlags_AT_REMOVEDIR              = 0x00000200,
+       #define Mono_Posix_AtFlags_AT_REMOVEDIR        Mono_Posix_AtFlags_AT_REMOVEDIR
+       Mono_Posix_AtFlags_AT_SYMLINK_FOLLOW         = 0x00000400,
+       #define Mono_Posix_AtFlags_AT_SYMLINK_FOLLOW   Mono_Posix_AtFlags_AT_SYMLINK_FOLLOW
+       Mono_Posix_AtFlags_AT_SYMLINK_NOFOLLOW       = 0x00000100,
+       #define Mono_Posix_AtFlags_AT_SYMLINK_NOFOLLOW Mono_Posix_AtFlags_AT_SYMLINK_NOFOLLOW
+};
+int Mono_Posix_FromAtFlags (int x, int *r);
+int Mono_Posix_ToAtFlags (int x, int *r);
+
 enum Mono_Posix_ConfstrName {
        Mono_Posix_ConfstrName__CS_GNU_LIBC_VERSION                      = 0x00000002,
        #define Mono_Posix_ConfstrName__CS_GNU_LIBC_VERSION                Mono_Posix_ConfstrName__CS_GNU_LIBC_VERSION
@@ -669,6 +684,8 @@ enum Mono_Posix_OpenFlags {
        #define Mono_Posix_OpenFlags_O_APPEND    Mono_Posix_OpenFlags_O_APPEND
        Mono_Posix_OpenFlags_O_ASYNC           = 0x00002000,
        #define Mono_Posix_OpenFlags_O_ASYNC     Mono_Posix_OpenFlags_O_ASYNC
+       Mono_Posix_OpenFlags_O_CLOEXEC         = 0x00080000,
+       #define Mono_Posix_OpenFlags_O_CLOEXEC   Mono_Posix_OpenFlags_O_CLOEXEC
        Mono_Posix_OpenFlags_O_CREAT           = 0x00000040,
        #define Mono_Posix_OpenFlags_O_CREAT     Mono_Posix_OpenFlags_O_CREAT
        Mono_Posix_OpenFlags_O_DIRECT          = 0x00004000,
@@ -685,6 +702,8 @@ enum Mono_Posix_OpenFlags {
        #define Mono_Posix_OpenFlags_O_NOFOLLOW  Mono_Posix_OpenFlags_O_NOFOLLOW
        Mono_Posix_OpenFlags_O_NONBLOCK        = 0x00000800,
        #define Mono_Posix_OpenFlags_O_NONBLOCK  Mono_Posix_OpenFlags_O_NONBLOCK
+       Mono_Posix_OpenFlags_O_PATH            = 0x00200000,
+       #define Mono_Posix_OpenFlags_O_PATH      Mono_Posix_OpenFlags_O_PATH
        Mono_Posix_OpenFlags_O_RDONLY          = 0x00000000,
        #define Mono_Posix_OpenFlags_O_RDONLY    Mono_Posix_OpenFlags_O_RDONLY
        Mono_Posix_OpenFlags_O_RDWR            = 0x00000002,
@@ -1411,6 +1430,7 @@ int Mono_Posix_ToXattrFlags (int x, int *r);
  */
 
 struct Mono_Posix_Flock;
+struct Mono_Posix_Iovec;
 struct Mono_Posix_Pollfd;
 struct Mono_Posix_Stat;
 struct Mono_Posix_Statvfs;
@@ -1430,6 +1450,7 @@ struct Mono_Unix_UnixSignal_SignalInfo;
  */
 
 struct flock;
+struct iovec;
 struct pollfd;
 struct stat;
 struct timespec;
@@ -1461,6 +1482,17 @@ int
 Mono_Posix_ToFlock (struct flock *from, struct Mono_Posix_Flock* to);
 
 
+struct Mono_Posix_Iovec {
+       void*   iov_base;
+       guint64 iov_len;
+};
+
+int
+Mono_Posix_FromIovec (struct Mono_Posix_Iovec* from, struct iovec *to);
+int
+Mono_Posix_ToIovec (struct iovec *from, struct Mono_Posix_Iovec* to);
+
+
 struct Mono_Posix_Pollfd {
        int   fd;
        short events;
@@ -1685,9 +1717,14 @@ gint64 Mono_Posix_Syscall_fpathconf (int filedes, int name, int defaultError);
 int Mono_Posix_Syscall_fremovexattr (int fd, const char* name);
 int Mono_Posix_Syscall_fsetxattr (int fd, const char* name, unsigned char* value, guint64 size, int flags);
 int Mono_Posix_Syscall_fstat (int filedes, struct Mono_Posix_Stat* buf);
+int Mono_Posix_Syscall_fstatat (int dirfd, const char* file_name, struct Mono_Posix_Stat* buf, int flags);
 int Mono_Posix_Syscall_fstatvfs (int fd, struct Mono_Posix_Statvfs* buf);
 int Mono_Posix_Syscall_ftruncate (int fd, gint64 length);
+int Mono_Posix_Syscall_futimens (int fd, struct Mono_Posix_Timespec* times);
 int Mono_Posix_Syscall_futimes (int fd, struct Mono_Posix_Timeval* tvp);
+int Mono_Posix_Syscall_get_at_fdcwd (void);
+gint64 Mono_Posix_Syscall_get_utime_now (void);
+gint64 Mono_Posix_Syscall_get_utime_omit (void);
 void* Mono_Posix_Syscall_getcwd (char* buf, guint64 size);
 int Mono_Posix_Syscall_getdomainname (char* name, guint64 len);
 int Mono_Posix_Syscall_getfsent (struct Mono_Posix_Syscall__Fstab* fs);
@@ -1721,6 +1758,7 @@ int Mono_Posix_Syscall_lstat (const char* file_name, struct Mono_Posix_Stat* buf
 int Mono_Posix_Syscall_lutimes (const char* filename, struct Mono_Posix_Timeval* tvp);
 int Mono_Posix_Syscall_mincore (void* start, guint64 length, unsigned char* vec);
 int Mono_Posix_Syscall_mknod (const char* pathname, unsigned int mode, guint64 dev);
+int Mono_Posix_Syscall_mknodat (int dirfd, const char* pathname, unsigned int mode, guint64 dev);
 int Mono_Posix_Syscall_mlock (void* start, guint64 len);
 void* Mono_Posix_Syscall_mmap (void* start, guint64 length, int prot, int flags, int fd, gint64 offset);
 int Mono_Posix_Syscall_mprotect (void* start, guint64 len, int prot);
@@ -1738,12 +1776,16 @@ int Mono_Posix_Syscall_posix_fadvise (int fd, gint64 offset, gint64 len, int adv
 int Mono_Posix_Syscall_posix_fallocate (int fd, gint64 offset, guint64 len);
 int Mono_Posix_Syscall_posix_madvise (void* addr, guint64 len, int advice);
 gint64 Mono_Posix_Syscall_pread (int fd, void* buf, guint64 count, gint64 offset);
+gint64 Mono_Posix_Syscall_preadv (int fd, struct Mono_Posix_Iovec* iov, int iovcnt, gint64 offset);
 int Mono_Posix_Syscall_psignal (int sig, const char* s);
 gint64 Mono_Posix_Syscall_pwrite (int fd, void* buf, guint64 count, gint64 offset);
+gint64 Mono_Posix_Syscall_pwritev (int fd, struct Mono_Posix_Iovec* iov, int iovcnt, gint64 offset);
 gint64 Mono_Posix_Syscall_read (int fd, void* buf, guint64 count);
 int Mono_Posix_Syscall_readdir (void* dir, struct Mono_Posix_Syscall__Dirent* dentry);
 int Mono_Posix_Syscall_readdir_r (void* dirp, struct Mono_Posix_Syscall__Dirent* entry, void** result);
 int Mono_Posix_Syscall_readlink (const char* path, char* buf, guint64 bufsiz);
+int Mono_Posix_Syscall_readlinkat (int dirfd, const char* pathname, char* buf, guint64 bufsiz);
+gint64 Mono_Posix_Syscall_readv (int fd, struct Mono_Posix_Iovec* iov, int iovcnt);
 int Mono_Posix_Syscall_remap_file_pages (void* start, guint64 size, int prot, gint64 pgoff, int flags);
 int Mono_Posix_Syscall_removexattr (const char* path, const char* name);
 int Mono_Posix_Syscall_rewinddir (void* dir);
@@ -1773,12 +1815,14 @@ int Mono_Posix_Syscall_truncate (const char* path, gint64 length);
 int Mono_Posix_Syscall_ttyname_r (int fd, char* buf, guint64 buflen);
 int Mono_Posix_Syscall_uname (struct Mono_Posix_Syscall__Utsname* buf);
 int Mono_Posix_Syscall_utime (const char* filename, struct Mono_Posix_Utimbuf* buf, int use_buf);
+int Mono_Posix_Syscall_utimensat (int dirfd, const char* pathname, struct Mono_Posix_Timespec* times, int flags);
 int Mono_Posix_Syscall_utimes (const char* filename, struct Mono_Posix_Timeval* tvp);
 int Mono_Posix_Syscall_WEXITSTATUS (int status);
 int Mono_Posix_Syscall_WIFEXITED (int status);
 int Mono_Posix_Syscall_WIFSIGNALED (int status);
 int Mono_Posix_Syscall_WIFSTOPPED (int status);
 gint64 Mono_Posix_Syscall_write (int fd, void* buf, guint64 count);
+gint64 Mono_Posix_Syscall_writev (int fd, struct Mono_Posix_Iovec* iov, int iovcnt);
 int Mono_Posix_Syscall_WSTOPSIG (int status);
 int Mono_Posix_Syscall_WTERMSIG (int status);
 int Mono_Posix_ToStatvfs (void* source, struct Mono_Posix_Statvfs* destination);
index 952a46363dbb687052d045404063c46142ac4cd7..54d53086801464ef70e413d869a08febd325e57a 100644 (file)
@@ -70,6 +70,27 @@ Mono_Posix_Syscall_lstat (const char *file_name, struct Mono_Posix_Stat *buf)
        return r;
 }
 
+#ifdef HAVE_FSTATAT
+gint32
+Mono_Posix_Syscall_fstatat (gint32 dirfd, const char *file_name, struct Mono_Posix_Stat *buf, gint32 flags)
+{
+       int r;
+       struct stat _buf;
+
+       if (Mono_Posix_FromAtFlags (flags, &flags) == -1)
+               return -1;
+
+       if (buf == NULL) {
+               errno = EFAULT;
+               return -1;
+       }
+       r = fstatat (dirfd, file_name, &_buf, flags);
+       if (r != -1 && Mono_Posix_ToStat (&_buf, buf) == -1)
+               r = -1;
+       return r;
+}
+#endif
+
 gint32
 Mono_Posix_Syscall_mknod (const char *pathname, guint32 mode, mph_dev_t dev)
 {
@@ -78,8 +99,79 @@ Mono_Posix_Syscall_mknod (const char *pathname, guint32 mode, mph_dev_t dev)
        return mknod (pathname, mode, dev);
 }
 
+#ifdef HAVE_MKNODAT
+gint32
+Mono_Posix_Syscall_mknodat (int dirfd, const char *pathname, guint32 mode, mph_dev_t dev)
+{
+       if (Mono_Posix_FromFilePermissions (mode, &mode) == -1)
+               return -1;
+       return mknodat (dirfd, pathname, mode, dev);
+}
+#endif
+
 G_END_DECLS
 
+gint64
+Mono_Posix_Syscall_get_utime_now ()
+{
+#ifdef UTIME_NOW
+       return UTIME_NOW;
+#else
+       return -1;
+#endif
+}
+
+gint64
+Mono_Posix_Syscall_get_utime_omit ()
+{
+#ifdef UTIME_OMIT
+       return UTIME_OMIT;
+#else
+       return -1;
+#endif
+}
+
+static inline struct timespec*
+copy_utimens (struct timespec* to, struct Mono_Posix_Timespec *from)
+{
+       if (from) {
+               to[0].tv_sec  = from[0].tv_sec;
+               to[0].tv_nsec = from[0].tv_nsec;
+               to[1].tv_sec  = from[1].tv_sec;
+               to[1].tv_nsec = from[1].tv_nsec;
+               return to;
+       }
+
+       return NULL;
+}
+
+#ifdef HAVE_FUTIMENS
+gint32
+Mono_Posix_Syscall_futimens(int fd, struct Mono_Posix_Timespec *tv)
+{
+       struct timespec _tv[2];
+       struct timespec *ptv;
+
+       ptv = copy_utimens (_tv, tv);
+
+       return futimens (fd, ptv);
+}
+#endif /* def HAVE_FUTIMENS */
+
+#ifdef HAVE_UTIMENSAT
+gint32
+Mono_Posix_Syscall_utimensat(int dirfd, const char *pathname, struct Mono_Posix_Timespec *tv, int flags)
+{
+       struct timespec _tv[2];
+       struct timespec *ptv;
+
+       ptv = copy_utimens (_tv, tv);
+
+       return utimensat (dirfd, pathname, ptv, flags);
+}
+#endif /* def HAVE_UTIMENSAT */
+
+
 /*
  * vim: noexpandtab
  */
diff --git a/support/sys-uio.c b/support/sys-uio.c
new file mode 100644 (file)
index 0000000..f6b80e0
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * <sys/uio.h> wrapper functions.
+ *
+ * Authors:
+ *   Steffen Kiess (s-kiess@web.de)
+ *
+ * Copyright (C) 2012 Steffen Kiess
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif /* ndef _GNU_SOURCE */
+
+#include <sys/uio.h>
+
+#include "map.h"
+#include "mph.h"
+
+G_BEGIN_DECLS
+
+static struct iovec*
+from_iovec (struct Mono_Posix_Iovec *iov, gint32 iovcnt)
+{
+       struct iovec* v;
+       gint32 i;
+
+       if (iovcnt < 0) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       v = malloc (iovcnt * sizeof (struct iovec));
+       if (!v) {
+               return NULL;
+       }
+
+       for (i = 0; i < iovcnt; i++) {
+               if (Mono_Posix_FromIovec (&iov[i], &v[i]) != 0) {
+                       free (v);
+                       return NULL;
+               }
+       }
+
+       return v;
+}
+
+#ifdef HAVE_READV
+gint64
+Mono_Posix_Syscall_readv (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt)
+{
+       struct iovec* v;
+       gint64 res;
+
+       v = from_iovec (iov, iovcnt);
+       if (!v) {
+               return -1;
+       }
+
+       res = readv(dirfd, v, iovcnt);
+       free (v);
+       return res;
+}
+#endif /* def HAVE_READV */
+
+#ifdef HAVE_WRITEV
+gint64
+Mono_Posix_Syscall_writev (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt)
+{
+       struct iovec* v;
+       gint64 res;
+
+       v = from_iovec (iov, iovcnt);
+       if (!v) {
+               return -1;
+       }
+
+       res = writev (dirfd, v, iovcnt);
+       free (v);
+       return res;
+}
+#endif /* def HAVE_WRITEV */
+
+#ifdef HAVE_PREADV
+gint64
+Mono_Posix_Syscall_preadv (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt, gint64 off)
+{
+       struct iovec* v;
+       gint64 res;
+
+       mph_return_if_off_t_overflow (off);
+
+       v = from_iovec (iov, iovcnt);
+       if (!v) {
+               return -1;
+       }
+
+       res = preadv (dirfd, v, iovcnt, (off_t) off);
+       free (v);
+       return res;
+}
+#endif /* def HAVE_PREADV */
+
+#ifdef HAVE_PWRITEV
+gint64
+Mono_Posix_Syscall_pwritev (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt, gint64 off)
+{
+       struct iovec* v;
+       gint64 res;
+
+       mph_return_if_off_t_overflow (off);
+
+       v = from_iovec (iov, iovcnt);
+       if (!v) {
+               return -1;
+       }
+
+       res = pwritev (dirfd, v, iovcnt, (off_t) off);
+       free (v);
+       return res;
+}
+#endif /* def HAVE_PWRITEV */
+
+
+/*
+ * vim: noexpandtab
+ */
index 5652329e13ff78abe8ca97b54789c5ded2522e7e..da2750abe8a35758ca832e5cc760bbf06dac02ca 100644 (file)
@@ -147,6 +147,19 @@ Mono_Posix_Syscall_readlink (const char *path, char *buf, mph_size_t len)
        return r;
 }
 
+#ifdef HAVE_READLINKAT
+gint32
+Mono_Posix_Syscall_readlinkat (int dirfd, const char *path, char *buf, mph_size_t len)
+{
+       int r;
+       mph_return_if_size_t_overflow (len);
+       r = readlinkat (dirfd, path, buf, (size_t) len);
+       if (r >= 0 && r < len)
+               buf [r] = '\0';
+       return r;
+}
+#endif /* def HAVE_READLINKAT */
+
 #if HAVE_GETLOGIN_R
 gint32
 Mono_Posix_Syscall_getlogin_r (char *buf, mph_size_t len)