summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2013-08-15 07:54:31 +0000
committerglebius <glebius@FreeBSD.org>2013-08-15 07:54:31 +0000
commit722a1a5e5d54a4935a4136368f443f6c88ca0d71 (patch)
tree72f140bc20e3f03e8744a0112282734ba89f474b /sys/compat
parent8c7687b41c874820110a7106c1167f5b0e3fc7d0 (diff)
downloadFreeBSD-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.c26
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);
OpenPOWER on IntegriCloud