Add linux_preadv() and linux_pwritev() syscalls to Linuxulator.

Reviewed by:	dchagin
Approved by:	dchagin, trasz (src committers)
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D9722
This commit is contained in:
Mahdi Mokhtari 2017-02-24 20:04:02 +00:00
parent 8665c4d9cd
commit bd911530b7
6 changed files with 60 additions and 10 deletions

View File

@ -110,9 +110,6 @@ DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
DUMMY(inotify_init1);
/* linux 2.6.30: */
DUMMY(preadv);
DUMMY(pwritev);
/* linux 2.6.31: */
DUMMY(perf_event_open);
/* linux 2.6.38: */

View File

@ -663,6 +663,7 @@ struct l_user_desc {
(((desc)->b >> LINUX_ENTRY_B_USEABLE) & 1)
struct iovec;
struct uio;
struct l_iovec32 {
uint32_t iov_base;
@ -671,6 +672,8 @@ struct l_iovec32 {
int linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt,
struct iovec **iovp, int error);
int linux32_copyinuio(struct l_iovec32 *iovp, l_ulong iovcnt,
struct uio **uiop);
int linux_copyout_rusage(struct rusage *ru, void *uaddr);
/* robust futexes */

View File

@ -110,9 +110,6 @@ DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
DUMMY(inotify_init1);
/* linux 2.6.30: */
DUMMY(preadv);
DUMMY(pwritev);
/* linux 2.6.31: */
DUMMY(perf_event_open);
/* linux 2.6.33: */

View File

@ -144,7 +144,7 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
CTASSERT(sizeof(struct l_iovec32) == 8);
static int
int
linux32_copyinuio(struct l_iovec32 *iovp, l_ulong iovcnt, struct uio **uiop)
{
struct l_iovec32 iov32;

View File

@ -1027,6 +1027,62 @@ linux_pwrite(struct thread *td, struct linux_pwrite_args *uap)
return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte, uap->offset));
}
int
linux_preadv(struct thread *td, struct linux_preadv_args *uap)
{
struct uio *auio;
int error;
off_t offset;
/*
* According http://man7.org/linux/man-pages/man2/preadv.2.html#NOTES
* pos_l and pos_h, respectively, contain the
* low order and high order 32 bits of offset.
*/
offset = (((off_t)uap->pos_h << (sizeof(offset) * 4)) <<
(sizeof(offset) * 4)) | uap->pos_l;
if (offset < 0)
return (EINVAL);
#ifdef COMPAT_LINUX32
error = linux32_copyinuio(PTRIN(uap->vec), uap->vlen, &auio);
#else
error = copyinuio(uap->vec, uap->vlen, &auio);
#endif
if (error != 0)
return (error);
error = kern_preadv(td, uap->fd, auio, offset);
free(auio, M_IOV);
return (error);
}
int
linux_pwritev(struct thread *td, struct linux_pwritev_args *uap)
{
struct uio *auio;
int error;
off_t offset;
/*
* According http://man7.org/linux/man-pages/man2/pwritev.2.html#NOTES
* pos_l and pos_h, respectively, contain the
* low order and high order 32 bits of offset.
*/
offset = (((off_t)uap->pos_h << (sizeof(offset) * 4)) <<
(sizeof(offset) * 4)) | uap->pos_l;
if (offset < 0)
return (EINVAL);
#ifdef COMPAT_LINUX32
error = linux32_copyinuio(PTRIN(uap->vec), uap->vlen, &auio);
#else
error = copyinuio(uap->vec, uap->vlen, &auio);
#endif
if (error != 0)
return (error);
error = kern_pwritev(td, uap->fd, auio, offset);
free(auio, M_IOV);
return (error);
}
int
linux_mount(struct thread *td, struct linux_mount_args *args)
{

View File

@ -106,9 +106,6 @@ DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
DUMMY(inotify_init1);
/* linux 2.6.30: */
DUMMY(preadv);
DUMMY(pwritev);
/* linux 2.6.31: */
DUMMY(perf_event_open);
/* linux 2.6.33: */