<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/33f41f427b585af129fabcf66c029af2452a407d">https://github.com/macports/macports-legacy-support/commit/33f41f427b585af129fabcf66c029af2452a407d</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 33f41f427b585af129fabcf66c029af2452a407d
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Fri Dec 27 13:59:17 2024 -0800

<span style='display:block; white-space:pre;color:#404040;'>    Add test for copyfile().
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    This is a simple test of copyfile(), along with a couple of
</span><span style='display:block; white-space:pre;color:#404040;'>    copyfile_state_set()/copyfile_state_get() options.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Includes access to copyfile()'s secret debug mode.
</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;'>    Passes on all platforms, except 10.4 Rosetta.
</span>---
 test/test_copyfile.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_copyfile.c b/test/test_copyfile.c
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..4ad3521
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/test/test_copyfile.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,132 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2024 Frederick H. G. Wright II <fw@fwright.net>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Permission to use, copy, modify, and distribute this software for any
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * purpose with or without fee is hereby granted, provided that the above
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * copyright notice and this permission notice appear in all copies.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This provides a limited test of copyfile(), mainly to test the operation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * of copyfile_state_get() for COPYFILE_STATE_COPIED, which is added by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * legacy-support in some cases.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <copyfile.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <libgen.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/param.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/stat.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef TEST_TEMP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define TEST_TEMP "/dev/null"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Secret debug flag for copyfile() */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define COPYFILE_DEBUG (1U<<31)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Dummy copyfile context to test set/get */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct dummy_ctx_s {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int dummy;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} dummy_ctx_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+main(int argc, char *argv[])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int verbose = 0, debug = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *debugenv;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  copyfile_state_t state;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  dummy_ctx_t ctx = {0}, *ctxp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  pid_t pid = getpid();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *name = basename(argv[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  off_t copied;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  struct stat ourstat;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char dest[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (argc > 1 && !strcmp(argv[1], "-v")) verbose = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (argc > 1 && !strcmp(argv[1], "-d")) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    verbose = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    debug = COPYFILE_DEBUG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) snprintf(dest, sizeof(dest), "%s/%s-%u", TEST_TEMP, name, pid);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("%s starting.\n", name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("  %s -> %s\n", argv[0], dest);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (debug) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((debugenv = getenv("COPYFILE_DEBUG"))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("    Debugging enabled, level (COPYFILE_DEBUG) = %s\n", debugenv);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("    Debugging enabled, COPYFILE_DEBUG env var not set\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (stat(argv[0], &ourstat)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("unable to stat() self");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) printf("  size is %ld bytes\n", (long) ourstat.st_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  state = copyfile_state_alloc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!state) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("copyfile_state_alloc() failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Check that we can set the context pointer */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (copyfile_state_set(state, COPYFILE_STATE_STATUS_CTX, &ctx)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("unable to set COPYFILE_STATE_STATUS_CTX");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (copyfile(argv[0], dest, state, COPYFILE_ALL | debug)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("copyfile() failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (copyfile_state_get(state, COPYFILE_STATE_COPIED, &copied)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("unable to get COPYFILE_STATE_COPIED");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (copied != ourstat.st_size) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "  COPYFILE_STATE_COPIED = %ld bytes"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    " mismatches st_size = %ld bytes\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (long) copied, (long) ourstat.st_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Check that we can get the context pointer */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (copyfile_state_get(state, COPYFILE_STATE_STATUS_CTX, &ctxp)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("unable to get COPYFILE_STATE_STATUS_CTX");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Check that it matches what we set */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (ctxp != &ctx) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "  COPYFILE_STATE_STATUS_CTX set to 0x%lX"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    " reads back as 0x%lX\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (unsigned long) &ctx, (unsigned long) ctxp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (copyfile_state_free(state)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("copyfile_state_free() failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  printf("%s succeeded.\n", name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span></pre><pre style='margin:0'>

</pre>