Index: sys/compat/linux/linux_file.c =================================================================== --- sys/compat/linux/linux_file.c +++ sys/compat/linux/linux_file.c @@ -2039,13 +2039,28 @@ int linux_splice(struct thread *td, struct linux_splice_args *args) { + l_loff_t inoff, outoff, *inoffp, *outoffp; + int error; - linux_msg(td, "syscall splice not really implemented"); + inoffp = outoffp = NULL; + if (args->off_in != NULL) { + error = copyin(args->off_in, &inoff, sizeof(inoff)); + if (error != 0) + return (error); + inoffp = &inoff; + } + if (args->off_out != NULL) { + error = copyin(args->off_out, &outoff, sizeof(outoff)); + if (error != 0) + return (error); + outoffp = &outoff; + } + error = kern_copy_file_range(td, args->fd_in, inoffp, args->fd_out, + outoffp, args->len, 0); + if (error == 0 && args->off_in != NULL) + error = copyout(inoffp, args->off_in, sizeof(*inoffp)); + if (error == 0 && args->off_out != NULL) + error = copyout(outoffp, args->off_out, sizeof(*outoffp)); - /* - * splice(2) is documented to return EINVAL in various circumstances; - * returning it instead of ENOSYS should hint the caller to use fallback - * instead. - */ - return (EINVAL); + return (error); }