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 30static const int kMaxIOVecs = 1024; 31 32 33bool 34prepare_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 51fssh_ssize_t 52fssh_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 71fssh_ssize_t 72fssh_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 90fssh_ssize_t 91fssh_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 110fssh_ssize_t 111fssh_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