diff options
author | Rich Felker <dalias@aerifal.cx> | 2024-12-23 07:05:06 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2024-12-23 07:05:06 +0000 |
commit | d36e5bf83b601da15b2b4ab0cc225d3fb93ef489 (patch) | |
tree | 36bcfed01eeb1abcbd48b0dd50421f9b0b7a693c | |
parent | 561cd07dff8003251729569e5539b00698941697 (diff) | |
download | musl-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.
-rw-r--r-- | src/mq/x32/mq_open.c | 22 | ||||
-rw-r--r-- | src/mq/x32/mq_setattr.c | 14 |
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; +} |