diff options
author | Jonathan Pryor <jonp@xamarin.com> | 2013-03-27 01:42:30 +0400 |
---|---|---|
committer | Jonathan Pryor <jonp@xamarin.com> | 2013-03-27 01:42:30 +0400 |
commit | f3b1d7e5eba21eca5b6a2f857f3405ab2182015a (patch) | |
tree | 3862437105bf36b7a3fb890f835d437520a8ee9d | |
parent | f85afc4d5534b94373866507e0f8af61fd83c5c1 (diff) | |
parent | 5329fab38b640727b78a6e09b53900801bf47347 (diff) |
Merge pull request #221 from steffen-kiess/master
Add various methods and flags to Syscall
-rw-r--r-- | configure.in | 5 | ||||
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs | 48 | ||||
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs | 287 | ||||
-rw-r--r-- | support/Makefile.am | 1 | ||||
-rw-r--r-- | support/dirent.c | 1 | ||||
-rw-r--r-- | support/fcntl.c | 10 | ||||
-rw-r--r-- | support/map.c | 118 | ||||
-rw-r--r-- | support/map.h | 44 | ||||
-rw-r--r-- | support/sys-stat.c | 92 | ||||
-rw-r--r-- | support/sys-uio.c | 126 | ||||
-rw-r--r-- | support/unistd.c | 13 |
11 files changed, 744 insertions, 1 deletions
diff --git a/configure.in b/configure.in index 099c56eecf1..c32d35fc442 100644 --- a/configure.in +++ b/configure.in @@ -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)], , diff --git a/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs b/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs index be846a892c1..e5e41cc3b0c 100644 --- a/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs +++ b/mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.generated.cs @@ -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); diff --git a/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs b/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs index e5ef6c7a93b..083fb6c4093 100644 --- a/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs +++ b/mcs/class/Mono.Posix/Mono.Unix.Native/Syscall.cs @@ -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 diff --git a/support/Makefile.am b/support/Makefile.am index 1de8fc77cb7..0ae77e769b9 100644 --- a/support/Makefile.am +++ b/support/Makefile.am @@ -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 \ diff --git a/support/dirent.c b/support/dirent.c index 939d915d949..bc1b3e238e1 100644 --- a/support/dirent.c +++ b/support/dirent.c @@ -78,6 +78,7 @@ Mono_Posix_Syscall_readdir (void *dirp, struct Mono_Posix_Syscall__Dirent *entry return -1; } + errno = 0; d = readdir (dirp); if (d == NULL) { diff --git a/support/fcntl.c b/support/fcntl.c index 013d9cd4167..12947991c00 100644 --- a/support/fcntl.c +++ b/support/fcntl.c @@ -101,6 +101,16 @@ Mono_Posix_Syscall_open_mode (const char *pathname, gint32 flags, guint32 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) { if (Mono_Posix_FromFilePermissions (mode, &mode) == -1) diff --git a/support/map.c b/support/map.c index cb653bcda9a..2150cb29bbb 100644 --- a/support/map.c +++ b/support/map.c @@ -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; diff --git a/support/map.h b/support/map.h index aab06b7b9cd..77d75db3ad4 100644 --- a/support/map.h +++ b/support/map.h @@ -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); diff --git a/support/sys-stat.c b/support/sys-stat.c index 952a46363db..54d53086801 100644 --- a/support/sys-stat.c +++ b/support/sys-stat.c @@ -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 index 00000000000..f6b80e0d740 --- /dev/null +++ b/support/sys-uio.c @@ -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 + */ diff --git a/support/unistd.c b/support/unistd.c index 5652329e13f..da2750abe8a 100644 --- a/support/unistd.c +++ b/support/unistd.c @@ -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) |