asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, int fd_out, loff_t __user *off_out, size_t len, unsigned int flags) { long error; struct file *in, *out; int fput_in, fput_out; if (unlikely(!len)) return 0; error = -EBADF; in = fget_light(fd_in, &fput_in); if (in) { if (in->f_mode & FMODE_READ) { out = fget_light(fd_out, &fput_out); if (out) { if (out->f_mode & FMODE_WRITE) error = do_splice(in, off_in, out, off_out, len, flags); fput_light(out, fput_out); } } fput_light(in, fput_in); } return error; }
int main(int argc, char *argv[]) { int fd, index; if (argc < 2) return usage(argv[0]); if (check_input_pipe()) return usage(argv[0]); index = parse_options(argc, argv); if (index == -1 || index + 1 > argc) return usage(argv[0]); fd = open(argv[index], O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd < 0) return error("open output"); do { int tee_len = stee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, 0); if (tee_len < 0) { if (errno == EAGAIN) { usleep(1000); continue; } return error("tee"); } else if (!tee_len) break; /* * Send output to file, also consumes input pipe. */ if (do_splice(STDIN_FILENO, fd, tee_len, "splice-file")) break; } while (1); return 0; }