| /**************************************************************************** |
| * libs/libc/uio/lib_preadv.c |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <sys/types.h> |
| #include <sys/uio.h> |
| #include <unistd.h> |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: preadv() |
| * |
| * Description: |
| * The preadv() function is equivalent to pread(), except it takes |
| * an iov array. |
| * |
| ****************************************************************************/ |
| |
| ssize_t preadv(int fildes, FAR const struct iovec *iov, int iovcnt, |
| off_t offset) |
| { |
| ssize_t ntotal; |
| ssize_t nread; |
| size_t remaining; |
| FAR uint8_t *buffer; |
| int i; |
| |
| /* Process each entry in the struct iovec array */ |
| |
| for (i = 0, ntotal = 0; i < iovcnt; i++) |
| { |
| /* Ignore zero-length reads */ |
| |
| if (iov[i].iov_len > 0) |
| { |
| buffer = iov[i].iov_base; |
| remaining = iov[i].iov_len; |
| |
| /* Read repeatedly as necessary to fill buffer */ |
| |
| do |
| { |
| /* NOTE: pread() is a cancellation point */ |
| |
| nread = pread(fildes, buffer, remaining, offset + ntotal); |
| |
| /* Check for a read error */ |
| |
| if (nread < 0) |
| { |
| return nread; |
| } |
| |
| /* Check for an end-of-file condition */ |
| |
| else if (nread == 0) |
| { |
| return ntotal; |
| } |
| |
| /* Update pointers and counts in order to handle partial |
| * buffer reads. |
| */ |
| |
| buffer += nread; |
| remaining -= nread; |
| ntotal += nread; |
| } |
| while (remaining > 0); |
| } |
| } |
| |
| return ntotal; |
| } |