<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/e67acca7c0b8e0d3d4dc801db90e284566a75fbd">https://github.com/macports/macports-legacy-support/commit/e67acca7c0b8e0d3d4dc801db90e284566a75fbd</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit e67acca7c0b8e0d3d4dc801db90e284566a75fbd
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Wed Jun 25 16:55:12 2025 -0700

<span style='display:block; white-space:pre;color:#404040;'>    test_fcntl: New test.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    This provides tests for a few fcntl() functions.  See the comments for
</span><span style='display:block; white-space:pre;color:#404040;'>    more details.
</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;'>    Without 10.4 ppc64 fix, fails on 10.4 ppc64 and passes on others.
</span><span style='display:block; white-space:pre;color:#404040;'>    With fix, passes on all platforms.
</span>---
 test/test_fcntl.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_fcntl.c b/test/test_fcntl.c
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..0fa00ff
</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_fcntl.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,116 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2025 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 tests some of the functions of fcntl().  Unfortunately, due to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * variadic nature of fcntl() and the lack of a corresponding vfcntl(), our
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * wrapper is forced to handle all possible commands just to get the correct
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * type for the third argument.  Including all commands in this test would
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * be massive, and some can't be tested without additional restrictions,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * so we simply try to cover as many argument types as possible.  We can't
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * easily test F_SETOWN or F_SETSIZE, but we can cover the none, int, and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * pointer cases of the argument type.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The only function of fcntl() that we actually modify in the library is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * F_GETPATH, and that one only for 10.4 ppc64.  It's already implicitly
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * tested via the fxattrlist tests, but we also test it here, which also
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * provides coverage for the "pointer" arg-type case.
</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 <errno.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <fcntl.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 <stdint.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;'>+
</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;'>+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, ret = 0, fd = -1, val;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *progname = basename(argv[0]);
</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 tpath[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char rpath[MAXPATHLEN], xpath[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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) snprintf(tpath, sizeof(tpath), "%s/%s-%u", TEST_TEMP, progname, pid);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) printf("%s starting.\n", progname);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  do {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (verbose) printf("  creating '%s'\n", tpath);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((fd = open(tpath, O_CREAT | O_RDWR, S_IRWXU)) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       printf("*** unable to open '%s': %s\n", tpath, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       break;
</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 (!realpath(tpath, rpath)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("  *** realpath() for '%s' failed: %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             tpath, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ret =1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</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 (verbose) printf("  testing F_SETFD(FD_CLOEXEC)\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("  *** fcntl(fd, F_SETFD, FD_CLOEXEC) failed: %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ret = 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 (verbose) printf("  testing F_GETFD\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((val = fcntl(fd, F_GETFD)) == -1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("  *** fcntl(fd, F_GETFD) failed: %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else if (val != FD_CLOEXEC) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("  *** F_GETFD returned %d, should be %d\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             val, FD_CLOEXEC);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ret = 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 (verbose) printf("  testing F_GETPATH\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((val = fcntl(fd, F_GETPATH, xpath)) == -1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("  *** fcntl(fd, F_GETPATH, xpath) failed: %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      xpath[MAXPATHLEN-1] = '\0';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (strcmp(xpath, rpath)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        printf("  *** F_GETPATH returned %s, should be %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               xpath, rpath);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ret = 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;'>+  } while (0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (fd >= 0) (void) close(fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) unlink(tpath);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  printf("%s %s.\n", progname, ret ? "failed" : "passed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span></pre><pre style='margin:0'>

</pre>