diff options
-rw-r--r-- | sys/kern/syscalls.master | 7 | ||||
-rw-r--r-- | sys/kern/uipc_syscalls.c | 39 |
2 files changed, 41 insertions, 5 deletions
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 15a5d7c..beeee9c 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 1e9c5fa..02cce09 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) |