summaryrefslogtreecommitdiff
path: root/support/sys-uio.c
blob: f6b80e0d740ad70b0c2d6b937ed634fb3835718d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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
 */