1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "sys/sendfile.h" 18 19 #include <errno.h> 20 #include <unistd.h> 21 22 namespace { 23 // This value is arbitrarily chosen. 24 constexpr size_t kBufSize = 4096; 25 } // namespace 26 27 // TODO(ZX-429): This is a painfully simple sendfile implementation that does 28 // not attempt to optimize for anything and is only provided as something that "works". 29 ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) { 30 // We don't support seek() for now. 31 if (offset != nullptr) { 32 errno = ESPIPE; 33 return -1; 34 } 35 36 size_t total = 0; 37 unsigned char buffer[kBufSize]; 38 while(count > 0) { 39 int bytes = read(in_fd, buffer, sizeof(buffer)); 40 if (bytes == 0) { 41 break; 42 } 43 44 if (bytes < 0) { 45 return bytes; 46 } 47 48 count -= bytes; 49 50 unsigned char *data = buffer; 51 while(bytes > 0) { 52 int written = write(out_fd, data, bytes); 53 if (written < 0) { 54 return written; 55 } 56 57 58 bytes -= written; 59 data += written; 60 total += written; 61 } 62 } 63 64 return total; 65 } 66