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