summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/mq
diff options
context:
space:
mode:
Diffstat (limited to 'libc-top-half/musl/src/mq')
-rw-r--r--libc-top-half/musl/src/mq/mq_close.c7
-rw-r--r--libc-top-half/musl/src/mq/mq_getattr.c7
-rw-r--r--libc-top-half/musl/src/mq/mq_notify.c73
-rw-r--r--libc-top-half/musl/src/mq/mq_open.c19
-rw-r--r--libc-top-half/musl/src/mq/mq_receive.c6
-rw-r--r--libc-top-half/musl/src/mq/mq_send.c6
-rw-r--r--libc-top-half/musl/src/mq/mq_setattr.c7
-rw-r--r--libc-top-half/musl/src/mq/mq_timedreceive.c24
-rw-r--r--libc-top-half/musl/src/mq/mq_timedsend.c24
-rw-r--r--libc-top-half/musl/src/mq/mq_unlink.c16
10 files changed, 189 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/mq/mq_close.c b/libc-top-half/musl/src/mq/mq_close.c
new file mode 100644
index 0000000..a61f094
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_close.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_close(mqd_t mqd)
+{
+ return syscall(SYS_close, mqd);
+}
diff --git a/libc-top-half/musl/src/mq/mq_getattr.c b/libc-top-half/musl/src/mq/mq_getattr.c
new file mode 100644
index 0000000..dce1806
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_getattr.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_getattr(mqd_t mqd, struct mq_attr *attr)
+{
+ return mq_setattr(mqd, 0, attr);
+}
diff --git a/libc-top-half/musl/src/mq/mq_notify.c b/libc-top-half/musl/src/mq/mq_notify.c
new file mode 100644
index 0000000..221591c
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_notify.c
@@ -0,0 +1,73 @@
+#include <mqueue.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <unistd.h>
+#include "syscall.h"
+
+struct args {
+ pthread_barrier_t barrier;
+ int sock;
+ const struct sigevent *sev;
+};
+
+static void *start(void *p)
+{
+ struct args *args = p;
+ char buf[32];
+ ssize_t n;
+ int s = args->sock;
+ void (*func)(union sigval) = args->sev->sigev_notify_function;
+ union sigval val = args->sev->sigev_value;
+
+ pthread_barrier_wait(&args->barrier);
+ n = recv(s, buf, sizeof(buf), MSG_NOSIGNAL|MSG_WAITALL);
+ close(s);
+ if (n==sizeof buf && buf[sizeof buf - 1] == 1)
+ func(val);
+ return 0;
+}
+
+int mq_notify(mqd_t mqd, const struct sigevent *sev)
+{
+ struct args args = { .sev = sev };
+ pthread_attr_t attr;
+ pthread_t td;
+ int s;
+ struct sigevent sev2;
+ static const char zeros[32];
+
+ if (!sev || sev->sigev_notify != SIGEV_THREAD)
+ return syscall(SYS_mq_notify, mqd, sev);
+
+ s = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, 0);
+ if (s < 0) return -1;
+ args.sock = s;
+
+ if (sev->sigev_notify_attributes) attr = *sev->sigev_notify_attributes;
+ else pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_barrier_init(&args.barrier, 0, 2);
+
+ if (pthread_create(&td, &attr, start, &args)) {
+ __syscall(SYS_close, s);
+ errno = EAGAIN;
+ return -1;
+ }
+
+ pthread_barrier_wait(&args.barrier);
+ pthread_barrier_destroy(&args.barrier);
+
+ sev2.sigev_notify = SIGEV_THREAD;
+ sev2.sigev_signo = s;
+ sev2.sigev_value.sival_ptr = (void *)&zeros;
+
+ if (syscall(SYS_mq_notify, mqd, &sev2) < 0) {
+ pthread_cancel(td);
+ __syscall(SYS_close, s);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libc-top-half/musl/src/mq/mq_open.c b/libc-top-half/musl/src/mq/mq_open.c
new file mode 100644
index 0000000..aa91d58
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_open.c
@@ -0,0 +1,19 @@
+#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;
+ 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 *);
+ va_end(ap);
+ }
+ return syscall(SYS_mq_open, name, flags, mode, attr);
+}
diff --git a/libc-top-half/musl/src/mq/mq_receive.c b/libc-top-half/musl/src/mq/mq_receive.c
new file mode 100644
index 0000000..0b1bb4e
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_receive.c
@@ -0,0 +1,6 @@
+#include <mqueue.h>
+
+ssize_t mq_receive(mqd_t mqd, char *msg, size_t len, unsigned *prio)
+{
+ return mq_timedreceive(mqd, msg, len, prio, 0);
+}
diff --git a/libc-top-half/musl/src/mq/mq_send.c b/libc-top-half/musl/src/mq/mq_send.c
new file mode 100644
index 0000000..1acb1b7
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_send.c
@@ -0,0 +1,6 @@
+#include <mqueue.h>
+
+int mq_send(mqd_t mqd, const char *msg, size_t len, unsigned prio)
+{
+ return mq_timedsend(mqd, msg, len, prio, 0);
+}
diff --git a/libc-top-half/musl/src/mq/mq_setattr.c b/libc-top-half/musl/src/mq/mq_setattr.c
new file mode 100644
index 0000000..eae022e
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_setattr.c
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_setattr(mqd_t mqd, const struct mq_attr *restrict new, struct mq_attr *restrict old)
+{
+ return syscall(SYS_mq_getsetattr, mqd, new, old);
+}
diff --git a/libc-top-half/musl/src/mq/mq_timedreceive.c b/libc-top-half/musl/src/mq/mq_timedreceive.c
new file mode 100644
index 0000000..f41b664
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_timedreceive.c
@@ -0,0 +1,24 @@
+#include <mqueue.h>
+#include <errno.h>
+#include "syscall.h"
+
+#define IS32BIT(x) !((x)+0x80000000ULL>>32)
+#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63))
+
+ssize_t mq_timedreceive(mqd_t mqd, char *restrict msg, size_t len, unsigned *restrict prio, const struct timespec *restrict at)
+{
+#ifdef SYS_mq_timedreceive_time64
+ time_t s = at ? at->tv_sec : 0;
+ long ns = at ? at->tv_nsec : 0;
+ long r = -ENOSYS;
+ if (SYS_mq_timedreceive == SYS_mq_timedreceive_time64 || !IS32BIT(s))
+ r = __syscall_cp(SYS_mq_timedreceive_time64, mqd, msg, len, prio,
+ at ? ((long long []){at->tv_sec, at->tv_nsec}) : 0);
+ if (SYS_mq_timedreceive == SYS_mq_timedreceive_time64 || r != -ENOSYS)
+ return __syscall_ret(r);
+ return syscall_cp(SYS_mq_timedreceive, mqd, msg, len, prio,
+ at ? ((long[]){CLAMP(s), ns}) : 0);
+#else
+ return syscall_cp(SYS_mq_timedreceive, mqd, msg, len, prio, at);
+#endif
+}
diff --git a/libc-top-half/musl/src/mq/mq_timedsend.c b/libc-top-half/musl/src/mq/mq_timedsend.c
new file mode 100644
index 0000000..56cfcbb
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_timedsend.c
@@ -0,0 +1,24 @@
+#include <mqueue.h>
+#include <errno.h>
+#include "syscall.h"
+
+#define IS32BIT(x) !((x)+0x80000000ULL>>32)
+#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63))
+
+int mq_timedsend(mqd_t mqd, const char *msg, size_t len, unsigned prio, const struct timespec *at)
+{
+#ifdef SYS_mq_timedsend_time64
+ time_t s = at ? at->tv_sec : 0;
+ long ns = at ? at->tv_nsec : 0;
+ long r = -ENOSYS;
+ if (SYS_mq_timedsend == SYS_mq_timedsend_time64 || !IS32BIT(s))
+ r = __syscall_cp(SYS_mq_timedsend_time64, mqd, msg, len, prio,
+ at ? ((long long []){at->tv_sec, at->tv_nsec}) : 0);
+ if (SYS_mq_timedsend == SYS_mq_timedsend_time64 || r != -ENOSYS)
+ return __syscall_ret(r);
+ return syscall_cp(SYS_mq_timedsend, mqd, msg, len, prio,
+ at ? ((long[]){CLAMP(s), ns}) : 0);
+#else
+ return syscall_cp(SYS_mq_timedsend, mqd, msg, len, prio, at);
+#endif
+}
diff --git a/libc-top-half/musl/src/mq/mq_unlink.c b/libc-top-half/musl/src/mq/mq_unlink.c
new file mode 100644
index 0000000..6a08a4c
--- /dev/null
+++ b/libc-top-half/musl/src/mq/mq_unlink.c
@@ -0,0 +1,16 @@
+#include <mqueue.h>
+#include <errno.h>
+#include "syscall.h"
+
+int mq_unlink(const char *name)
+{
+ int ret;
+ if (*name == '/') name++;
+ ret = __syscall(SYS_mq_unlink, name);
+ if (ret < 0) {
+ if (ret == -EPERM) ret = -EACCES;
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}