summaryrefslogtreecommitdiff
path: root/src/mq
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2024-12-23 07:05:06 +0000
committerRich Felker <dalias@aerifal.cx>2024-12-23 07:05:06 +0000
commitd36e5bf83b601da15b2b4ab0cc225d3fb93ef489 (patch)
tree36bcfed01eeb1abcbd48b0dd50421f9b0b7a693c /src/mq
parent561cd07dff8003251729569e5539b00698941697 (diff)
downloadmusl-d36e5bf83b601da15b2b4ab0cc225d3fb93ef489.tar.gz
mq: add x32-specific implementations to work around mismatched kernel ABI
the kernel mq_attr structure has 8 64-bit longs instead of 8 32-bit longs. it's not clear that this is the nicest way to implement the fix, but the concept (translation) is right, and the details can be changed later if desired.
Diffstat (limited to 'src/mq')
-rw-r--r--src/mq/x32/mq_open.c22
-rw-r--r--src/mq/x32/mq_setattr.c14
2 files changed, 36 insertions, 0 deletions
diff --git a/src/mq/x32/mq_open.c b/src/mq/x32/mq_open.c
new file mode 100644
index 00000000..23481959
--- /dev/null
+++ b/src/mq/x32/mq_open.c
@@ -0,0 +1,22 @@
+#include <mqueue.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+mqd_t mq_open(const char *name, int flags, ...)
+{
+ mode_t mode = 0;
+ struct mq_attr *attr = 0;
+ long long attrbuf[8];
+ if (*name == '/') name++;
+ if (flags & O_CREAT) {
+ va_list ap;
+ va_start(ap, flags);
+ mode = va_arg(ap, mode_t);
+ attr = va_arg(ap, struct mq_attr *);
+ if (attr) for (int i=0; i<8; i++)
+ attrbuf[i] = *(long *)((char *)attr + i*sizeof(long));
+ va_end(ap);
+ }
+ return syscall(SYS_mq_open, name, flags, mode, attr?attrbuf:0);
+}
diff --git a/src/mq/x32/mq_setattr.c b/src/mq/x32/mq_setattr.c
new file mode 100644
index 00000000..0c631175
--- /dev/null
+++ b/src/mq/x32/mq_setattr.c
@@ -0,0 +1,14 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_setattr(mqd_t mqd, const struct mq_attr *restrict new, struct mq_attr *restrict old)
+{
+ long long attr[8];
+ if (new) for (int i=0; i<8; i++)
+ attr[i] = *(long *)((char *)new + i*sizeof(long));
+ int ret = __syscall(SYS_mq_getsetattr, mqd, new?attr:0, old?attr:0);
+ if (ret < 0) return __syscall_ret(ret);
+ if (old) for (int i=0; i<8; i++)
+ *(long *)((char *)old + i*sizeof(long)) = attr[i];
+ return 0;
+}