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 19:22:17 +00:00
parent a81ce6e9d5
commit 21d23e3249
5 changed files with 92 additions and 9 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

@ -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

@ -241,6 +241,52 @@ linux_writev(struct thread *td, struct linux_writev_args *uap)
return (error);
}
int
linux_preadv(struct thread *td, struct linux_preadv_args *uap)
{
struct uio *auio;
int error;
off_t offset;
error = linux32_copyinuio((struct l_iovec32 *)uap->vec,
uap->vlen, &auio);
if (error)
return (error);
/*
* 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;
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;
error = linux32_copyinuio((struct l_iovec32 *)uap->vec,
uap->vlen, &auio);
if (error)
return (error);
/*
* 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;
error = kern_pwritev(td, uap->fd, auio, offset);
free(auio, M_IOV);
return (error);
}
struct l_ipc_kludge {
l_uintptr_t msgp;
l_long msgtyp;

View File

@ -1027,6 +1027,52 @@ linux_pwrite(struct thread *td, struct linux_pwrite_args *uap)
return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte, uap->offset));
}
#if !(defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_preadv(struct thread *td, struct linux_preadv_args *uap)
{
struct uio *auio;
int error;
off_t offset;
error = copyinuio(uap->vec, uap->vlen, &auio);
if (error)
return (error);
/*
* 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;
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;
error = copyinuio(uap->vec, uap->vlen, &auio);
if (error)
return (error);
/*
* 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;
error = kern_pwritev(td, uap->fd, auio, offset);
free(auio, M_IOV);
return (error);
}
#endif /* !(__amd64__ && COMPAT_LINUX32) */
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: */