<pre style='margin:0'>
Christopher Nielsen (mascguy) pushed a commit to branch master
in repository macports-legacy-support.
</pre>
<p><a href="https://github.com/macports/macports-legacy-support/commit/70d7fab8523920c7037669cba0fac2aed8d80981">https://github.com/macports/macports-legacy-support/commit/70d7fab8523920c7037669cba0fac2aed8d80981</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 70d7fab8523920c7037669cba0fac2aed8d80981
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Thu Jan 2 00:35:42 2025 -0800
<span style='display:block; white-space:pre;color:#404040;'> Add 10.6 copyfile manpage for 10.4 and 10.5.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This is taken from:
</span><span style='display:block; white-space:pre;color:#404040;'> https://github.com/apple-oss-distributions/copyfile/blob/copyfile-66.1/copyfile.3
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Almost verbatim, but with additions to indicate that QUARANTINE
</span><span style='display:block; white-space:pre;color:#404040;'> operations are unavailable on 10.4, and that ACL copying doesn't work
</span><span style='display:block; white-space:pre;color:#404040;'> in 10.4 Rosetta.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Adds manpage directory creation to Makefile, including missing case
</span><span style='display:block; white-space:pre;color:#404040;'> for the previously added 'which' manpage.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> TESTED:
</span><span style='display:block; white-space:pre;color:#404040;'> Manpages are installed as appropriate by the relevant targets.
</span>---
Makefile | 24 ++-
src/.gitignore | 1 +
src/copyfile.3 | 538 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 561 insertions(+), 2 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/Makefile b/Makefile
</span><span style='display:block; white-space:pre;color:#808080;'>index 17da30a..ca46bec 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/Makefile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/Makefile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -22,6 +22,7 @@ LIBDIR = $(PREFIX)/lib
</span> BINDIR = $(PREFIX)/bin
MANDIR = $(PREFIX)/share/man
MAN1DIR = $(MANDIR)/man1
<span style='display:block; white-space:pre;background:#e0ffe0;'>+MAN3DIR = $(MANDIR)/man3
</span> AREXT = .a
SOEXT = .dylib
LIBNAME = MacportsLegacySupport
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -113,6 +114,9 @@ ALLSLIBOBJS := $(SLIBOBJS) $(MULTISLIBOBJS)
</span> ADDOBJS := $(patsubst %.c,%$(SLIBOBJEXT),$(ADDSRCS))
ALLSYSLIBOBJS := $(ALLDLIBOBJS) $(ADDOBJS)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# Man pages
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+SRCMAN3S := $(wildcard $(SRCDIR)/*.3)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> # Defs for filtering out empty object files
#
# Some object files are logically empty, due to their content being
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -243,7 +247,8 @@ $(SOBJLIST): $(ALLSLIBOBJS)
</span> if [ ! -s $@ ]; then echo $(DUMMYOBJ) > $@; fi
# Make the directories separate targets to avoid collisions in parallel builds.
<span style='display:block; white-space:pre;background:#ffe0e0;'>-$(BUILDLIBDIR) $(DESTDIR)$(LIBDIR) $(TEST_TEMP):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+$(BUILDLIBDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(BINDIR) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ $(DESTDIR)$(MAN1DIR) $(DESTDIR)$(MAN3DIR) $(TEST_TEMP):
</span> $(MKINSTALLDIRS) $@
$(BUILDDLIBPATH): $(ALLDLIBOBJS) | $(BUILDLIBDIR)
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -309,6 +314,10 @@ $(TIGERPRGS): %: %.c
</span>
tiger-bins: $(TIGERPRGS)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# Dummy Leopard build target, so the Portfile can reference it in case
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# we need it later.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+leopard-bins:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> # Special clause for testing the cmath fix: Just need to verify that
# building succeeds or fails, not that the executable runs or what it
# produces. Note that for some reason all Clang compilers tested
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -435,9 +444,19 @@ install-syslib: $(BUILDSYSLIBPATH) | $(DESTDIR)$(LIBDIR)
</span> install-slib: $(BUILDSLIBPATH) | $(DESTDIR)$(LIBDIR)
$(INSTALL_DATA) $(BUILDSLIBPATH) $(DESTDIR)$(LIBDIR)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-install-tiger: $(TIGERPRGS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# We need a better way to handle OS-dependent manpage installs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Currently, the only cases are the Tiger-specific which.1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# and copyfile.3 for Tiger and Leopard, so we add the Tiger
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# case to the existing Tiger install, and add a new Leopard install.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+install-tiger: $(TIGERPRGS) | $(DESTDIR)$(BINDIR) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ $(DESTDIR)$(MAN1DIR) $(DESTDIR)$(MAN3DIR)
</span> $(INSTALL_PROGRAM) $(TIGERPRGS) $(DESTDIR)$(BINDIR)
$(INSTALL_MAN) $(TIGERMAN1S) $(DESTDIR)$(MAN1DIR)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ $(INSTALL_MAN) $(SRCMAN3S) $(DESTDIR)$(MAN3DIR)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+install-leopard: | $(DESTDIR)$(MAN3DIR)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ $(INSTALL_MAN) $(SRCMAN3S) $(DESTDIR)$(MAN3DIR)
</span>
test check: $(TESTRUNS) $(XTESTRUNS) test_cmath test_faccessat_setuid_msg
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -475,4 +494,5 @@ clean: $(MANRUNPREFIX)clean test_clean
</span> .PHONY: $(TESTRUNPREFIX)stat_all
.PHONY: install install-headers install-lib install-dlib install-slib
.PHONY: tiger-bins install-tiger
<span style='display:block; white-space:pre;background:#e0ffe0;'>+.PHONY: leopard-bins install-leopard
</span> .PHONY: allobjs dlibobjs slibobjs syslibobjs
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/.gitignore b/src/.gitignore
</span><span style='display:block; white-space:pre;color:#808080;'>index 62cc70a..92fce52 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/.gitignore
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/.gitignore
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -5,3 +5,4 @@
</span> !*.cc
!*.xxc
!Makefile
<span style='display:block; white-space:pre;background:#e0ffe0;'>+!*.[1-9]
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/copyfile.3 b/src/copyfile.3
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..b0edce8
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/copyfile.3
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,538 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.\"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.\" Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.\"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dd April 27, 2006
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dt COPYFILE 3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Os
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh NAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Nm copyfile , fcopyfile ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Nm copyfile_state_alloc , copyfile_state_free ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Nm copyfile_state_get , copyfile_state_set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Nd copy a file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh LIBRARY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Lb libc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh SYNOPSIS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.In copyfile.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile "const char *from" "const char *to" "copyfile_state_t state" "copyfile_flags_t flags"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile "int from" "int to" "copyfile_state_t state" "copyfile_flags_t flags"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft copyfile_state_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_alloc "void"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_free "copyfile_state_t state"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_get "copyfile_state_t state" "uint32_t flag" "void * dst"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_set "copyfile_state_t state" "uint32_t flag" "const void * src"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft typedef int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn (*copyfile_callback_t) "int what" "int stage" "copyfile_state_t state" "const char * src" "const char * dst" "void * ctx"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh DESCRIPTION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+These functions are used to copy a file's data and/or metadata. (Metadata
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+consists of permissions, extended attributes, access control lists, and so
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+forth.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_alloc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function initializes a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt copyfile_state_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+object (which is an opaque data type).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This object can be passed to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_get
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+can be used to manipulate the state (see below).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_free
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function is used to deallocate the object and its contents.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function can copy the named
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file to the named
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file; the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function does the same, but using the file descriptors of already-opened
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+files.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+If the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va state
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter is the return value from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_alloc ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will use the information from the state object; if it is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv NULL ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+then both functions will work normally, but less control will be available to the caller.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va flags
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter controls which contents are copied:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_XATTR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_ACL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the source file's access control lists (doesn't work on 10.4 Rosetta).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STAT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the source file's POSIX information (mode, modification time, etc.).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_XATTR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the source file's extended attributes.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_DATA
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the source file's data.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+These values may be or'd together; several convenience macros are provided:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_SECURITY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_SECURITY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the source file's POSIX and ACL information; equivalent to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv (COPYFILE_STAT|COPYFILE_ACL) .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_METADATA
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the metadata; equivalent to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv (COPYFILE_SECURITY|COPYFILE_XATTR) .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_ALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the entire file; equivalent to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv (COPYFILE_METADATA|COPYFILE_DATA) .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+functions can also have their behavior modified by the following flags:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_NOFOLLOW_SRC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_RECURSIVE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Causes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+to recursively copy a hierachy.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This flag is not used by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+see below for more information.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_CHECK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Return a bitmask (corresponding to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va flags
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+argument) indicating which contents would be copied; no data are actually
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copied. (E.g., if
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va flags
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+was set to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_CHECK|COPYFILE_METADATA ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file had extended attributes but no ACLs, the return value would be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_XATTR .)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_PACK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Serialize the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file. The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file is an AppleDouble-format file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_UNPACK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Unserialize the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file. The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file is an AppleDouble-format file; the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file will have the extended attributes, ACLs, resource fork, and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+FinderInfo data from the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file, regardless of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va flags
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+argument passed in.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_EXCL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Fail if the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file already exists. (This is only applicable for the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_NOFOLLOW_SRC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Do not follow the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file, if it is a symbolic link. (This is only applicable for the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_NOFOLLOW_DST
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Do not follow the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file, if it is a symbolic link. (This is only applicable for the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_MOVE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Unlink (remove) the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fa from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file. (This is only applicable for the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_UNLINK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Unlink the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file before starting. (This is only applicable for the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_NOFOLLOW
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This is a convenience macro, equivalent to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv (COPYFILE_NOFOLLOW_DST|COPYFILE_NOFOLLOW_SRC) .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_get
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+functions can be used to manipulate the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ft copyfile_state_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+object returned by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_alloc .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+In both functions, the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va dst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter's type depends on the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va flag
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter that is passed in.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_STATE_DST_FILENAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_SRC_FD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_DST_FD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Get or set the file descriptor associated with the source (or destination)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+If this has not been initialized yet, the value will be -2.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va dst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_get )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va src
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_set )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameters are pointers to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt int .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_SRC_FILENAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_DST_FILENAME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Get or set the filename associated with the source (or destination)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+file. If it has not been initialized yet, the value will be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv NULL .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+For
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_set ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va src
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter is a pointer to a C string
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(i.e.,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt char* );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+makes a private copy of this string.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+For
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_get
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+function, the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va dst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter is a pointer to a pointer to a C string
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(i.e.,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt char** );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+the returned value is a pointer to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va state 's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copy, and must not be modified or released.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_STATUS_CB
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Get or set the callback status function (currently
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+only used for recursive copies; see below for details).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va src
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter is a pointer to a function of type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt copyfile_callback_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(see above).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_STATUS_CTX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Get or set the context parameter for the status
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+call-back function (see below for details).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va src
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter is a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt void\ * .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_QUARANTINE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Get or set the quarantine information with the source file (not on 10.4).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va src
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter is a pointer to an opaque
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+object (type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt void\ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_STATE_COPIED
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Get the number of data bytes copied so far.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(Only valid for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_get ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+see below for more details about callbacks.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va dst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter is a pointer to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt off_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt off_t\ * ).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh Recursive Copies
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+When given the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_RECURSIVE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+flag,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(but not
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will use the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Xr fts 3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+functions to recursively descend into the source file-system object.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+It then calls
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+on each of the entries it finds that way.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+If a call-back function is given (using
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_STATE_STATUS_CB ),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+the call-back function will be called four times for each directory
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+object, and twice for all other objects. (Each directory will
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+be examined twice, once on entry -- before copying each of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+objects contained in the directory -- and once on exit -- after
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copying each object contained in the directory, in order to perform
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+some final cleanup.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The call-back function will have one of the following values
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+as the first argument, indicating what is being copied:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_RECURSE_DIR_CLEANUP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_RECURSE_FILE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The object being copied is a file (or, rather,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+something other than a directory).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_RECURSE_DIR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The object being copied is a directory, and is being
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+entered. (That is, none of the filesystem objects contained
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+within the directory have been copied yet.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_RECURSE_DIR_CLEANUP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The object being copied is a directory, and all of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+objects contained have been copied. At this stage, the destination directory
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+being copied will have any extra permissions that were added to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+allow the copying will be removed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_RECURSE_ERROR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+There was an error in processing an element of the source hierarchy;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+this happens when
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Xr fts 3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+returns an error or unknown file type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(Currently, the second argument to the call-back function will always
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_ERR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+in this case.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The second argument to the call-back function will indicate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+the stage of the copy, and will be one of the following values:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_FINISH
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_START
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Before copying has begun. The third
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter will be a newly-created
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt copyfile_state_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+object with the call-back function and context pre-loaded.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_FINISH
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+After copying has successfully finished.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_ERR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Indicates an error has happened at some stage. If the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+first argument to the call-back function is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_RECURSE_ERROR ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+then an error occurred while processing the source hierarchy;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+otherwise, it will indicate what type of object was being copied,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv errno
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will be set to indicate the error.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The fourth and fifth
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameters are the source and destination paths that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+are to be copied (or have been copied, or failed to copy, depending on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+the second argument).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The last argument to the call-back function will be the value
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_STATE_STATUS_CTX ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if any.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The call-back function is required to return one of the following
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+values:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_CONTINUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_CONTINUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The copy will continue as expected.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_SKIP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This object will be skipped, and the next object will
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+be processed. (Note that, when entering a directory.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+returning
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_SKIP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+from the call-back function will prevent the contents
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+of the directory from being copied.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_QUIT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The entire copy is aborted at this stage. Any filesystem
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+objects created up to this point will remain.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will return -1, but
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv errno
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will be unmodified.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The call-back function must always return one of the values listed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+above; if not, the results are undefined.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The call-back function will be called twice for each object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(and an additional two times for directory cleanup); the first
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+call will have a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ar stage
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_START ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+the second time, that value will be either
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_FINISH
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_ERR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+to indicate a successful completion, or an error during
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+processing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+In the event of an error, the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv errno
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+value will be set appropriately.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_PACK ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_UNPACK ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_MOVE ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_UNLINK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+flags are not used during a recursive copy, and will result
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+in an error being returned.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh Progress Callback
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+In addition to the recursive callbacks described above,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will also use a callback to report data (i.e.,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_DATA )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+progress. If given, the callback will be invoked on each
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Xr write 2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+call. The first argument to the callback function will be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_COPY_DATA .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The second argument will either be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_COPY_PROGRESS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(indicating that the write was successful), or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_ERR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(indicating that there was an error of some sort).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The amount of data bytes copied so far can be retrieved using
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile_state_get ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+with the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_STATE_COPIED
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+requestor (the argument type is a pointer to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Vt off_t ).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The return value for the data callback must be one of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width COPYFILE_CONTINUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_CONTINUE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The copy will continue as expected.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(In the case of error, it will attempt to write the data again.)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_SKIP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The data copy will be aborted, but without error.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Dv COPYFILE_QUIT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The data copy will be aborted; in the case of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_COPY_PROGRESS ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv errno
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will be set to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv ECANCELED .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+While the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va src
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va dst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameters will be passed in, they may be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv NULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+in the case of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh RETURN VALUES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Except when given the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_CHECK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+flag,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+return less than 0 on error, and 0 on success.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+All of the other functions return 0 on success, and less than 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+on error.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh WARNING
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Both
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+can copy symbolic links; there is a gap between when the source
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+link is examnined and the actual copy is started, and this can
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+be a potential security risk, especially if the process has
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+elevated privileges.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+When performing a recursive copy, if the source hierarchy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+changes while the copy is occurring, the results are undefined.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh ERRORS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn fcopyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will fail if:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bl -tag -width Er
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Bq Er EINVAL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+An invalid flag was passed in with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv COPYFILE_RECURSIVE .
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Bq Er EINVAL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+was a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv NULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+pointer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Bq Er EINVAL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Va to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+parameter to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+was a negative number.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Bq Er ENOMEM
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+A memory allocation failed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Bq Er ENOTSUP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The source file was not a directory, symbolic link, or regular file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.It Bq Er ECANCELED
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The copy was cancelled by callback.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.El
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+In addition, both functions may set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Dv errno
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+via an underlying library or system call.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh EXAMPLES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Bd -literal -offset indent
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Initialize a state variable */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile_state_t s;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+s = copyfile_state_alloc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Copy the data and extended attributes of one file to another */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile("/tmp/f1", "/tmp/f2", s, COPYFILE_DATA | COPYFILE_XATTR);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Convert a file to an AppleDouble file for serialization */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile("/tmp/f2", "/tmp/tmpfile", NULL, COPYFILE_ALL | COPYFILE_PACK);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Release the state variable */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile_state_free(s);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* A more complex way to call copyfile() */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+s = copyfile_state_alloc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile_state_set(s, COPYFILE_STATE_SRC_FILENAME, "/tmp/foo");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* One of src or dst must be set... rest can come from the state */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile(NULL, "/tmp/bar", s, COPYFILE_ALL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Now copy the same source file to another destination file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile(NULL, "/tmp/car", s, COPYFILE_ALL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile_state_free(s);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Remove extended attributes from a file */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+copyfile("/dev/null", "/tmp/bar", NULL, COPYFILE_XATTR);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Ed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh SEE ALSO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Xr listxattr 2 ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Xr getxattr 2 ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Xr setxattr 2 ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Xr acl 3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh BUGS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Both
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+functions lack a way to set the input or output block size.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Pp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Recursive copies do not honor hard links.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Sh HISTORY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+.Fn copyfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+API was introduced in Mac OS X 10.5.
</span></pre><pre style='margin:0'>
</pre>