Merge pull request #221 from steffen-kiess/master
[mono.git] / support / sys-uio.c
1 /*
2  * <sys/uio.h> wrapper functions.
3  *
4  * Authors:
5  *   Steffen Kiess (s-kiess@web.de)
6  *
7  * Copyright (C) 2012 Steffen Kiess
8  */
9
10 #ifndef _GNU_SOURCE
11 #define _GNU_SOURCE
12 #endif /* ndef _GNU_SOURCE */
13
14 #include <sys/uio.h>
15
16 #include "map.h"
17 #include "mph.h"
18
19 G_BEGIN_DECLS
20
21 static struct iovec*
22 from_iovec (struct Mono_Posix_Iovec *iov, gint32 iovcnt)
23 {
24         struct iovec* v;
25         gint32 i;
26
27         if (iovcnt < 0) {
28                 errno = EINVAL;
29                 return NULL;
30         }
31
32         v = malloc (iovcnt * sizeof (struct iovec));
33         if (!v) {
34                 return NULL;
35         }
36
37         for (i = 0; i < iovcnt; i++) {
38                 if (Mono_Posix_FromIovec (&iov[i], &v[i]) != 0) {
39                         free (v);
40                         return NULL;
41                 }
42         }
43
44         return v;
45 }
46
47 #ifdef HAVE_READV
48 gint64
49 Mono_Posix_Syscall_readv (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt)
50 {
51         struct iovec* v;
52         gint64 res;
53
54         v = from_iovec (iov, iovcnt);
55         if (!v) {
56                 return -1;
57         }
58
59         res = readv(dirfd, v, iovcnt);
60         free (v);
61         return res;
62 }
63 #endif /* def HAVE_READV */
64
65 #ifdef HAVE_WRITEV
66 gint64
67 Mono_Posix_Syscall_writev (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt)
68 {
69         struct iovec* v;
70         gint64 res;
71
72         v = from_iovec (iov, iovcnt);
73         if (!v) {
74                 return -1;
75         }
76
77         res = writev (dirfd, v, iovcnt);
78         free (v);
79         return res;
80 }
81 #endif /* def HAVE_WRITEV */
82
83 #ifdef HAVE_PREADV
84 gint64
85 Mono_Posix_Syscall_preadv (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt, gint64 off)
86 {
87         struct iovec* v;
88         gint64 res;
89
90         mph_return_if_off_t_overflow (off);
91
92         v = from_iovec (iov, iovcnt);
93         if (!v) {
94                 return -1;
95         }
96
97         res = preadv (dirfd, v, iovcnt, (off_t) off);
98         free (v);
99         return res;
100 }
101 #endif /* def HAVE_PREADV */
102
103 #ifdef HAVE_PWRITEV
104 gint64
105 Mono_Posix_Syscall_pwritev (int dirfd, struct Mono_Posix_Iovec *iov, gint32 iovcnt, gint64 off)
106 {
107         struct iovec* v;
108         gint64 res;
109
110         mph_return_if_off_t_overflow (off);
111
112         v = from_iovec (iov, iovcnt);
113         if (!v) {
114                 return -1;
115         }
116
117         res = pwritev (dirfd, v, iovcnt, (off_t) off);
118         free (v);
119         return res;
120 }
121 #endif /* def HAVE_PWRITEV */
122
123
124 /*
125  * vim: noexpandtab
126  */