<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/b9f83ccea85a7b3695d18ec74fe74825aae2989a">https://github.com/macports/macports-legacy-support/commit/b9f83ccea85a7b3695d18ec74fe74825aae2989a</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit b9f83ccea85a7b3695d18ec74fe74825aae2989a
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Mon Mar 3 16:13:54 2025 -0800
<span style='display:block; white-space:pre;color:#404040;'> Implement recvmsg() variants.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This provides the UNIX2003 and/or NOCANCEL variants of the recvmsg()
</span><span style='display:block; white-space:pre;color:#404040;'> wrapper.
</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 tests for the different variants.
</span>---
src/packet.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 98 insertions(+), 12 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/packet.c b/src/packet.c
</span><span style='display:block; white-space:pre;color:#808080;'>index ffd3aef..bc6828c 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/packet.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/packet.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -17,6 +17,37 @@
</span> /* MP support header */
#include "MacportsLegacySupport.h"
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Handle the suffixed variants of recvmsg(), even if no fixes being applied.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Define a macro listing all variants supported by the OS/arch.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 10.4 lacks the NOCANCEL variant.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 64-bit builds lack the UNIX2003 variant.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The macro defined here only includes the non-basic variants, so that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * the inclusion of the basic case can be optional.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Note that additional aliases appeared in 10.7+, but since this code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * doesn't currently apply there, we ignore that.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Although 10.4 doesn't have NOCANCEL, builds with later SDKs may
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * reference it, so we need to provide it anyway. The runtime lookup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * falls back to the basic version if it's missing.
</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 !__MPLS_64BIT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MOST_VARIANTS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ VARIANT_ENT(posix,$UNIX2003) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ VARIANT_ENT(nocancel,$NOCANCEL$UNIX2003)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#else /* __MPLS_64BIT */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MOST_VARIANTS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ VARIANT_ENT(nocancel,$NOCANCEL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* __MPLS_64BIT */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #if __MPLS_LIB_CMSG_ROSETTA_FIX__
/*
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -46,6 +77,16 @@
</span> * types. If so, the code could be extended appropriately.
*/
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The non-noncancelable variants are the default. This results in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * generating the "unadorned" names, which we augment with explicit suffixes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * where needed. Similarly, we use the non-POSIX form in 32-bit builds.
</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 !__MPLS_64BIT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define _NONSTD_SOURCE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #include <dlfcn.h>
#include <stddef.h>
#include <stdlib.h>
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -104,28 +145,67 @@ fix_cmsg_endianness(struct msghdr *msghdr)
</span> }
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-ssize_t
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-recvmsg(int socket, struct msghdr *message, int flags)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define ALL_VARIANTS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ VARIANT_ENT(basic,) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ MOST_VARIANTS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define VARIANT_ENT(name,sfx) fv_##name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef enum fv_type {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ALL_VARIANTS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} fv_type_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef VARIANT_ENT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define VARIANT_ENT(name,sfx) "recvmsg" #sfx,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static const char * const fv_names[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ALL_VARIANTS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef VARIANT_ENT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef __typeof__(recvmsg) recvmsg_fn_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define VARIANT_ENT(name,sfx) NULL,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static recvmsg_fn_t *fv_adrs[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ALL_VARIANTS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef VARIANT_ENT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Function to get address of the OS function, with fallback for 10.4 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static recvmsg_fn_t *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+sys_recvmsg(fv_type_t fvtype)
</span> {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- static __typeof__(recvmsg) *sys_recvmsg = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- static int is_rosetta = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ssize_t ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Return cached value if available */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (fv_adrs[fvtype]) return fv_adrs[fvtype];
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (!sys_recvmsg) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (!(sys_recvmsg = dlsym(RTLD_NEXT, "recvmsg"))){
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Something's badly wrong if we can't find the function */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- abort();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Or cache and return address of desired variant if available */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((fv_adrs[fvtype] = dlsym(RTLD_NEXT, fv_names[fvtype]))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return fv_adrs[fvtype];
</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 not, try for basic version (10.4) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((fv_adrs[fvtype] = dlsym(RTLD_NEXT, fv_names[fv_basic]))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return fv_adrs[fvtype];
</span> }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Something's badly wrong if we can't find the function at all */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ abort();
</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;'>+/* Common internal function for all variants */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static ssize_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+recvmsg_internal(int socket, struct msghdr *message, int flags,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fv_type_t fvtype)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static int is_rosetta = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ssize_t ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* Determine Rosettaness, if not already known */
if (!is_rosetta) is_rosetta = check_rosetta();
/* Just pass through if not Rosetta */
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (is_rosetta < 0) return (*sys_recvmsg)(socket, message, flags);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (is_rosetta < 0) return (*sys_recvmsg(fvtype))(socket, message, flags);
</span>
/* Running under Rosetta - need to intercept return */
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ret = (*sys_recvmsg)(socket, message, flags);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = (*sys_recvmsg(fvtype))(socket, message, flags);
</span>
/* If error or no CMSG data, just return */
if (ret < 0 || !message->msg_controllen) return ret;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -136,4 +216,10 @@ recvmsg(int socket, struct msghdr *message, int flags)
</span> return ret;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#define VARIANT_ENT(name,sfx) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ssize_t recvmsg##sfx(int socket, struct msghdr *message, int flags) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ { return recvmsg_internal(socket, message, flags, fv_##name); }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ALL_VARIANTS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef VARIANT_ENT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #endif /* __MPLS_LIB_CMSG_ROSETTA_FIX__ */
</pre><pre style='margin:0'>
</pre>