static struct iovec *lock_iovec(int type, abi_ulong target_addr,

                                int count, int copy)

{

    struct target_iovec *target_vec;

    struct iovec *vec;

    abi_ulong total_len, max_len;

    int i;

    int err = 0;



    if (count == 0) {

        errno = 0;

        return NULL;

    }

    if (count < 0 || count > IOV_MAX) {

        errno = EINVAL;

        return NULL;

    }



    vec = calloc(count, sizeof(struct iovec));

    if (vec == NULL) {

        errno = ENOMEM;

        return NULL;

    }



    target_vec = lock_user(VERIFY_READ, target_addr,

                           count * sizeof(struct target_iovec), 1);

    if (target_vec == NULL) {

        err = EFAULT;

        goto fail2;

    }



    



    max_len = 0x7fffffff & TARGET_PAGE_MASK;

    total_len = 0;



    for (i = 0; i < count; i++) {

        abi_ulong base = tswapal(target_vec[i].iov_base);

        abi_long len = tswapal(target_vec[i].iov_len);



        if (len < 0) {

            err = EINVAL;

            goto fail;

        } else if (len == 0) {

            

            vec[i].iov_base = 0;

        } else {

            vec[i].iov_base = lock_user(type, base, len, copy);

            if (!vec[i].iov_base) {

                err = EFAULT;

                goto fail;

            }

            if (len > max_len - total_len) {

                len = max_len - total_len;

            }

        }

        vec[i].iov_len = len;

        total_len += len;

    }



    unlock_user(target_vec, target_addr, 0);

    return vec;



 fail:

    unlock_user(target_vec, target_addr, 0);

 fail2:

    free(vec);

    errno = err;

    return NULL;

}
