--- /dev/null
+#define _GNU_SOURCE
+#include <fcntl.h> /* file control functions */
+...
+
+int main(int argc, char *argv[])
+{
+ int size = 4096;
+ int pipefd[2];
+ int in_fd, out_fd;
+ int nread, nwrite;
+ ...
+ /* Main body */
+ if ((argc - optind) != 2) { /* There must two argument */
+ printf("Wrong number of arguments %d\n", argc - optind);
+ usage();
+ }
+ /* open pipe, input and output file */
+ in_fd = open(argv[optind], O_RDONLY);
+ if (in_fd < 0) {
+ printf("Input error %s on %s\n", strerror(errno), argv[optind]);
+ exit(EXIT_FAILURE);
+ }
+ out_fd = open(argv[optind+1], O_CREAT|O_RDWR|O_TRUNC, 0644);
+ if (out_fd < 0) {
+ printf("Cannot open %s, error %s\n", argv[optind+1], strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (pipe(pipefd) == -1) {
+ perror("Cannot create buffer pipe");
+ exit(EXIT_FAILURE);
+ }
+ /* copy loop */
+ while (1) {
+ nread = splice(in_fd, NULL, pipefd[1], NULL, size,
+ SPLICE_F_MOVE|SPLICE_F_MORE);
+ if (nread == 0) break;
+ if (nread < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ perror("read error");
+ exit(EXIT_FAILURE);
+ }
+ }
+ do {
+ nwrite = splice(pipefd[0], NULL, out_fd, NULL, nread,
+ SPLICE_F_MOVE|SPLICE_F_MORE);
+ if (nwrite == 0) continue;
+ if (nwrite < 0) {
+ if (errno == EINTR)
+ continue;
+ else {
+ perror("write error");
+ exit(EXIT_FAILURE);
+ }
+ }
+ nread -= nwrite;
+ } while (nread);
+ }
+ return EXIT_SUCCESS;
+}