1/*
2 * Copyright 2007-2008, Ingo Weinhold, bonefish@cs.tu-berlin.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "compatibility.h"
7
8#include "fssh_uio.h"
9
10#if defined(HAIKU_HOST_PLATFORM_FREEBSD)
11#include <unistd.h>
12#endif
13
14#include <new>
15
16#include <errno.h>
17#include <sys/uio.h>
18
19#include "partition_support.h"
20
21
22static const fssh_size_t kMaxIOVecs = 1024;
23
24
25bool
26prepare_iovecs(const struct fssh_iovec *vecs, fssh_size_t count,
27	struct iovec* systemVecs)
28{
29	if (count > kMaxIOVecs) {
30		errno = B_BAD_VALUE;
31		return false;
32	}
33
34	for (fssh_size_t i = 0; i < count; i++) {
35		systemVecs[i].iov_base = vecs[i].iov_base;
36		systemVecs[i].iov_len = vecs[i].iov_len;
37	}
38
39	return true;
40}
41
42
43fssh_ssize_t
44fssh_readv(int fd, const struct fssh_iovec *vector, fssh_size_t count)
45{
46	struct iovec systemVecs[kMaxIOVecs];
47	if (!prepare_iovecs(vector, count, systemVecs))
48		return -1;
49
50	fssh_off_t pos = -1;
51	fssh_size_t length = 0;
52	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
53		return -1;
54
55	#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
56		return readv(fd, systemVecs, count);
57	#else
58		return readv_pos(fd, lseek(fd, 0, SEEK_CUR), systemVecs, count);
59	#endif
60}
61
62
63fssh_ssize_t
64fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
65	fssh_size_t count)
66{
67	struct iovec systemVecs[kMaxIOVecs];
68	if (!prepare_iovecs(vec, count, systemVecs))
69		return -1;
70
71	fssh_size_t length = 0;
72	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
73		return -1;
74
75	return readv_pos(fd, pos, systemVecs, count);
76}
77
78
79fssh_ssize_t
80fssh_writev(int fd, const struct fssh_iovec *vector, fssh_size_t count)
81{
82	struct iovec systemVecs[kMaxIOVecs];
83	if (!prepare_iovecs(vector, count, systemVecs))
84		return -1;
85
86	fssh_off_t pos = -1;
87	fssh_size_t length = 0;
88	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
89		return -1;
90
91	#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
92		return writev(fd, systemVecs, count);
93	#else
94		return writev_pos(fd, lseek(fd, 0, SEEK_CUR), systemVecs, count);
95	#endif
96}
97
98
99fssh_ssize_t
100fssh_writev_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
101				fssh_size_t count)
102{
103	struct iovec systemVecs[kMaxIOVecs];
104	if (!prepare_iovecs(vec, count, systemVecs))
105		return -1;
106
107	fssh_size_t length = 0;
108	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
109		return -1;
110
111	return writev_pos(fd, pos, systemVecs, count);
112}
113