linux(4): Add a dedicated writev syscall wrapper
Adding a writev syscall wrapper is needed due to Linux family of write syscalls doesn't distinguish between in kernel blocking operations and always returns EAGAIN while FreeBSD can return ENOBUFS. MFC after: 1 month
This commit is contained in:
parent
1f9d71ee32
commit
4231b825ac
@ -196,20 +196,6 @@ linux_readv(struct thread *td, struct linux_readv_args *uap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
linux_writev(struct thread *td, struct linux_writev_args *uap)
|
||||
{
|
||||
struct uio *auio;
|
||||
int error;
|
||||
|
||||
error = linux32_copyinuio(uap->iovp, uap->iovcnt, &auio);
|
||||
if (error)
|
||||
return (error);
|
||||
error = kern_writev(td, uap->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct l_ipc_kludge {
|
||||
l_uintptr_t msgp;
|
||||
l_long msgtyp;
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
#ifdef COMPAT_LINUX32
|
||||
#include <compat/freebsd32/freebsd32_misc.h>
|
||||
#include <compat/freebsd32/freebsd32_util.h>
|
||||
#include <machine/../linux32/linux.h>
|
||||
#include <machine/../linux32/linux32_proto.h>
|
||||
#else
|
||||
@ -1855,3 +1856,21 @@ linux_write(struct thread *td, struct linux_write_args *args)
|
||||
|
||||
return (linux_enobufs2eagain(td, args->fd, sys_write(td, &bargs)));
|
||||
}
|
||||
|
||||
int
|
||||
linux_writev(struct thread *td, struct linux_writev_args *args)
|
||||
{
|
||||
struct uio *auio;
|
||||
int error;
|
||||
|
||||
#ifdef COMPAT_LINUX32
|
||||
error = freebsd32_copyinuio(PTRIN(args->iovp), args->iovcnt, &auio);
|
||||
#else
|
||||
error = copyinuio(args->iovp, args->iovcnt, &auio);
|
||||
#endif
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_writev(td, args->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
return (linux_enobufs2eagain(td, args->fd, error));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user