diff options
| author | Adrian Chadd <adrian@FreeBSD.org> | 2014-01-17 05:26:55 +0000 |
|---|---|---|
| committer | Adrian Chadd <adrian@FreeBSD.org> | 2014-01-17 05:26:55 +0000 |
| commit | 0cfea1c8fc539d70dc0d8333cf6e42db06cc752a (patch) | |
| tree | 2ee74af347fde330acc3a30d52e45c03ba9e066e /sys/compat | |
| parent | fda21f4d2a65e8ab6bee3d8af5c063c0865ffc0b (diff) | |
Notes
Diffstat (limited to 'sys/compat')
| -rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index c8681c6e3f8b..719a0573cb5d 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1644,18 +1644,28 @@ struct sf_hdtr32 { int trl_cnt; }; +struct sf_hdtr_kq32 { + int kq_fd; + uint32_t kq_flags; + uint32_t kq_udata; /* 32-bit void ptr */ + uint32_t kq_ident; /* 32-bit uintptr_t */ +}; + static int freebsd32_do_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap, int compat) { struct sf_hdtr32 hdtr32; struct sf_hdtr hdtr; + struct sf_hdtr_kq32 hdtr_kq32; + struct sf_hdtr_kq hdtr_kq; struct uio *hdr_uio, *trl_uio; struct iovec32 *iov32; off_t offset; int error; off_t sbytes; struct sendfile_sync *sfs; + int do_kqueue = 0; offset = PAIR32TO64(off_t, uap->offset); if (offset < 0) @@ -1687,10 +1697,32 @@ freebsd32_do_sendfile(struct thread *td, if (error) goto out; } + + /* + * If SF_KQUEUE is set, then we need to also copy in + * the kqueue data after the normal hdtr set and set do_kqueue=1. + */ + if (uap->flags & SF_KQUEUE) { + error = copyin(((char *) uap->hdtr) + sizeof(hdtr32), + &hdtr_kq32, + sizeof(hdtr_kq32)); + if (error != 0) + goto out; + + /* 32->64 bit fields */ + CP(hdtr_kq32, hdtr_kq, kq_fd); + CP(hdtr_kq32, hdtr_kq, kq_flags); + PTRIN_CP(hdtr_kq32, hdtr_kq, kq_udata); + CP(hdtr_kq32, hdtr_kq, kq_ident); + do_kqueue = 1; + } } + + /* Call sendfile */ + /* XXX stack depth! */ error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat, - offset, uap->nbytes, &sbytes, hdr_uio, trl_uio); + offset, uap->nbytes, &sbytes, hdr_uio, trl_uio, &hdtr_kq); if (uap->sbytes != NULL) copyout(&sbytes, uap->sbytes, sizeof(off_t)); |
