Line data Source code
1 : /* 2 : * Unix SMB/CIFS implementation. 3 : * Samba system utilities 4 : * Copyright (C) Andrew Tridgell 1992-1998 5 : * Copyright (C) Jeremy Allison 1998-2005 6 : * Copyright (C) Timur Bakeyev 2005 7 : * Copyright (C) Bjoern Jacke 2006-2007 8 : * 9 : * This program is free software; you can redistribute it and/or modify 10 : * it under the terms of the GNU General Public License as published by 11 : * the Free Software Foundation; either version 3 of the License, or 12 : * (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program. If not, see <http://www.gnu.org/licenses/>. 21 : */ 22 : 23 : #include "replace.h" 24 : #include "system/filesys.h" 25 : #include "lib/util/sys_rw_data.h" 26 : #include "lib/util/sys_rw.h" 27 : #include "lib/util/iov_buf.h" 28 : 29 : /**************************************************************************** 30 : Write all data from an iov array 31 : NB. This can be called with a non-socket fd, don't add dependencies 32 : on socket calls. 33 : ****************************************************************************/ 34 : 35 683560 : ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt) 36 683560 : { 37 7859 : ssize_t to_send; 38 7859 : ssize_t thistime; 39 7859 : size_t sent; 40 683560 : struct iovec iov_copy[iovcnt]; 41 7859 : struct iovec *iov; 42 : 43 683560 : to_send = iov_buflen(orig_iov, iovcnt); 44 683560 : if (to_send == -1) { 45 0 : errno = EINVAL; 46 0 : return -1; 47 : } 48 : 49 683560 : thistime = sys_writev(fd, orig_iov, iovcnt); 50 683560 : if ((thistime <= 0) || (thistime == to_send)) { 51 665632 : return thistime; 52 : } 53 10088 : sent = thistime; 54 : 55 : /* 56 : * We could not send everything in one call. Make a copy of iov that 57 : * we can mess with. 58 : */ 59 : 60 10088 : memcpy(iov_copy, orig_iov, sizeof(struct iovec) * iovcnt); 61 10088 : iov = iov_copy; 62 : 63 237370 : while (sent < (size_t)to_send) { 64 320 : bool ok; 65 : 66 227282 : ok = iov_advance(&iov, &iovcnt, thistime); 67 227282 : if (!ok) { 68 0 : errno = EIO; 69 0 : return -1; 70 : } 71 : 72 227282 : thistime = sys_writev(fd, iov, iovcnt); 73 227282 : if (thistime <= 0) { 74 0 : break; 75 : } 76 227282 : sent += thistime; 77 : } 78 : 79 10088 : return sent; 80 : } 81 : 82 : /**************************************************************************** 83 : Write data to a fd. 84 : NB. This can be called with a non-socket fd, don't add dependencies 85 : on socket calls. 86 : ****************************************************************************/ 87 : 88 683556 : ssize_t write_data(int fd, const void *buffer, size_t n) 89 : { 90 7859 : struct iovec iov; 91 : 92 683556 : iov.iov_base = discard_const_p(void, buffer); 93 683556 : iov.iov_len = n; 94 683556 : return write_data_iov(fd, &iov, 1); 95 : } 96 : 97 : /* 98 : * Blocking read n bytes from a fd 99 : */ 100 : 101 0 : ssize_t read_data(int fd, void *buffer, size_t n) 102 : { 103 0 : ssize_t nread; 104 : 105 0 : nread = 0; 106 : 107 0 : while ((size_t)nread < n) { 108 0 : ssize_t ret; 109 0 : ret = sys_read(fd, ((char *)buffer) + nread, n - nread); 110 0 : if (ret <= 0) { 111 0 : return ret; 112 : } 113 0 : nread += ret; 114 : } 115 : 116 0 : return nread; 117 : }