1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <bits/ensure.h>
#include <mlibc/posix-sysdeps.hpp>
#include <mlibc/tcb.hpp>
int sigsuspend(const sigset_t *sigmask) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigsuspend, -1);
// This is guaranteed to return an error (EINTR most probably)
errno = mlibc::sys_sigsuspend(sigmask);
return -1;
}
int pthread_sigmask(int how, const sigset_t *__restrict set, sigset_t *__restrict retrieve) {
if(!mlibc::sys_sigprocmask) {
MLIBC_MISSING_SYSDEP();
return ENOSYS;
}
if(int e = mlibc::sys_sigprocmask(how, set, retrieve); e) {
return e;
}
return 0;
}
int pthread_kill(pthread_t thread, int sig) {
auto tcb = reinterpret_cast<Tcb *>(thread);
auto pid = getpid();
if(!mlibc::sys_tgkill) {
MLIBC_MISSING_SYSDEP();
return ENOSYS;
}
if(int e = mlibc::sys_tgkill(pid, tcb->tid, sig); e) {
return e;
}
return 0;
}
int sigaction(int signum, const struct sigaction *__restrict act, struct sigaction *__restrict oldact) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigaction, -1);
if(int e = mlibc::sys_sigaction(signum, act, oldact); e) {
errno = e;
return -1;
}
return 0;
}
int siginterrupt(int sig, int flag) {
int ret;
struct sigaction act;
sigaction(sig, NULL, &act);
if (flag)
act.sa_flags &= ~SA_RESTART;
else
act.sa_flags |= SA_RESTART;
ret = sigaction(sig, &act, NULL);
return ret;
}
int kill(pid_t pid, int number) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_kill, -1);
if(int e = mlibc::sys_kill(pid, number); e) {
errno = e;
return -1;
}
return 0;
}
int killpg(pid_t pgrp, int sig) {
if(pgrp > 1) {
return kill(-pgrp, sig);
}
errno = EINVAL;
return -1;
}
int sigtimedwait(const sigset_t *__restrict set, siginfo_t *__restrict info, const struct timespec *__restrict timeout) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigtimedwait, -1);
int signo;
if (int e = sysdep(set, info, timeout, &signo)) {
errno = e;
return -1;
}
return signo;
}
int sigwaitinfo(const sigset_t *__restrict set, siginfo_t *__restrict info) {
// NOTE: This assumes the sysdep behavior noted in mlibc/posix-sysdeps.hpp
return sigtimedwait(set, info, nullptr);
}
int sigwait(const sigset_t *__restrict set, int *__restrict sig) {
if (int e = sigwaitinfo(set, nullptr); e < 0) {
return e;
} else {
if (sig)
*sig = e;
return 0;
}
}
int sigpending(sigset_t *set) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigpending, -1);
if(int e = sysdep(set)) {
errno = e;
return -1;
}
return 0;
}
int sigaltstack(const stack_t *__restrict ss, stack_t *__restrict oss) {
if (ss && ss->ss_size < MINSIGSTKSZ && !(ss->ss_flags & SS_DISABLE)) {
errno = ENOMEM;
return -1;
}
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigaltstack, -1);
if (int e = mlibc::sys_sigaltstack(ss, oss); e) {
errno = e;
return -1;
}
return 0;
}
#if __MLIBC_GLIBC_OPTION
int sigisemptyset(const sigset_t *set) {
return !(*set);
}
#endif // __MLIBC_GLIBC_OPTION
int sigqueue(pid_t, int, const union sigval) {
__ensure(!"sigqueue() not implemented");
__builtin_unreachable();
}
|