Rizin
unix-like reverse engineering framework and cli tools
can_clone_file.c File Reference
#include <stdlib.h>
#include "config.h"

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 56 of file can_clone_file.c.

56  {
57 #ifdef HAVE_CLONEFILE
58  struct statfs fs;
59  struct attrlist attribute_list;
60  struct {
61  uint32_t size;
62  vol_capabilities_attr_t capabilities;
63  } volume_attributes;
64 
65  if (statfs(".", &fs) < 0) {
66  fprintf(stderr, "%s: can't get mount point of current directory: %s\n", argv[0], strerror(errno));
67  exit(1);
68  }
69 
70  /* Not all volumes support clonefile(). A volume can be tested for
71  clonefile() support by using getattrlist(2) to get the volume
72  capabilities attribute ATTR_VOL_CAPABILITIES, and then testing the
73  VOL_CAP_INT_CLONE flag. */
74 
75  memset(&attribute_list, 0, sizeof(attribute_list));
76  attribute_list.bitmapcount = ATTR_BIT_MAP_COUNT;
77  attribute_list.volattr = ATTR_VOL_INFO | ATTR_VOL_CAPABILITIES;
78  memset(&volume_attributes, 0, sizeof(volume_attributes));
79 
80  if (getattrlist(fs.f_mntonname, &attribute_list, &volume_attributes, sizeof(volume_attributes), 0) < 0) {
81  fprintf(stderr, "%s: can't get volume capabilities of '%s': %s\n", argv[0], fs.f_mntonname, strerror(errno));
82  exit(1);
83  }
84 
85  if (volume_attributes.capabilities.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_CLONE) {
86  exit(0);
87  }
88 #elif defined(HAVE_FICLONERANGE)
89  char namea[32] = "a.fioclone.XXXXXX";
90  char nameb[32] = "b.fioclone.XXXXXX";
91  int fda, fdb, ret;
92  struct file_clone_range range;
93 
94  if ((fda = mkstemp(namea)) < 0) {
95  fprintf(stderr, "can't create temp file a: %s\n", strerror(errno));
96  exit(1);
97  }
98  if ((fdb = mkstemp(nameb)) < 0) {
99  fprintf(stderr, "can't create temp file b: %s\n", strerror(errno));
100  (void)close(fda);
101  (void)remove(namea);
102  exit(1);
103  }
104  if (write(fda, "test\n", 5) < 0) {
105  fprintf(stderr, "can't write temp file a: %s\n", strerror(errno));
106  (void)close(fda);
107  (void)remove(namea);
108  close(fdb);
109  (void)remove(nameb);
110  exit(1);
111  }
112  range.src_fd = fda;
113  range.src_offset = 0;
114  range.src_length = 0;
115  range.dest_offset = 0;
116  ret = ioctl(fdb, FICLONERANGE, &range);
117  (void)close(fda);
118  (void)close(fdb);
119  (void)remove(namea);
120  (void)remove(nameb);
121  if (ret >= 0) {
122  exit(0);
123  }
124 #endif
125 
126  exit(1);
127 }
static static fork write
Definition: sflib.h:33
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename ioctl
Definition: sflib.h:62
voidpf void uLong size
Definition: ioapi.h:138
return memset(p, 0, total)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who statfs
Definition: sflib.h:124
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
unsigned int uint32_t
Definition: sftypes.h:29
Definition: sftypes.h:74

References argv, close, test-lz4-list::exit, ioctl, memset(), capstone::range, statfs, and write.