summaryrefslogtreecommitdiff
path: root/src/samizdat-ficlonerange.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/samizdat-ficlonerange.c')
-rw-r--r--src/samizdat-ficlonerange.c51
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
9int 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