Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteffen Kieß <s-kiess@web.de>2013-03-27 00:26:09 +0400
committerSteffen Kieß <s-kiess@web.de>2013-03-27 00:26:09 +0400
commit5329fab38b640727b78a6e09b53900801bf47347 (patch)
treedc241f84212224b7d326f5dc89b4d531ec746ae6 /support
parent6ceccd8cd264e92a956a4375e13170cbcc7191e9 (diff)
Add various methods and flags to Syscall
* 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
Diffstat (limited to 'support')
-rw-r--r--support/Makefile.am1
-rw-r--r--support/fcntl.c10
-rw-r--r--support/map.c118
-rw-r--r--support/map.h44
-rw-r--r--support/sys-stat.c92
-rw-r--r--support/sys-uio.c126
-rw-r--r--support/unistd.c13
7 files changed, 404 insertions, 0 deletions
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/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)