diff options
Diffstat (limited to 'src/samizdat-ficlonerange.c')
-rw-r--r-- | src/samizdat-ficlonerange.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/samizdat-ficlonerange.c b/src/samizdat-ficlonerange.c new file mode 100644 index 0000000..a620cbf --- /dev/null +++ b/src/samizdat-ficlonerange.c | |||
@@ -0,0 +1,51 @@ | |||
1 | #include <fcntl.h> | ||
2 | #include <linux/fs.h> | ||
3 | #include <stdio.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <sys/ioctl.h> | ||
6 | #include <sys/stat.h> | ||
7 | #include <sys/types.h> | ||
8 | |||
9 | int main(int argc, char **argv) | ||
10 | { | ||
11 | if (argc != 6) | ||
12 | { | ||
13 | fputs("Error: usage: wrong number of arguments\n", stderr); | ||
14 | return -1; | ||
15 | } | ||
16 | char *src_name = argv[1]; | ||
17 | char *dest_name = argv[2]; | ||
18 | u_int64_t src_offset = atoll(argv[3]); | ||
19 | u_int64_t src_length = atoll(argv[4]); | ||
20 | u_int64_t dest_offset = atoll(argv[5]); | ||
21 | |||
22 | int src, dest; | ||
23 | if ((src = open(src_name, O_RDONLY)) < 0) | ||
24 | { | ||
25 | perror("Error opening input file"); | ||
26 | return 1; | ||
27 | } | ||
28 | if ((dest = open(dest_name, O_RDWR | O_CREAT)) < 0) | ||
29 | { | ||
30 | perror("Error opening output file"); | ||
31 | return 2; | ||
32 | } | ||
33 | if (dest_offset == 0) | ||
34 | { | ||
35 | struct stat buf; | ||
36 | stat(dest_name, &buf); | ||
37 | dest_offset = buf.st_size; | ||
38 | } | ||
39 | |||
40 | struct file_clone_range s = {src, src_offset, src_length, dest_offset}; | ||
41 | if (ioctl(dest, FICLONERANGE, &s)) | ||
42 | { | ||
43 | perror("ioctl FICLONERANGE failed"); | ||
44 | return 3; | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | return 0; | ||
49 | } | ||
50 | } | ||
51 | |||