summaryrefslogtreecommitdiff
path: root/src/copy.c
AgeCommit message (Collapse)Author
2013-11-27selinux: adjust utils to run restorecon with -ZPádraig Brady
cp, mv, install, mkdir, mkfifo, mknod are adjusted so that: -Z no longer accepts an argument. -Z or --context without an argument do not warn without SELinux. --context with an argument will warn without SELinux. * src/local.mk: Reference the new selinux module where required. * src/system.h: Make the argument to --context optional. * src/mkdir.c: Likewise. Also handle the SMACK case for --context. Note we currently silently ignore -Z with SMACK. * src/mkfifo.c: Likewise. * src/mknod.c: Likewise. * src/install.c: Likewise. Note install(1) by default already set the context for target files to their system default, albeit with an older method. Use the -Z option to select between the old and new context restoration behavior, and document the differences and details for how context restoration is done in new and old methods, with a view disabling the old method entirely in future. * src/cp.c: Make the argument to --context optional. Note -Z implies --no-preserve=context. I.E. -Z overrides that aspect of -a no matter what order specified. (struct cp_options): Document the context handling options. (main): Check/adjust option combinations after all options are processed, to both simplify processing and to make handling independent of order of options on the command line. Also improve the diagnostics from a failed call to setfscreatecon(). (set_process_security_ctx): A new function, refactored to set the default context from the source file, or with the type adjusted as per the system default for the destination path. (set_file_security_ctx): A new function refactored to set the security context of an existing file, either based on the process context or the default system context for a path. (copy_internal): Use the refactored functions to simplify error handling and consistently fail or warn as needed. (copy_reg): Likewise. (copy_internal): With --preserve=context, also copy context from non regular files. Note for directories this may impact the copying of subsequent files to that directory? (copy_attr): If we're handling SELinux explicitly, then exclude to avoid the redudant copy with --preserve=context, and the problematic copy with -Z. Note SELinux attribute exclusion also now honors cp -a --no-preserve=context. Note there was a very small window over 10 years ago, where attr_copy_file was available, while attr_copy_check_permissions was not, so we don't bother adding an explicit m4 check for the latter function. * src/mv.c: Support --context, but don't allow specifying an argument. * src/chcon.c: Adjust a comment to be specific to SELinux. * src/runcon.c: Likewise. * src/copy.c: Honor the context settings to "restorecon" as appropriate. * src/copy.h: Add a new setting to select "restorecon" functionality. * tests/mkdir/selinux.sh: s/-Z/--context=/ * tests/cp/cp-a-selinux.sh: Augment this test with cases testing basic -Z functionality, and also test the various invalid option combinations and option precedence. * tests/mkdir/restorecon.sh: Add a new test for the more involved mkdir -Z handling, since the directory changing and non existent directories need to be specially handled. Also check the similar but simpler handling of -Z by mk{nod,fifo}. * tests/local.mk: Reference the new test. * doc/coreutils.texi (cp invocation): Update as per interface changes. (mv invocation): Likewise. (install invocation): Likewise. (mkfifo invocation): Likewise. (mknod invocation): Likewise. (mkdir invocation): Likewise. * NEWS: Mention the new feature and change in behavior.
2013-11-07cp: fix --link regarding the dereferencing of symbolic linksGian Piero Carrubba
* src/copy.c (create_hard_link): Add a bool 'dereference' parameter, and pass AT_SYMLINK_FOLLOW as 'flags' to linkat() when dereference is true. (should_dereference): Add new 'bool' function to determine if a file should be dereferenced or not. (copy_internal): Use the above new should_dereference() and remember its return value in a new local bool 'dereference' variable. Use that in all three calls to create_hard_link(). * src/cp.c (main): after parsing the options, if x.dereference is still DEFEF_UNDEFINED and the x.recursive is true, then only set x.dereference to DEREF_NEVER iff --link was not specified. * doc/coreutils.texi (cp invocation): Mention that cp(1) does not follow symbolic links in the source when --link is specified. Likewise in the description of the -R option when used together with that option. * tests/cp/same-file.sh: Adapt the expected results for the -fl, the -bl and the -bfl tests. * tests/cp/link-deref.sh: Add a new test. * tests/local.mk (all_tests): Reference the above new test. * NEWS (Changes in behavior): Mention the change. This fixes http://bugs.gnu.org/15173 Co-authored-by: Bernhard Voelker <mail@bernhard-voelker.de>
2013-09-01maint: update out of date confusing commentsPádraig Brady
* src/copy.c (copy_internal): Change mention of the removed --reply=no option, to the similar in this context --no-clobber. * src/sort.c: SI and IEC suffixes can now be mixed when --human-numeric.
2013-07-25mv: replace empty directories in cross file system moveKen Booth
src/copy.c (copy_internal): Use rmdir() rather than unlink() when the source is a directory, so that empty directories are replaced in the destination as per POSIX. * tests/mv/part-rename.sh: Augment with various combinations. * NEWS: Mention the bug fix. Fixes http://bugs.gnu.org/14763
2013-05-11maint: add FIXME commentPaul Eggert
2013-02-20copy: ensure the correct root ID is checked on all platformsJoachim Schmitz
* src/copy.c (copy_reg): Check ROOT_UID rather than 0, which is significant on HP-NonStop.
2013-02-20maint: cleanup up various uses of __attribute__Pádraig Brady
* src/cfg.mk (sc_prohibit-gl-attributes): Disallow the __attribute() form without trailing underscores as that is not elided where required. Also ensure we use gnulib macros rather than defining our own. * src/system.h: Remove gnulib provided macros. * src/chown-core.c: Likewise. * src/chroot.c: Likewise. * src/copy.c: Likewise. * src/csplit.c: Likewise. * src/dd.c: Likewise. * src/expr.c: Likewise. * src/extent-scan.c: Likewise. * src/factor.c: Likewise. * src/ls.c: Likewise. * src/od.c: Likewise. * src/paste.c: Likewise. * src/ptx.c: Likewise. * src/sort.c: Likewise. * src/stat.c: Likewise. * src/stty.c: Likewise. * src/system.h: Likewise. * src/tac.c: Likewise. * src/test.c: Likewise. * src/tsort.c: Likewise.
2013-02-06maint: improve error messages upon failed read, write, access, closeBenno Schulenberg
Note we use "failed to {access,close}" for those single operations, and "error {read,writ}ing" for those partial operation failures. * src/copy.c: Improve error messages for failing read, write and close. * src/cp.c: Improve error messages for failing access. * src/dd.c: Improve error messages for failing read, write and open. * src/head.c: Improve error message for failing close. * src/install.c: Improve error messages for failing access. * src/ln.c: Likewise. * src/mv.c: Likewise. * src/touch.c: Improve error message for failing close. * src/truncate.c: Likewise.
2013-01-01maint: update all copyright year number rangesJim Meyering
Run "make update-copyright", but then also run this, perl -pi -e 's/2\d\d\d-//' tests/sample-test to make that one script use the single most recent year number.
2012-12-08cp: fix --no-preserve=mode to not exit 1Bernhard Voelker
cp --no-preserve=mode exited 1 unconditionally. Furthermore, the tests which would have detected this error - namely link-preserve.sh and reserve-mode.sh - failed to test cp's exit code. * src/copy.c (copy_reg): In the case x->explicit_no_preserve_mode, do only set return_val to false iff the previous set_acl () failed. * tests/cp/link-preserve.sh: Check cp's exit code. * tests/cp/link-symlink.sh: Likewise. * tests/cp/preserve-mode.sh: Likewise. * NEWS: Mention the fix. Bug introduced in commit v8.19-145-g24ebca6. Reported by Florian Pritz in http://bugs.gnu.org/13119.
2012-11-20install: fix security racePaul Eggert
* src/copy.c (copy_internal): Use DST_MODE_BITS, not SRC_MODE. See Bernhard R. Link in <http://bugs.gnu.org/12947> and in <http://bugs.debian.org/598018>.
2012-09-28cp: fix the --no-preserve=mode optionOndrej Oprala
The --no-preserve=mode option did not do what its name implies: it would mistakenly preserve permission mode bits. * NEWS: Mention the fix. * TODO: Remove an entry. * src/copy.c (copy_reg): Add a condition to properly handle the --no-preserve=mode option for files (copy_internal): Add a condition to properly handle the --no-preserve=mode option for directories. * src/copy.h (struct cp_options): Add a new boolean. * src/cp.c (cp_option_init,decode_preserve_arg): Set the new boolean value according to specified options. * src/install.c (struct cp_options): Initialize the new boolean. * src/mv.c (struct cp_options): Initialize the new boolean. * tests/cp/preserve-mode.sh: Add a new test. * tests/cp/link-preserve.sh (-a --no-preserve=mode): Adjust the expected perms: now, --no-preserve=mode overrides the --preserve=mode that is inherent in -a, as it should. * tests/local.mk: Add the new test to the list.
2012-05-07cp: handle a race condition more sensiblyJim Meyering
* src/copy.c (copy_reg): In a narrow race (stat sees dest, yet open-without-O_CREAT fails with ENOENT), retry the open with O_CREAT. * tests/cp/nfs-removal-race: New file. * tests/Makefile.am (TESTS): Add it. * NEWS (Bug fixes): Mention it. Reported by Philipp Thomas and Neil F. Brown in http://bugs.gnu.org/11100
2012-05-02cp,mv,install: provide POSIX_FADV_SEQUENTIAL hint to inputPádraig Brady
This was inadvertently omitted from v8.5-104-g47076e3, and gives the same 5% speedup when copying from an SSD. * src/copy.c (copy_internal): Apply the FADVISE_SEQUENTIAL hint.
2012-05-02maint: with split lines, don't leave an operator at end of lineJim Meyering
* src/copy.c (copy_reg): Split an expression before a binary operator, not after it. * src/cut.c (set_fields): Likewise. * src/id.c (main): Likewise. * src/install.c (setdefaultfilecon): Likewise. * src/join.c (ignore_case): Likewise. * src/pr.c (cols_ready_to_print, init_parameters, print_page): Likewise. * src/stty.c (set_window_size): Likewise. * src/wc.c (SUPPORT_OLD_MBRTOWC): Likewise. * src/who.c (scan_entries): Likewise. * src/test.c (binary_operator): Join a split line. * src/extent-scan.c (extent_scan_read): Move an ">" from end of line to beginning of the following. Likewise for two other expressions.
2012-04-12cp: change --attributes-only to not truncate existing filesPádraig Brady
* src/copy.c (copy_reg): Don't truncate an existing file, to support copying attributes between existing files. The original use case only considered creating new files, and it would be a very unusual use case to be relying on the truncating behavior. * doc/coreutils.texi (cp invocation): Mention the non truncating behavior. * tests/cp/attr-existing: A new test to ensure O_TRUNC skipped. * tests/Makefile.am: Reference the new test. * NEWS: Mention the change in behavior.
2012-03-06maint: refactor copy to use is_nul()Pádraig Brady
* src/dd.c: Move is_nul() from here to ... * src/system.h: ... here * src/copy.c (sparse_copy): Adjust to use the refactored is_nul()
2012-02-12mv: "mv A B" would sometimes succeed, yet A would remain, ...Jim Meyering
But only when both A and B were hard links to the same symlink. * src/copy.c (same_file_ok): Handle another special case: the one in which we are moving a symlink onto a hard link to itself. In this case, we must explicitly tell the caller to unlink the source file. Otherwise, at least the linux-3.x kernel rename function would do nothing, as mandated by POSIX 2008. * tests/mv/symlink-onto-hardlink-to-self: New test. * tests/Makefile.am (TESTS): Add it. * NEWS (Bug fixes): Mention it. Reported by Bernhard Voelker in http://bugs.gnu.org/10686
2012-01-30mv: allow moving symlink onto same-inode dest with >= 2 hard linksJim Meyering
Normally, mv detects a few subtle cases in which proceeding with a same-file rename would, with very high probability, cause data loss. Here, we have found a corner case in which one of these same-inode tests makes mv refuse to perform a useful operation. Permit that corner case. * src/copy.c (same_file_ok): Detect/exempt this case. * tests/mv/symlink-onto-hardlink: New test. * tests/Makefile.am (TESTS): Add it. * NEWS (Bug fixes): Mention it. Initially reported by: Matt McCutchen in http://bugs.gnu.org/6960. Raised again by Anders Kaseorg due to http://bugs.debian.org/654596. Improved-by: Paul Eggert.
2012-01-27maint: use single copyright year rangeJim Meyering
Run "make update-copyright".
2012-01-09maint: src/*.[ch]: convert more `...' to '...'Jim Meyering
Run this (twice): git grep -E -l '`.+'\' src/*.[ch] \ |xargs perl -pi -e 's/`(.+?'\'')/'\''$1/'
2012-01-09maint: src/*.c: change remaining quotes (without embedded spaces)Jim Meyering
Run this (twice): git grep -E -l '`[^ ]+'\' src/*.c \ |xargs perl -pi -e 's/`([^ ]+'\'')/'\''$1/'
2012-01-01maint: update all copyright year number rangesJim Meyering
Run "make update-copyright".
2011-07-27maint: copy: refactor hard link creationPádraig Brady
* src/copy.c (create_hard_link): A new function refactored from existing code. (copy_internal): Call the new function from all 3 locations that create hard links. * tests/cp/same-file: Amend to match the adjusted diagnostic.
2011-07-26maint: use consistent style in C and test scriptsJim Meyering
* src/copy.c (copy_internal): Adjust formatting style to conform with guidelines in HACKING: put braces around two one-line "else" blocks. * tests/cp/existing-perm-dir: Use $(...), not `...`, and stat rather than ls+cut to get the mode string. mode=$(stat --p=%A dst/dir)
2011-07-25cp: don't mishandle existing dir dest permissions (Bug#9170)Paul Eggert
* src/copy.c (copy_internal): If we don't create the directory, then we cannot have omitted permissions. Problem and trivial fix reported by Eric Lammerts. * tests/Makefile.am (TESTS): Add cp/existing-perm-dir. * tests/cp/existing-perm-dir: New file.
2011-07-25cp -up: preserve all hard linksJim Meyering
* src/copy.c (copy_internal): With --update (-u), this function would return early once it found that the destination is not older than the source, *without* recording the source-dev/ino--to--dest_name mapping. That mapping is required in order to preserve src hard links in the destination tree, so when using cp with --update and --preserve=links (perhaps via -p or -a), cp could fail to preserve one hard link per inode when at least one of the hard-linked names already exists in the destination tree. Reported by Odd Harry Mannsverk in http://debbugs.gnu.org/8419. * tests/cp/preserve-link: New file. Exercise the flaw/fix. * tests/Makefile.am (TESTS): Add it. * NEWS (Bug fixes): Mention it.
2011-07-02maint: use "const" and "pure" function attributes where possibleJim Meyering
* configure.ac (WARN_CFLAGS): Add -Wsuggest-attribute=const, -Wsuggest-attribute=pure and -Wsuggest-attribute=noreturn. (GNULIB_WARN_CFLAGS): But do not add them here... yet. * src/chown-core.h (chopt_free, uid_to_name): Add function attribute(s). * src/copy.c (is_ancestor, valid_options): Likewise. * src/copy.h (chown_failure_ok): Likewise. * src/dd.c (operand_matches, operand_is): Likewise. * src/df.c (selected_fstype, excluded_fstype): Likewise. * src/expr.c (null looks_like_integer): Likewise. * src/md5sum.c (hex_digits): Likewise. * src/od.c (get_lcm): Likewise. * src/pathchk.c (component_start, component_len): Likewise. * src/pinky.c (count_ampersands): Likewise. * src/pr.c (cols_ready_to_print): Likewise. * src/ptx.c (search_table): Likewise. * src/sort.c (find_unit_order): Likewise. * src/stty.c (mode_type_flag, string_to_baud, baud_to_value): Likewise. * src/system.h (gcd, lcm): Likewise. * src/tr.c (is_char_class_member, look_up_char_class): Likewise. (star_digits_closebracket): Likewise. * src/uniq.c (find_field): Likewise. * src/wc.c (compute_number_width): Likewise. * lib/xfts.h (cycle_warning_required): Likewise. * gl/lib/randint.h (randint_get_source): Likewise. * gl/lib/randperm.c (ceil_lg): Likewise. * gl/lib/randperm.h (randperm_bound): Likewise. * lib/strnumcmp.h (strintcmp): Likewise.
2011-06-13maint: use stat-size module from gnulibJames Youngman
* gnulib: Update to latest. * src/system.h: Definitions of ST_* macros have moved into the gnulib module stat-size (specifically, the header file stat-size.h), so remove them from here. * src/truncate.c: Include stat-size.h. * src/stat.c: Likewise. * src/shred.c: Likewise. * src/ls.c: Likewise. * src/du.c: Likewise. * src/ioblksize.h: New file. Move definition of io_blksize out of system.h so that system.h does not have to include stat-size.h. * src/cat.c: Include ioblksize.h. * src/split.c: Likewise. * src/copy.c: Include both stat-size.h and ioblksize.h. * src/Makefile.am (noinst_HEADERS): Add ioblksize.h.
2011-05-03copy: fix my typoJim Meyering
* src/copy.c (copy_reg): Fix my typo (mis-applied patch). The patch by Jeff Liu was fine, but I mis-applied it and introduced a compilation error in commit efa479c1. 2011-05-03 Jim Meyering <meyering@redhat.com>
2011-05-03copy: correct misuse of quote in diagnosticJeff Liu
* src/copy.c (copy_reg): Multiple uses of quote (s) in an argument list is erroneous. Use quote_n, instead.
2011-04-25copy: include both src and dest names in clone failure diagnosticJeff Liu
* src/copy.c (copy_reg): Upon btrfs clone failure, print not just the destination file name, but also the source file name. That may be useful upon failure of a cross-device clone attempt.
2011-04-20copy: use FIEMAP (extent_copy) only for apparently-sparse files,Jim Meyering
to avoid the expense of extent_copy's unconditional use of FIEMAP_FLAG_SYNC. * src/copy.c (copy_reg): Do not attempt extent_copy on a file that appears to have no holes. * NEWS (Changes in behavior): Document this. At first I labeled this as a bug fix, but that would be inaccurate, considering there is no documentation of FIEMAP semantics, nor even consensus among kernel FS developers. Here's hoping SEEK_HOLE/SEEK_DATA support will soon make it into the linux kernel.
2011-04-20copy: factor out a tiny sparse-testing functionJim Meyering
* src/copy.c (HAVE_STRUCT_STAT_ST_BLOCKS): Define to 0 if undefined, so we can use it in the return expression, here: (is_probably_sparse): New function, factored out of... (copy_reg): ...here. Use the new function.
2011-04-20copy: do not treat unwritten extents specially: avoid XFS/ext4 data lossJim Meyering
* src/copy.c (extent_copy): Do not treat "unwritten extents" specially. Otherwise, with a release-candidate 2.6.39-rc3 kernel, XFS or ext4, when using gold as your linker, and if you forget to run "make check", you could end up installing files full of zeros instead of the expected binaries. For a lot of discussion, see http://thread.gmane.org/gmane.comp.file-systems.xfs.general/37895 * tests/cp/fiemap-empty: Disable this test.
2011-04-06copy: fix an unlikely memory leak when a fiemap copy failsPádraig Brady
* src/copy.c (extent_copy): Free the extents array when sparse_copy() fails.
2011-04-02cp: always detect copy-into-self: avoid infloop w/large PATH_MAXJim Meyering
When running the erroneous command, cp -rl A D D, and depending on the structure of directories A and D and the file system type (because that changes order of dir. entry traversal), cp would sometimes fail to detect that D was being copied into D, and would create D/D/D/D/D/... until it hit PATH_MAX or exhausted some resource. I noticed this via the occasional failure of the cp/into-self test when run using a ZFS file system. It is occasional because the bug is dependent on the order in which directory entries are traversed, and that is apparently indeterminate with ZFS. Technically, with the current recursive implementation, there is no risk of an infinite loop, due to stack limitations, but with an eventual fts-based implementation, it might have iterated until disk space or inodes are exhausted. * src/copy.c (copy_dir): Avoid copy-into-self interminable loop on systems with large PATH_MAX. On other systems, diagnose the copy-into- self error consistently. Handle the parameter, first_dir_created_per_command_line_arg, correctly when there are two or more sub-directories.
2011-04-01copy: process empty extents more efficientlyPádraig Brady
* src/copy.c (extent_copy): Treat an allocated but empty extent much like a hole. I.E. don't read data we know is going to be NUL. Also we convert the empty extent to a hole only when SPARSE_ALWAYS so that the source and dest have the same allocation. This will be improved soon, when we use fallocate() to do the allocation. * tests/cp/fiemap-empty: A new test for efficiency and correctness of copying empty extents. * tests/Makefile.am: Reference the new test. * NEWS: Mention the change in behavior.
2011-04-01copy: link rather than copy symlinks, when --link usedPádraig Brady
This bug was introduced in commit ca9e212c, 2009-09-24, "cp, mv: use linkat to guarantee semantics", which inadvertently disabled the creation of hardlinks to symlinks. However rather than implementing the intention of that commit and relying on gnulib linkat emulation, we'll revert to the previous emulation as that maintains ownership and timestamps. * src/copy.c (copy_internal): Use our existing hardlink to symlink emulation when link() might dereference the symlink. Also ensure that we copy the timestamps of the original symlink when we use the emulation. * tests/cp/link-symlink: Add a test to ensure timestamps copied. * tests/Makefile.am: Reference the new test. * NEWS: Mention the fix. Reported by Ruediger Meier
2011-02-11copy: adjust fiemap handling of sparse filesPádraig Brady
Don't depend on heuristics to detect sparse files if fiemap is available. Also don't scan for new holes unless --sparse=always has been specified. * src/copy.c (extent_copy): Pass the user specified sparse mode, and handle as described above.
2011-02-11copy: suppress redundant lseeks when using fiemapPádraig Brady
* src/copy.c (extent_copy): Suppress redundant lseek()s in both the source and dest files, when there is no hole between extents.
2011-02-05copy: don't let a failed lseek go undiagnosedJim Meyering
Upon failed lseek, sparse_copy_finalize would mistakenly return true. Admittedly, that is very unlikely, since that particular lseek is attempted only if the preceding call to sparse_copy induced a hole at EOF (via lseek on the destination FD). However, now that sparse_copy has an output parameter, N_READ, there is no longer any reason to call lseek (fd, 0, SEEK_CUR), so... * src/copy.c (sparse_copy_finalize): Remove the function. (copy_reg): Call ftruncate with n_read, rather than sparse_copy_finalize with its now-unnecessary lseek. Lasse Collin spotted the bug in sparse_copy_finalize.
2011-01-31cp: fix the buffer size used when writing zerosPádraig Brady
* src/copy.c (write_zeros): This bug caused 4 or 8 bytes to be written at a time which is very inefficient. One could trigger the issue with `cp --sparse=never sparse non-sparse` on a file system that supports fiemap.
2011-01-31cp: always initialize extent_copy's output parameterJim Meyering
* src/copy.c (extent_copy): Otherwise it would be used uninitialized.
2011-01-31cp: fix copying a sparse file to a pipeJim Meyering
The recent FIEMAP-related changes made it so the unusual case of copying a sparse file to a non-regular destination (e.g., a pipe) would erroneously write one byte too many to that destination. That happened because extent_copy assumed that it could use lseek to obtain the number of bytes written to the output file descriptor. That was valid only for regular files. * src/copy.c (sparse_copy): Add a parameter, to be used by extent_copy, but not by reg_copy. Adjust callers. (extent_copy): Maintain new local, dest_pos, using new arg, n_read. Don't call lseek on dest_fd; use new var, dest_pos, instead. (copy_reg): Add unused arg.
2011-01-31maint: remove unused inclusion of "fiemap.h"Jim Meyering
* src/copy.c: Don't include "fiemap.h".
2011-01-30copy, tee: assume EINTR is always defined: remove #ifdefsJim Meyering
Don't use "#ifdef EINTR". dd.c has been doing that since 2004. * src/copy.c (sparse_copy): Remove #ifdef...#endif around EINTR use. * src/tee.c (tee_files): Remove #ifdef...#endif around EINTR use. If we need it, add something like this in system.h: /* When EINTR is not defined, define it to an improbable value so that each use does not have to be #ifdef'd. */ #ifndef EINTR # define EINTR 999988 #endif
2011-01-30copy: make extent_copy use sparse_copy, rather than its own codeJim Meyering
* src/copy.c (extent_copy): Before this change, extent_copy would fail to create holes, thus breaking --sparse=auto and --sparse=always. I.e., copying a large enough file of all zeros, cp --sparse=always should introduce a hole, but with extent_copy, it would not.
2011-01-30copy: remove obsolete commentJim Meyering
* src/copy.c (sparse_copy): Remove now-obsolete comment about how we used to work around lack of ftruncate. Combine nested if conditions into one.
2011-01-30copy: factor sparse-copying code into its own function, becauseJim Meyering
we're going to have to use it from within extent_copy, too. * src/copy.c (sparse_copy): New function, factored out of... (copy_reg): ...here. Remove now-unused locals.