diff options
| author | Kacper <kacper@mail.openlinux.dev> | 2025-12-07 20:10:31 +0100 |
|---|---|---|
| committer | Kacper <kacper@mail.openlinux.dev> | 2025-12-07 20:10:31 +0100 |
| commit | fc00c656c96528112d05cf0edf8631bd5eaea446 (patch) | |
| tree | a6e0e6c588191a8bd1c64afc3b7a258e3e66c236 /lib/libc/signal | |
Add build system scaffolding and libc headers
Diffstat (limited to 'lib/libc/signal')
| -rw-r--r-- | lib/libc/signal/kill.c | 7 | ||||
| -rw-r--r-- | lib/libc/signal/killpg.c | 13 | ||||
| -rw-r--r-- | lib/libc/signal/psiginfo.c | 6 | ||||
| -rw-r--r-- | lib/libc/signal/psignal.c | 9 | ||||
| -rw-r--r-- | lib/libc/signal/pthread_kill.c | 18 | ||||
| -rw-r--r-- | lib/libc/signal/pthread_sigmask.c | 23 | ||||
| -rw-r--r-- | lib/libc/signal/raise.c | 7 | ||||
| -rw-r--r-- | lib/libc/signal/sig2str.c | 33 | ||||
| -rw-r--r-- | lib/libc/signal/sigaction.c | 8 | ||||
| -rw-r--r-- | lib/libc/signal/sigaddset.c | 10 | ||||
| -rw-r--r-- | lib/libc/signal/sigemptyset.c | 10 | ||||
| -rw-r--r-- | lib/libc/signal/sigismember.c | 18 | ||||
| -rw-r--r-- | lib/libc/signal/signal.c | 14 | ||||
| -rw-r--r-- | lib/libc/signal/sigpending.c | 7 | ||||
| -rw-r--r-- | lib/libc/signal/sigprocmask.c | 17 | ||||
| -rw-r--r-- | lib/libc/signal/sigqueue.c | 15 | ||||
| -rw-r--r-- | lib/libc/signal/sigsuspend.c | 7 | ||||
| -rw-r--r-- | lib/libc/signal/sigtimedwait.c | 10 | ||||
| -rw-r--r-- | lib/libc/signal/sigwait.c | 14 | ||||
| -rw-r--r-- | lib/libc/signal/sigwaitinfo.c | 6 | ||||
| -rw-r--r-- | lib/libc/signal/str2sig.c | 52 |
21 files changed, 304 insertions, 0 deletions
diff --git a/lib/libc/signal/kill.c b/lib/libc/signal/kill.c new file mode 100644 index 00000000..d2a7ae68 --- /dev/null +++ b/lib/libc/signal/kill.c @@ -0,0 +1,7 @@ +#include <signal.h> +#include <syscall.h> + +int kill(pid_t pid, int sig) +{ + return syscall(kill, pid, sig); +} diff --git a/lib/libc/signal/killpg.c b/lib/libc/signal/killpg.c new file mode 100644 index 00000000..27b7a76a --- /dev/null +++ b/lib/libc/signal/killpg.c @@ -0,0 +1,13 @@ +#include <errno.h> +#include <signal.h> +#include <syscall.h> + +int killpg(pid_t pgrp, int sig) +{ + if (pgrp < 0) { + errno = EINVAL; + return -1; + } + + return kill(-pgrp, sig); +} diff --git a/lib/libc/signal/psiginfo.c b/lib/libc/signal/psiginfo.c new file mode 100644 index 00000000..47e10508 --- /dev/null +++ b/lib/libc/signal/psiginfo.c @@ -0,0 +1,6 @@ +#include <signal.h> + +void psiginfo(const siginfo_t *pinfo, const char *message) +{ + psignal(pinfo->si_signo, message); +} diff --git a/lib/libc/signal/psignal.c b/lib/libc/signal/psignal.c new file mode 100644 index 00000000..200b353c --- /dev/null +++ b/lib/libc/signal/psignal.c @@ -0,0 +1,9 @@ +#include <stdio.h> +#include <string.h> +#include <signal.h> + +void psignal(int signum, const char *message) +{ + fprintf(stderr, "%s%s%s\n", message ? message : "", message ? ": " : "", + strsignal(signum)); +} diff --git a/lib/libc/signal/pthread_kill.c b/lib/libc/signal/pthread_kill.c new file mode 100644 index 00000000..9323a869 --- /dev/null +++ b/lib/libc/signal/pthread_kill.c @@ -0,0 +1,18 @@ +#include <thread.h> +#include <asm-generic/signal.h> +#include <syscall.h> + +typedef struct __thread_self *pthread_t; + +int pthread_kill(pthread_t thread, int sig) +{ + if (sig < 0 || sig > _NSIG) { + return EINVAL; + } + + if (thread->tid == 0) { + return 0; + } + + return syscall(tkill, thread->tid, sig); +} diff --git a/lib/libc/signal/pthread_sigmask.c b/lib/libc/signal/pthread_sigmask.c new file mode 100644 index 00000000..1b83e1fe --- /dev/null +++ b/lib/libc/signal/pthread_sigmask.c @@ -0,0 +1,23 @@ +#include <errno.h> +#include <asm-generic/signal.h> +#include <libc.h> + +int sigdelset(sigset_t *, int); +int sigismember(const sigset_t *, int); +int sigprocmask(int, const sigset_t *restrict, sigset_t *restrict); + +int pthread_sigmask(int how, const sigset_t *restrict set, + sigset_t *restrict oset) +{ + sigset_t lset; + + if (set != NULL && (unlikely(sigismember(set, SIGRTMIN)) || + unlikely(sigismember(set, SIGRTMIN + 1)))) { + lset = *set; + sigdelset(&lset, SIGRTMIN); + sigdelset(&lset, SIGRTMIN + 1); + set = &lset; + } + + return sigprocmask(how, set, oset) == -1 ? errno : 0; +} diff --git a/lib/libc/signal/raise.c b/lib/libc/signal/raise.c new file mode 100644 index 00000000..3bdbc9cc --- /dev/null +++ b/lib/libc/signal/raise.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include <signal.h> + +int raise(int sig) +{ + return kill(getpid(), sig); +} diff --git a/lib/libc/signal/sig2str.c b/lib/libc/signal/sig2str.c new file mode 100644 index 00000000..209cb4c3 --- /dev/null +++ b/lib/libc/signal/sig2str.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <string.h> +#include <asm-generic/signal.h> +#include <__signal.h> + +int sig2str(int signum, char *str) +{ + if (signum >= SIGHUP && signum <= SIGSYS) { + strcpy(str, __sys_signame[signum - SIGHUP]); + return 0; + } + + if (signum == SIGRTMIN) { + strcpy(str, "SIGRTMIN"); + return 0; + } + + if (signum == SIGRTMAX) { + strcpy(str, "RTMAX"); + return 0; + } + + if (signum > SIGRTMIN && signum < SIGRTMAX) { + if (signum - SIGRTMIN <= SIGRTMAX - signum) { + sprintf(str, "RTMIN+%d", signum - SIGRTMIN); + } else { + sprintf(str, "RTMAX-%d", SIGRTMAX - signum); + } + return 0; + } + + return -1; +} diff --git a/lib/libc/signal/sigaction.c b/lib/libc/signal/sigaction.c new file mode 100644 index 00000000..f8377ebb --- /dev/null +++ b/lib/libc/signal/sigaction.c @@ -0,0 +1,8 @@ +#include <signal.h> +#include <syscall.h> + +int sigaction(int sig, const struct sigaction *restrict act, + struct sigaction *restrict oact) +{ + return syscall(rt_sigaction, sig, act, oact, sizeof(sigset_t)); +} diff --git a/lib/libc/signal/sigaddset.c b/lib/libc/signal/sigaddset.c new file mode 100644 index 00000000..33e74bd0 --- /dev/null +++ b/lib/libc/signal/sigaddset.c @@ -0,0 +1,10 @@ +#include <signal.h> + +int sigaddset(sigset_t *set, int signo) +{ + if (signo < 1 || signo > 64) { + return -1; + } + *set |= (1ULL << (signo - 1)); + return 0; +} diff --git a/lib/libc/signal/sigemptyset.c b/lib/libc/signal/sigemptyset.c new file mode 100644 index 00000000..6552bf45 --- /dev/null +++ b/lib/libc/signal/sigemptyset.c @@ -0,0 +1,10 @@ +#include <signal.h> + +int sigemptyset(sigset_t *set) +{ + if (!set) + return -1; + *set = 0; + + return 0; +} diff --git a/lib/libc/signal/sigismember.c b/lib/libc/signal/sigismember.c new file mode 100644 index 00000000..8adf5fab --- /dev/null +++ b/lib/libc/signal/sigismember.c @@ -0,0 +1,18 @@ +#include <asm-generic/signal.h> + +typedef __UINT64_TYPE__ __sigset_t; + +#define __sigmask(sig) (((__sigset_t)1) << ((sig) - 1)) +#define __sigismember(set, sig) \ + (__extension__({ \ + __sigset_t __mask = __sigmask(sig); \ + *(set) & __mask ? 1 : 0; \ + })) + +int sigismember(const __sigset_t *set, int signo) +{ + if (signo < 1 || signo > _NSIG) + return -1; + + return __sigismember((const __sigset_t *)set, signo); +} diff --git a/lib/libc/signal/signal.c b/lib/libc/signal/signal.c new file mode 100644 index 00000000..c2f578eb --- /dev/null +++ b/lib/libc/signal/signal.c @@ -0,0 +1,14 @@ +#include <signal.h> + +void (*signal(int sig, void (*func)(int)))(int) +{ + struct sigaction act, oact; + + act.sa_handler = func; + act.sa_flags = SA_RESTART; + + if (sigaction(sig, &act, &oact) < 0) + return SIG_ERR; + + return oact.sa_handler; +} diff --git a/lib/libc/signal/sigpending.c b/lib/libc/signal/sigpending.c new file mode 100644 index 00000000..b57f4adf --- /dev/null +++ b/lib/libc/signal/sigpending.c @@ -0,0 +1,7 @@ +#include <signal.h> +#include <syscall.h> + +int sigpending(sigset_t *set) +{ + return syscall(rt_sigpending, set); +} diff --git a/lib/libc/signal/sigprocmask.c b/lib/libc/signal/sigprocmask.c new file mode 100644 index 00000000..54063b9d --- /dev/null +++ b/lib/libc/signal/sigprocmask.c @@ -0,0 +1,17 @@ +#include <signal.h> +#include <syscall.h> + +int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset) +{ + long ret; + sigset_t oldset = { 0 }; + + ret = syscall(rt_sigprocmask, how, set, &oldset, sizeof(sigset_t)); + + if (ret < 0) + return -1; + + if (oset) + *oset = oldset; + return 0; +} diff --git a/lib/libc/signal/sigqueue.c b/lib/libc/signal/sigqueue.c new file mode 100644 index 00000000..9e5b6ddd --- /dev/null +++ b/lib/libc/signal/sigqueue.c @@ -0,0 +1,15 @@ +#include <signal.h> +#include <errno.h> + +int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old) +{ + int r = pthread_sigmask(how, set, old); + + if (r == 0) { + return r; + } + + errno = r; + + return -1; +} diff --git a/lib/libc/signal/sigsuspend.c b/lib/libc/signal/sigsuspend.c new file mode 100644 index 00000000..1e6b88a6 --- /dev/null +++ b/lib/libc/signal/sigsuspend.c @@ -0,0 +1,7 @@ +#include <signal.h> +#include <syscall.h> + +int sigsuspend(const sigset_t *sigmask) +{ + return syscall(rt_sigsuspend, sigmask, sizeof(sigset_t)); +} diff --git a/lib/libc/signal/sigtimedwait.c b/lib/libc/signal/sigtimedwait.c new file mode 100644 index 00000000..d55a4310 --- /dev/null +++ b/lib/libc/signal/sigtimedwait.c @@ -0,0 +1,10 @@ +#include <signal.h> +#include <syscall.h> + +#define _NSIG 64 + +int sigtimedwait(const sigset_t *restrict set, siginfo_t *restrict info, + const struct timespec *restrict timeout) +{ + return syscall(rt_sigtimedwait, set, info, timeout, _NSIG / 8); +} diff --git a/lib/libc/signal/sigwait.c b/lib/libc/signal/sigwait.c new file mode 100644 index 00000000..59b0dd6c --- /dev/null +++ b/lib/libc/signal/sigwait.c @@ -0,0 +1,14 @@ +#include <signal.h> + +int sigwait(const sigset_t *restrict mask, int *restrict sig) +{ + siginfo_t si; + + if (sigtimedwait(mask, &si, 0) < 0) { + return -1; + } + + *sig = si.si_signo; + + return 0; +} diff --git a/lib/libc/signal/sigwaitinfo.c b/lib/libc/signal/sigwaitinfo.c new file mode 100644 index 00000000..bb51f8b5 --- /dev/null +++ b/lib/libc/signal/sigwaitinfo.c @@ -0,0 +1,6 @@ +#include <signal.h> + +int sigwaitinfo(const sigset_t *restrict mask, siginfo_t *restrict si) +{ + return sigtimedwait(mask, si, 0); +} diff --git a/lib/libc/signal/str2sig.c b/lib/libc/signal/str2sig.c new file mode 100644 index 00000000..288948d7 --- /dev/null +++ b/lib/libc/signal/str2sig.c @@ -0,0 +1,52 @@ +#include <__signal.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <asm-generic/signal.h> + +int str2sig(const char *restrict str, int *restrict pnum) +{ + for (size_t i = SIGHUP; i <= SIGSYS; ++i) { + if (!strcmp(str, __sys_signame[i])) { + *pnum = i; + return 0; + } + } + + if (strcmp(str, "RTMIN") == 0) { + *pnum = SIGRTMIN; + return 0; + } + + if (strcmp(str, "RTMAX") == 0) { + *pnum = SIGRTMAX; + return 0; + } + + int base = 0; + if (strncmp(str, "RTMIN+", 6) == 0) { + base = SIGRTMIN; + str += 5; + } else if (strncmp(str, "RTMAX-", 6) == 0) { + base = SIGRTMAX; + str += 5; + } + + char *end = NULL; + errno = 0; + int offset = strtol(str, &end, 10); + if (errno || *end) { + return -1; + } + + int result = base + offset; + bool regular = (base == 0 && result >= SIGHUP && result <= SIGSYS); + bool realtime = (result >= SIGRTMIN && result <= SIGRTMAX); + if (!regular && !realtime) { + return -1; + } + + *pnum = result; + return 0; +} |
