Commit b70ba7e2 authored by Philippe Gerum's avatar Philippe Gerum
Browse files

net/iovec: add copy iterators for iovec[]

parent 7db2935b
......@@ -25,6 +25,8 @@
#include <linux/uio.h>
struct user_msghdr;
struct rtdm_fd;
/***
* rt_iovec_len
......@@ -44,7 +46,13 @@ static inline size_t rt_iovec_len(const struct iovec *iov, int iovlen)
extern void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len);
extern void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov, int len);
ssize_t rtnet_write_to_iov(struct rtdm_fd *fd,
struct iovec *iov, int iovlen,
const void *data, size_t len);
ssize_t rtnet_read_from_iov(struct rtdm_fd *fd,
struct iovec *iov, int iovlen,
void *data, size_t len);
#endif /* __KERNEL__ */
#endif /* __RTNET_IOVEC_H_ */
......@@ -25,8 +25,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <rtdm/driver.h>
#include <rtnet_iovec.h>
#include <rtnet_socket.h>
/***
......@@ -49,6 +50,7 @@ void rt_memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len)
iov++;
}
}
EXPORT_SYMBOL_GPL(rt_memcpy_tokerneliovec);
/***
......@@ -71,7 +73,78 @@ void rt_memcpy_fromkerneliovec(unsigned char *kdata, struct iovec *iov,int len)
iov++;
}
}
EXPORT_SYMBOL_GPL(rt_memcpy_fromkerneliovec);
ssize_t rtnet_write_to_iov(struct rtdm_fd *fd,
struct iovec *iov, int iovlen,
const void *data, size_t len)
{
ssize_t ret = 0;
size_t nbytes;
int n;
EXPORT_SYMBOL_GPL(rt_memcpy_tokerneliovec);
EXPORT_SYMBOL_GPL(rt_memcpy_fromkerneliovec);
for (n = 0; len > 0 && n < iovlen; n++, iov++) {
if (iov->iov_len == 0)
continue;
nbytes = iov->iov_len;
if (nbytes > len)
nbytes = len;
ret = rtnet_put_arg(fd, iov->iov_base, data, nbytes);
if (ret)
break;
len -= nbytes;
data += nbytes;
iov->iov_len -= nbytes;
iov->iov_base += nbytes;
ret += nbytes;
if (ret < 0) {
ret = -EINVAL;
break;
}
}
return ret;
}
EXPORT_SYMBOL_GPL(rtnet_write_to_iov);
ssize_t rtnet_read_from_iov(struct rtdm_fd *fd,
struct iovec *iov, int iovlen,
void *data, size_t len)
{
ssize_t ret = 0;
size_t nbytes;
int n;
for (n = 0; len > 0 && n < iovlen; n++, iov++) {
if (iov->iov_len == 0)
continue;
nbytes = iov->iov_len;
if (nbytes > len)
nbytes = len;
if (!rtdm_fd_is_user(fd))
memcpy(data, iov->iov_base, nbytes);
else {
ret = rtdm_copy_from_user(fd, data, iov->iov_base, nbytes);
if (ret)
break;
}
len -= nbytes;
data += nbytes;
iov->iov_len -= nbytes;
iov->iov_base += nbytes;
ret += nbytes;
if (ret < 0) {
ret = -EINVAL;
break;
}
}
return ret;
}
EXPORT_SYMBOL_GPL(rtnet_read_from_iov);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment