aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorAlfred Perlstein <alfred@FreeBSD.org>2002-07-12 06:51:57 +0000
committerAlfred Perlstein <alfred@FreeBSD.org>2002-07-12 06:51:57 +0000
commit9c34129662e5528315759214946197b22a743652 (patch)
tree7a0bf043b02e40a3c00a04f2d19bb5c356f97759 /sys/kern
parent074453c230c604c5954dd7647427c727e9b4c99b (diff)
downloadsrc-9c34129662e5528315759214946197b22a743652.tar.gz
src-9c34129662e5528315759214946197b22a743652.zip
Create a bug-for-bug FreeBSD4 compatible version of sendfile and move the
fixed sendfile over. This is needed to preserve binary compatibility from 4.x to 5.x.
Notes
Notes: svn path=/head/; revision=99855
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/syscalls.master7
-rw-r--r--sys/kern/uipc_syscalls.c39
2 files changed, 41 insertions, 5 deletions
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 15a5d7cdda7d..beeee9c2f0b2 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -8,7 +8,7 @@
; number system call number, must be in order
; type one of [M]STD, [M]OBSOL, [M]UNIMPL, [M]COMPAT, [M]CPT_NOA,
; [M]LIBCOMPAT, [M]NODEF, [M]NOARGS, [M]NOPROTO, [M]NOIMPL,
-; [M]NOSTD
+; [M]NOSTD, [M]COMPAT4
; namespc one of POSIX, BSD, NOHIDE
; name psuedo-prototype of syscall routine
; If one of the following alts is different, then all appear:
@@ -23,6 +23,7 @@
; lock for the syscall.
; STD always included
; COMPAT included on COMPAT #ifdef
+; COMPAT4 included on COMPAT4 #ifdef (FreeBSD 4 compat)
; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h
; OBSOL obsolete, not included in system, only specifies name
; UNIMPL not implemented, placeholder only
@@ -479,7 +480,7 @@
333 MSTD POSIX { int sched_get_priority_min (int policy); }
334 MSTD POSIX { int sched_rr_get_interval (pid_t pid, struct timespec *interval); }
335 STD BSD { int utrace(const void *addr, size_t len); }
-336 MSTD BSD { int sendfile(int fd, int s, off_t offset, size_t nbytes, \
+336 MCOMPAT4 BSD { int sendfile(int fd, int s, off_t offset, size_t nbytes, \
struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
337 STD BSD { int kldsym(int fileid, int cmd, void *data); }
338 MSTD BSD { int jail(struct jail *jail); }
@@ -563,3 +564,5 @@
int len); }
391 STD BSD { int lchflags(const char *path, int flags); }
392 STD BSD { int uuidgen(struct uuid *store, int count); }
+393 MSTD BSD { int sendfile(int fd, int s, off_t offset, size_t nbytes, \
+ struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 1e9c5facdc39..02cce09530b7 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -81,6 +81,7 @@ static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
static int accept1(struct thread *td, struct accept_args *uap, int compat);
+static int do_sendfile(struct thread *td, struct sendfile_args *uap, int compat);
static int getsockname1(struct thread *td, struct getsockname_args *uap,
int compat);
static int getpeername1(struct thread *td, struct getpeername_args *uap,
@@ -1637,6 +1638,31 @@ sf_buf_free(void *addr, void *args)
int
sendfile(struct thread *td, struct sendfile_args *uap)
{
+
+ return (do_sendfile(td, uap, 0));
+}
+
+#ifdef COMPAT_FREEBSD4
+int
+freebsd4_sendfile(struct thread *td, struct freebsd4_sendfile_args *uap)
+{
+ struct sendfile_args args;
+
+ args.fd = uap->fd;
+ args.s = uap->s;
+ args.offset = uap->offset;
+ args.nbytes = uap->nbytes;
+ args.hdtr = uap->hdtr;
+ args.sbytes = uap->sbytes;
+ args.flags = uap->flags;
+
+ return (do_sendfile(td, &args, 1));
+}
+#endif /* COMPAT_FREEBSD4 */
+
+static int
+do_sendfile(struct thread *td, struct sendfile_args *uap, int compat)
+{
struct vnode *vp;
struct vm_object *obj;
struct socket *so = NULL;
@@ -1694,7 +1720,10 @@ sendfile(struct thread *td, struct sendfile_args *uap)
error = writev(td, &nuap);
if (error)
goto done;
- hdtr_size += td->td_retval[0];
+ if (compat)
+ sbytes += td->td_retval[0];
+ else
+ hdtr_size += td->td_retval[0];
}
}
@@ -1921,7 +1950,10 @@ retry_space:
error = writev(td, &nuap);
if (error)
goto done;
- hdtr_size += td->td_retval[0];
+ if (compat)
+ sbytes += td->td_retval[0];
+ else
+ hdtr_size += td->td_retval[0];
}
done:
@@ -1933,7 +1965,8 @@ done:
td->td_retval[0] = 0;
}
if (uap->sbytes != NULL) {
- sbytes += hdtr_size;
+ if (!compat)
+ sbytes += hdtr_size;
copyout(&sbytes, uap->sbytes, sizeof(off_t));
}
if (vp)