if (unlikely(buf == NULL)) return (ssize_t)ERR_INVALID_ARGS;
/* for each iov entry */ for (uint i = 0; i < iov_cnt; i++) { /* copy user iovec from user space into local buffer */
ret = copy_from_user(&uiov, iov_uaddr + i * sizeof(struct iovec_user), sizeof(struct iovec_user)); if (unlikely(ret != NO_ERROR)) return (ssize_t)ret;
if (unlikely(buf == NULL)) return (ssize_t)ERR_INVALID_ARGS;
while (buf_len > 0 && iovec_iter_has_next(iter)) { /* copy user iovec from user space into local buffer */
ret = copy_from_user(
&uiov, iov_uaddr + iter->iov_index * sizeof(struct iovec_user), sizeof(struct iovec_user)); if (unlikely(ret != NO_ERROR)) return (ssize_t)ret;
/* we've re-read the iov from userspace, it may have changed */ if (uiov.iov_len < iter->data_offset) return (ssize_t)ERR_INVALID_ARGS;
/* figure out how much to copy */
size_t to_copy = uiov.iov_len - iter->data_offset; if (to_copy > buf_len)
to_copy = buf_len;
/* copy data from user space */
ret = copy_from_user(buf, uiov.iov_base + iter->data_offset, to_copy); if (unlikely(ret != NO_ERROR)) return (ssize_t)ret;
/* update the input state */
iter->data_offset += to_copy; if (iter->data_offset >= uiov.iov_len) {
iter->iov_index += 1;
iter->data_offset = 0;
}
/* update the output state */
copied += to_copy;
buf += to_copy;
buf_len -= to_copy;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.