Commit | Line | Data |
---|---|---|
d8525fbd JA |
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 | ||
fd7e7c54 JA |
16 | static int splice_flags; |
17 | ||
18 | static int usage(char *name) | |
19 | { | |
20 | fprintf(stderr, "%s: [-m] in_file out_file\n", name); | |
21 | return 1; | |
22 | } | |
23 | ||
24 | static int parse_options(int argc, char *argv[]) | |
25 | { | |
26 | int c, index = 1; | |
27 | ||
28 | while ((c = getopt(argc, argv, "m")) != -1) { | |
29 | switch (c) { | |
30 | case 'm': | |
31 | splice_flags = SPLICE_F_MOVE; | |
32 | index++; | |
33 | break; | |
34 | default: | |
35 | return -1; | |
36 | } | |
37 | } | |
38 | ||
39 | return index; | |
40 | } | |
41 | ||
d8525fbd JA |
42 | int main(int argc, char *argv[]) |
43 | { | |
fd7e7c54 | 44 | int in_fd, out_fd, pfds[2], index; |
d8525fbd JA |
45 | struct stat sb; |
46 | ||
fd7e7c54 JA |
47 | index = parse_options(argc, argv); |
48 | if (index == -1 || index + 2 > argc) | |
49 | return usage(argv[0]); | |
d8525fbd | 50 | |
fd7e7c54 | 51 | in_fd = open(argv[index], O_RDONLY); |
49b68ef7 JA |
52 | if (in_fd < 0) |
53 | return error("open input"); | |
d8525fbd | 54 | |
49b68ef7 JA |
55 | if (fstat(in_fd, &sb) < 0) |
56 | return error("stat input"); | |
d8525fbd | 57 | |
fd7e7c54 | 58 | out_fd = open(argv[index + 1], O_WRONLY | O_CREAT | O_TRUNC, 0644); |
49b68ef7 JA |
59 | if (out_fd < 0) |
60 | return error("open output"); | |
d8525fbd | 61 | |
49b68ef7 JA |
62 | if (pipe(pfds) < 0) |
63 | return error("pipe"); | |
d8525fbd JA |
64 | |
65 | do { | |
49b68ef7 | 66 | int this_len = min((off_t) BS, sb.st_size); |
fd7e7c54 | 67 | int ret = splice(in_fd, NULL, pfds[1], NULL, this_len, 0); |
d8525fbd JA |
68 | |
69 | if (ret <= 0) | |
70 | return error("splice-in"); | |
71 | ||
72 | sb.st_size -= ret; | |
73 | while (ret > 0) { | |
fd7e7c54 | 74 | int written = splice(pfds[0], NULL, out_fd, NULL, ret, splice_flags); |
d8525fbd JA |
75 | if (written <= 0) |
76 | return error("splice-out"); | |
77 | ret -= written; | |
78 | } | |
79 | } while (sb.st_size); | |
80 | ||
81 | close(in_fd); | |
82 | close(pfds[1]); | |
83 | close(out_fd); | |
84 | close(pfds[0]); | |
85 | return 0; | |
86 | } |