xref: /haiku/src/tools/fs_shell/uio.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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 #if (!defined(__BEOS__) && !defined(__HAIKU__))
22 	// Defined in libroot_build.so.
23 #	define _kern_readv	_kernbuild_readv
24 #	define _kern_writev	_kernbuild_writev
25 	extern "C" ssize_t _kern_readv(int fd, off_t pos, const struct iovec *vecs, size_t count);
26 	extern "C" ssize_t _kern_writev(int fd, off_t pos, const struct iovec *vecs, size_t count);
27 #endif
28 
29 
30 static const int kMaxIOVecs = 1024;
31 
32 
33 bool
34 prepare_iovecs(const struct fssh_iovec *vecs, int count,
35 	struct iovec* systemVecs)
36 {
37 	if (count < 0 || count > kMaxIOVecs) {
38 		errno = B_BAD_VALUE;
39 		return false;
40 	}
41 
42 	for (int i = 0; i < count; i++) {
43 		systemVecs[i].iov_base = vecs[i].iov_base;
44 		systemVecs[i].iov_len = vecs[i].iov_len;
45 	}
46 
47 	return true;
48 }
49 
50 
51 fssh_ssize_t
52 fssh_readv(int fd, const struct fssh_iovec *vector, int count)
53 {
54 	struct iovec systemVecs[kMaxIOVecs];
55 	if (!prepare_iovecs(vector, count, systemVecs))
56 		return -1;
57 
58 	fssh_off_t pos = -1;
59 	fssh_size_t length = 0;
60 	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
61 		return -1;
62 
63 	#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
64 		return readv(fd, systemVecs, count);
65 	#else
66 		return _kern_readv(fd, lseek(fd, 0, SEEK_CUR), systemVecs, count);
67 	#endif
68 }
69 
70 
71 fssh_ssize_t
72 fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec, int count)
73 {
74 	struct iovec systemVecs[kMaxIOVecs];
75 	if (!prepare_iovecs(vec, count, systemVecs))
76 		return -1;
77 
78 	fssh_size_t length = 0;
79 	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
80 		return -1;
81 
82 #if defined(__HAIKU__)
83 	return readv_pos(fd, pos, systemVecs, count);
84 #else
85 	return _kern_readv(fd, pos, systemVecs, count);
86 #endif
87 }
88 
89 
90 fssh_ssize_t
91 fssh_writev(int fd, const struct fssh_iovec *vector, int count)
92 {
93 	struct iovec systemVecs[kMaxIOVecs];
94 	if (!prepare_iovecs(vector, count, systemVecs))
95 		return -1;
96 
97 	fssh_off_t pos = -1;
98 	fssh_size_t length = 0;
99 	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
100 		return -1;
101 
102 	#if !defined(HAIKU_HOST_PLATFORM_FREEBSD)
103 		return writev(fd, systemVecs, count);
104 	#else
105 		return _kern_writev(fd, lseek(fd, 0, SEEK_CUR), systemVecs, count);
106 	#endif
107 }
108 
109 
110 fssh_ssize_t
111 fssh_writev_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec, int count)
112 {
113 	struct iovec systemVecs[kMaxIOVecs];
114 	if (!prepare_iovecs(vec, count, systemVecs))
115 		return -1;
116 
117 	fssh_size_t length = 0;
118 	if (FSShell::restricted_file_restrict_io(fd, pos, length) < 0)
119 		return -1;
120 
121 #if defined(__HAIKU__)
122 	return writev_pos(fd, pos, systemVecs, count);
123 #else
124 	return _kern_writev(fd, pos, systemVecs, count);
125 #endif
126 }
127