diff options
author | glebius <glebius@FreeBSD.org> | 2013-08-15 07:54:31 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2013-08-15 07:54:31 +0000 |
commit | 722a1a5e5d54a4935a4136368f443f6c88ca0d71 (patch) | |
tree | 72f140bc20e3f03e8744a0112282734ba89f474b /sys/compat | |
parent | 8c7687b41c874820110a7106c1167f5b0e3fc7d0 (diff) | |
download | FreeBSD-src-722a1a5e5d54a4935a4136368f443f6c88ca0d71.zip FreeBSD-src-722a1a5e5d54a4935a4136368f443f6c88ca0d71.tar.gz |
Make sendfile() a method in the struct fileops. Currently only
vnode backed file descriptors have this method implemented.
Reviewed by: kib
Sponsored by: Nginx, Inc.
Sponsored by: Netflix
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 4899e03..51175aa 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/bus.h> +#include <sys/capability.h> #include <sys/clock.h> #include <sys/exec.h> #include <sys/fcntl.h> @@ -1653,22 +1654,19 @@ static int freebsd32_do_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap, int compat) { - struct sendfile_args ap; struct sf_hdtr32 hdtr32; struct sf_hdtr hdtr; struct uio *hdr_uio, *trl_uio; struct iovec32 *iov32; + struct file *fp; + off_t offset; int error; - hdr_uio = trl_uio = NULL; + offset = PAIR32TO64(off_t, uap->offset); + if (offset < 0) + return (EINVAL); - ap.fd = uap->fd; - ap.s = uap->s; - ap.offset = PAIR32TO64(off_t,uap->offset); - ap.nbytes = uap->nbytes; - ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */ - ap.sbytes = uap->sbytes; - ap.flags = uap->flags; + hdr_uio = trl_uio = NULL; if (uap->hdtr != NULL) { error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); @@ -1695,7 +1693,15 @@ freebsd32_do_sendfile(struct thread *td, } } - error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat); + AUDIT_ARG_FD(uap->fd); + + if ((error = fget_read(td, uap->fd, CAP_PREAD, &fp)) != 0) + goto out; + + error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, + uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); + fdrop(fp, td); + out: if (hdr_uio) free(hdr_uio, M_IOV); |