diff options
Diffstat (limited to 'libc-top-half/musl/src/mq')
-rw-r--r-- | libc-top-half/musl/src/mq/mq_close.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_getattr.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_notify.c | 73 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_open.c | 19 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_receive.c | 6 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_send.c | 6 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_setattr.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_timedreceive.c | 24 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_timedsend.c | 24 | ||||
-rw-r--r-- | libc-top-half/musl/src/mq/mq_unlink.c | 16 |
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; +} |