Initial commit
[splice.git] / splice-cp.c
1 /*
2  * Splice cp a file
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11
12 #include "splice.h"
13
14 #define BS      SPLICE_SIZE
15
16 int main(int argc, char *argv[])
17 {
18         int in_fd, out_fd, pfds[2];
19         struct stat sb;
20
21         if (argc < 3) {
22                 printf("%s: infile outfile\n", argv[0]);
23                 return 1;
24         }
25
26         in_fd = open(argv[1], O_RDONLY);
27         if (in_fd < 0) {
28                 perror("open in");
29                 return 1;
30         }
31
32         if (fstat(in_fd, &sb) < 0) {
33                 perror("stat");
34                 return 1;
35         }
36
37         out_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
38         if (out_fd < 0) {
39                 perror("open out");
40                 return 1;
41         }
42
43         if (pipe(pfds) < 0) {
44                 perror("pipe");
45                 return 1;
46         }
47
48         do {
49                 int this_len = min(BS, sb.st_size);
50                 int ret = splice(in_fd, NULL, pfds[1], NULL, this_len, SPLICE_F_NONBLOCK);
51
52                 if (ret <= 0)
53                         return error("splice-in");
54
55                 sb.st_size -= ret;
56                 while (ret > 0) {
57                         int written = splice(pfds[0], NULL, out_fd, NULL, ret, 0);
58                         if (written <= 0)
59                                 return error("splice-out");
60                         ret -= written;
61                 }
62         } while (sb.st_size);
63
64         close(in_fd);
65         close(pfds[1]);
66         close(out_fd);
67         close(pfds[0]);
68         return 0;
69 }