"Fossies" - the Fresh Open Source Software Archive

Member "libzip-1.6.0/regress/can_clone_file.c" (24 Jan 2020, 4087 Bytes) of package /linux/misc/libzip-1.6.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "can_clone_file.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.5.2_vs_1.6.0.

    1 /*
    2  can_clone_file.c -- does the current filesystem support cloning
    3  Copyright (C) 1999-2019 Dieter Baron and Thomas Klausner
    4 
    5  This file is part of libzip, a library to manipulate ZIP archives.
    6  The authors can be contacted at <libzip@nih.at>
    7 
    8  Redistribution and use in source and binary forms, with or without
    9  modification, are permitted provided that the following conditions
   10  are met:
   11  1. Redistributions of source code must retain the above copyright
   12  notice, this list of conditions and the following disclaimer.
   13  2. Redistributions in binary form must reproduce the above copyright
   14  notice, this list of conditions and the following disclaimer in
   15  the documentation and/or other materials provided with the
   16  distribution.
   17  3. The names of the authors may not be used to endorse or promote
   18  products derived from this software without specific prior
   19  written permission.
   20 
   21  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
   22  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
   25  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   27  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   29  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   30  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
   31  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 #include <errno.h>
   35 #include <stdio.h>
   36 #include <stdlib.h>
   37 #include <string.h>
   38 
   39 #include "config.h"
   40 
   41 #ifdef HAVE_CLONEFILE
   42 #include <sys/attr.h>
   43 #include <sys/mount.h>
   44 #include <sys/param.h>
   45 #include <unistd.h>
   46 #elif defined(HAVE_FICLONERANGE)
   47 #include <linux/fs.h>
   48 #include <sys/ioctl.h>
   49 #include <unistd.h>
   50 #endif
   51 
   52 int
   53 main(int argc, char *argv[]) {
   54 #ifdef HAVE_CLONEFILE
   55     struct statfs fs;
   56     struct attrlist attribute_list;
   57     struct {
   58     uint32_t size;
   59     vol_capabilities_attr_t capabilities;
   60     } volume_attributes;
   61 
   62     if (statfs(".", &fs) < 0) {
   63     fprintf(stderr, "%s: can't get mount point of current directory: %s\n", argv[0], strerror(errno));
   64     exit(1);
   65     }
   66 
   67     /* Not all volumes support clonefile().  A volume can be tested for
   68        clonefile() support by using getattrlist(2) to get the volume
   69        capabilities attribute ATTR_VOL_CAPABILITIES, and then testing the
   70        VOL_CAP_INT_CLONE flag. */
   71 
   72     memset(&attribute_list, 0, sizeof(attribute_list));
   73     attribute_list.bitmapcount = ATTR_BIT_MAP_COUNT;
   74     attribute_list.volattr = ATTR_VOL_INFO | ATTR_VOL_CAPABILITIES;
   75     memset(&volume_attributes, 0, sizeof(volume_attributes));
   76 
   77     if (getattrlist(fs.f_mntonname, &attribute_list, &volume_attributes, sizeof(volume_attributes), 0) < 0) {
   78     fprintf(stderr, "%s: can't get volume capabilities of '%s': %s\n", argv[0], fs.f_mntonname, strerror(errno));
   79     exit(1);
   80     }
   81 
   82     if (volume_attributes.capabilities.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_CLONE) {
   83     exit(0);
   84     }
   85 #elif defined(HAVE_FICLONERANGE)
   86     char namea[32] = "a.fioclone.XXXXXX";
   87     char nameb[32] = "b.fioclone.XXXXXX";
   88     int fda, fdb, ret;
   89     struct file_clone_range range;
   90 
   91     if ((fda = mkstemp(namea)) < 0) {
   92     fprintf(stderr, "can't create temp file a: %s\n", strerror(errno));
   93     exit(1);
   94     }
   95     if ((fdb = mkstemp(nameb)) < 0) {
   96     fprintf(stderr, "can't create temp file b: %s\n", strerror(errno));
   97     (void)close(fda);
   98     (void)remove(namea);
   99     exit(1);
  100     }
  101     if (write(fda, "test\n", 5) < 0) {
  102     fprintf(stderr, "can't write temp file a: %s\n", strerror(errno));
  103     (void)close(fda);
  104     (void)remove(namea);
  105     close(fdb);
  106     (void)remove(nameb);
  107     exit(1);
  108     }
  109     range.src_fd = fda;
  110     range.src_offset = 0;
  111     range.src_length = 0;
  112     range.dest_offset = 0;
  113     ret = ioctl(fdb, FICLONERANGE, &range);
  114     (void)close(fda);
  115     (void)close(fdb);
  116     (void)remove(namea);
  117     (void)remove(nameb);
  118     if (ret >= 0) {
  119     exit(0);
  120     }
  121 #endif
  122 
  123     exit(1);
  124 }