Use a heuristic to determine whether stat buffer sb

This preview shows page 12 - 15 out of 44 pages.

/* Use a heuristic to determine whether stat buffer SB comes from a filewith sparse blocks. If the file has fewer blocks than would normallybe needed for a file of its size, then at least one of the blocks inthe file is a hole. In that case, return true. */static boolis_probably_sparse (struct stat const *sb){return (HAVE_STRUCT_STAT_ST_BLOCKS&& S_ISREG (sb->st_mode)&& ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE);}
/* Copy a regular file from SRC_NAME to DST_NAME.If the source file contains holes, copies holes and blocks of zerosin the source file as holes in the destination file.(Holes are read as zeroes by the 'read' system call.)When creating the destination, use DST_MODE & ~OMITTED_PERMISSIONSas the third argument in the call to open, addingOMITTED_PERMISSIONS after copying as needed.X provides many option settings.Return true if successful.*NEW_DST is as in copy_internal.SRC_SB is the result of calling XSTAT (aka stat) on SRC_NAME. */static boolcopy_reg (char const *src_name, char const *dst_name,const struct cp_options *x,mode_t dst_mode, mode_t omitted_permissions, bool *new_dst,struct stat const *src_sb){char *buf;char *buf_alloc = NULL;char *name_alloc = NULL;int dest_desc;int dest_errno;int source_desc;mode_t src_mode = src_sb->st_mode;struct stat sb;struct stat src_open_sb;bool return_val = true;bool data_copy_required = x->data_copy_required;source_desc = open (src_name,(O_RDONLY | O_BINARY| (x->dereference == DEREF_NEVER ? O_NOFOLLOW : 0)));if (source_desc < 0){error (0, errno, _("cannot open %s for reading"), quote (src_name));return false;}if (fstat (source_desc, &src_open_sb) != 0){error (0, errno, _("cannot fstat %s"), quote (src_name));return_val = false;goto close_src_desc;}/* Compare the source dev/ino from the open file to the incoming,saved ones obtained via a previous call to stat. */if (! SAME_INODE (*src_sb, src_open_sb)){error (0, 0,_("skipping file %s, as it was replaced while being copied"),quote (src_name));return_val = false;goto close_src_desc;}/* The semantics of the following open calls are mandatedby the specs for both cp and mv. */if (! *new_dst){int open_flags =
O_WRONLY | O_BINARY | (x->data_copy_required ? O_TRUNC : 0);dest_desc = open (dst_name, open_flags);dest_errno = errno;/* When using cp --preserve=context to copy to an existing destination,use the default context rather than that of the source. Why?1) the src context may prohibit writing, and2) because it's more consistent to use the same contextthat is used when the destination file doesn't already exist. */if (x->preserve_security_context && 0 <= dest_desc){bool all_errors = (!x->data_copy_required|| x->require_preserve_context);bool some_errors = !all_errors && !x->reduce_diagnostics;security_context_t con = NULL;if (getfscreatecon (&con) < 0){if (all_errors || (some_errors && !errno_unsupported (errno)))error (0, errno, _("failed to get file system create context"));if (x->require_preserve_context){return_val = false;goto close_src_and_dst_desc;}}if (con){if (fsetfilecon (dest_desc, con) < 0){if (all_errors || (some_errors && !errno_unsupported (errno)))error (0, errno,_("failed to set the security context of %s to %s"),quote_n (0, dst_name), quote_n (1, con));if (x->require_preserve_context){return_val = false;freecon (con);goto close_src_and_dst_desc;}}

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture