Page MenuHomeFreeBSD

D59198.diff
No OneTemporary

D59198.diff

diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2215,6 +2215,25 @@
}
#ifdef COMPAT_FREEBSD4
+static int
+freebsd4_freebsd32_sendfile_copyin_hd_uio(size_t *nbytes, void *headers,
+ int hdr_cnt, struct uio **uiopp)
+{
+ int error;
+
+ error = freebsd32_copyinuio(headers, hdr_cnt, uiopp);
+ if (error != 0)
+ return (error);
+
+ /* In FreeBSD < 5.0 the nbytes to send also included the header. */
+ if (*nbytes > (*uiopp)->uio_resid)
+ *nbytes -= (*uiopp)->uio_resid;
+ else
+ *nbytes = 0;
+
+ return (error);
+}
+
int
freebsd4_freebsd32_sendfile(struct thread *td,
struct freebsd4_freebsd32_sendfile_args *uap)
@@ -2227,11 +2246,20 @@
.hdtr = (struct sf_hdtr *)uap->hdtr,
.sbytes = uap->sbytes,
.flags = uap->flags,
- }, true, freebsd32_copyin_hdtr,
- (copyinuio_t *)freebsd32_copyinuio));
+ },
+ freebsd32_copyin_hdtr,
+ (copyinuio_t *)freebsd32_copyinuio,
+ freebsd4_freebsd32_sendfile_copyin_hd_uio));
}
#endif
+static int
+freebsd32_sendfile_copyin_hd_uio(size_t *nbytes __unused,
+ void *headers, int hdr_cnt, struct uio **uiopp)
+{
+ return (freebsd32_copyinuio(headers, hdr_cnt, uiopp));
+}
+
int
freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
{
@@ -2243,8 +2271,10 @@
.hdtr = (struct sf_hdtr *)uap->hdtr,
.sbytes = uap->sbytes,
.flags = uap->flags,
- }, false, freebsd32_copyin_hdtr,
- (copyinuio_t *)freebsd32_copyinuio));
+ },
+ freebsd32_copyin_hdtr,
+ (copyinuio_t *)freebsd32_copyinuio,
+ freebsd32_sendfile_copyin_hd_uio));
}
static void
diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
--- a/sys/kern/kern_sendfile.c
+++ b/sys/kern/kern_sendfile.c
@@ -1215,8 +1215,9 @@
}
int
-kern_sendfile(struct thread *td, struct sendfile_args *uap, bool compat,
- copyin_hdtr_t *copyin_hdtr_f, copyinuio_t *copyinuio_f)
+kern_sendfile(struct thread *td, struct sendfile_args *uap,
+ copyin_hdtr_t *copyin_hdtr_f, copyinuio_t *copyinuio_f,
+ sendfile_copyin_hd_uio_t *copyin_hd_uio_f)
{
struct sf_hdtr hdtr;
struct uio *hdr_uio, *trl_uio;
@@ -1239,23 +1240,10 @@
if (error != 0)
goto out;
if (hdtr.headers != NULL) {
- error = copyinuio_f(hdtr.headers, hdtr.hdr_cnt,
- &hdr_uio);
+ error = copyin_hd_uio_f(&uap->nbytes,
+ hdtr.headers, hdtr.hdr_cnt, &hdr_uio);
if (error != 0)
goto out;
-#ifdef COMPAT_FREEBSD4
- /*
- * In FreeBSD < 5.0 the nbytes to send also included
- * the header. If compat is specified subtract the
- * header size from nbytes.
- */
- if (compat) {
- if (uap->nbytes > hdr_uio->uio_resid)
- uap->nbytes -= hdr_uio->uio_resid;
- else
- uap->nbytes = 0;
- }
-#endif
}
if (hdtr.trailers != NULL) {
error = copyinuio_f(hdtr.trailers, hdtr.trl_cnt,
@@ -1289,6 +1277,13 @@
return (error);
}
+static int
+sendfile_copyin_hd_uio(size_t *nbytes __unused,
+ void *headers, int hdr_cnt, struct uio **uiopp)
+{
+ return (copyinuio(headers, hdr_cnt, uiopp));
+}
+
/*
* sendfile(2)
*
@@ -1303,12 +1298,30 @@
int
sys_sendfile(struct thread *td, struct sendfile_args *uap)
{
-
- return (kern_sendfile(td, uap, false, (copyin_hdtr_t *)copyin_hdtr,
- (copyinuio_t *)copyinuio));
+ return (kern_sendfile(td, uap, (copyin_hdtr_t *)copyin_hdtr,
+ (copyinuio_t *)copyinuio, sendfile_copyin_hd_uio));
}
#ifdef COMPAT_FREEBSD4
+static int
+freebsd4_sendfile_copyin_hd_uio(size_t *nbytes,
+ void *headers, int hdr_cnt, struct uio **uiopp)
+{
+ int error;
+
+ error = copyinuio(headers, hdr_cnt, uiopp);
+ if (error != 0)
+ return (error);
+
+ /* In FreeBSD < 5.0 the nbytes to send also included the header. */
+ if (*nbytes > (*uiopp)->uio_resid)
+ *nbytes -= (*uiopp)->uio_resid;
+ else
+ *nbytes = 0;
+
+ return (error);
+}
+
int
freebsd4_sendfile(struct thread *td, struct freebsd4_sendfile_args *uap)
{
@@ -1320,6 +1333,9 @@
.hdtr = uap->hdtr,
.sbytes = uap->sbytes,
.flags = uap->flags,
- }, true, (copyin_hdtr_t *)copyin_hdtr, (copyinuio_t *)copyinuio));
+ },
+ (copyin_hdtr_t *)copyin_hdtr,
+ (copyinuio_t *)copyinuio,
+ freebsd4_sendfile_copyin_hd_uio));
}
#endif /* COMPAT_FREEBSD4 */
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -89,6 +89,13 @@
*/
typedef int (copyin_hdtr_t)(const void *hdtrp, struct sf_hdtr *hdtr);
+/*
+ * A sendfile_copyin_hd_uio_t wraps copyinuio and optionally adjusts
+ * nbytes when compatibility requires.
+ */
+typedef int (sendfile_copyin_hd_uio_t)(size_t *nbytes,
+ void *headers, int hdr_cnt, struct uio **iov);
+
/*
* A copyinuio_t takes a pointer to an iovec in userspace along with a
* count and allocates a struct uio containing a copy of the iovec.
@@ -349,8 +356,9 @@
struct timespec *ts);
int kern_semctl(struct thread *td, int semid, int semnum, int cmd,
union semun *arg, register_t *rval);
-int kern_sendfile(struct thread *td, struct sendfile_args *uap, bool compat,
- copyin_hdtr_t *copyin_hdtr_f, copyinuio_t *copyinuio_f);
+int kern_sendfile(struct thread *td, struct sendfile_args *uap,
+ copyin_hdtr_t *copyin_hdtr_f, copyinuio_t *copyinuio_f,
+ sendfile_copyin_hd_uio_t *copyin_hd_uio_f);
int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits);
int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 3, 10:03 PM (6 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37998000
Default Alt Text
D59198.diff (5 KB)

Event Timeline