25static int death_ready[2], death_go[2], death_report[2];
32static void death_handler(
int signal, siginfo_t* info,
void* context) {
34 struct death_notice notice = {signal, info->si_pid};
35 (void)write(death_report[1], ¬ice,
sizeof(notice));
39static void read_bounded(
int fd,
void* data,
size_t size) {
40 struct pollfd pollfd = {fd, POLLIN, 0};
41 if (poll(&pollfd, 1, 5000) != 1 || read(fd, data, size) != (ssize_t)size) {
46static void* death_creator(
void* unused) {
49 if (prctl(PR_GET_PDEATHSIG, &setting, 0UL, 0UL, 0UL) || setting) {
57 pid_t parent = getppid();
58 struct sigaction action = {.sa_sigaction = death_handler, .sa_flags = SA_SIGINFO};
59 sigemptyset(&action.sa_mask);
60 if (sigaction(SIGUSR1, &action, NULL)) {
63 if (death_mode != 2 && prctl(PR_SET_PDEATHSIG, SIGUSR1, 0UL, 0UL, 0UL)) {
66 if (death_mode == 1 && prctl(PR_SET_PDEATHSIG, 0UL, 0UL, 0UL, 0UL)) {
69 if (write(death_ready[1],
"r", 1) != 1) {
77 for (
int i = 0; getppid() == parent && i < 1000; ++i) {
80 if (getppid() == parent ||
81 (death_mode == 2 && prctl(PR_SET_PDEATHSIG, SIGUSR1, 0UL, 0UL, 0UL))) {
85 struct death_notice notice = {0, parent};
86 if (write(death_report[1], ¬ice,
sizeof(notice)) !=
sizeof(notice)) {
92 read_bounded(death_go[0], &go, 1);
93 return (
void*)(intptr_t)child;
96static void test_creator_exit(
int threaded,
int mode) {
98 if (pipe(death_ready) || pipe(death_go) || pipe(death_report)) {
102 pid_t parent = getpid();
104 if (pthread_create(&thread, NULL, death_creator, NULL)) {
118 read_bounded(death_ready[0], &ready, 1);
119 if (write(death_go[1],
"g", 1) != 1) {
125 if (pthread_join(thread, &child)) {
128 if (waitpid((pid_t)(intptr_t)child, &status, 0) < 0 || status) {
131 }
else if (waitpid(parent, &status, 0) != parent || status) {
134 struct death_notice notice;
135 read_bounded(death_report[0], ¬ice,
sizeof(notice));
136 if (notice.signal != (mode ? 0 : SIGUSR1) || notice.sender != parent) {
139 for (
int i = 0; i < 2; ++i) {
140 close(death_ready[i]);
142 close(death_report[i]);
146int test_prctl_exec(
void) {
148 return prctl(PR_GET_PDEATHSIG, &signal, 0UL, 0UL, 0UL) || signal != SIGUSR1;
151static void test_parent_death(
void) {
153 if (prctl(PR_SET_PDEATHSIG, SIGUSR1, 0UL, 0UL, 0UL) ||
154 prctl(PR_GET_PDEATHSIG, &signal, 0UL, 0UL, 0UL) || signal != SIGUSR1) {
158 if (prctl(PR_SET_PDEATHSIG, 65UL, 0UL, 0UL, 0UL) != -1 || errno != EINVAL) {
162 if (prctl(PR_SET_PDEATHSIG, -1UL, 0UL, 0UL, 0UL) != -1 || errno != EINVAL) {
166 if (prctl(PR_GET_PDEATHSIG, (
void*)-1, 0UL, 0UL, 0UL) != -1 || errno != EFAULT) {
169 pid_t child = fork();
171 if (prctl(PR_GET_PDEATHSIG, &signal, 0UL, 0UL, 0UL) || signal) {
174 if (prctl(PR_SET_PDEATHSIG, SIGUSR1, 0UL, 0UL, 0UL)) {
177 execl(
"/proc/self/exe",
"testsuite",
"--prctl-exec", NULL);
181 if (child < 0 || waitpid(child, &status, 0) != child || status) {
185 test_creator_exit(1, 0);
186 if (prctl(PR_GET_PDEATHSIG, &signal, 0UL, 0UL, 0UL) || signal != SIGUSR1) {
192 if (prctl(PR_SET_PDEATHSIG, SIGUSR1, 0UL, 0UL, 0UL)) {
195 (void)setfsuid(65534);
196 if (prctl(PR_GET_PDEATHSIG, &signal, 0UL, 0UL, 0UL) || signal) {
200 if (prctl(PR_SET_PDEATHSIG, SIGUSR1, 0UL, 0UL, 0UL) || setresuid(0, 65534, 0) ||
201 prctl(PR_GET_PDEATHSIG, &signal, 0UL, 0UL, 0UL) || signal) {
207 if (child < 0 || waitpid(child, &status, 0) != child || status) {
210 if (prctl(PR_SET_PDEATHSIG, 0UL, 0UL, 0UL, 0UL) ||
211 prctl(PR_GET_PDEATHSIG, &signal, 0UL, 0UL, 0UL) || signal) {
214 test_creator_exit(0, 0);
215 test_creator_exit(0, 1);
216 test_creator_exit(0, 2);
217 puts(
"PDEATH-CONTRACT PASS");
220void test_prctl(
void) {
221 puts(
"Testing prctl(2) thread names... ");
224 char original[16] = {0};
226 if (prctl(PR_GET_NAME, original, 0UL, 0UL, 0UL))
229 if (prctl(PR_SET_NAME,
"0123456789abcdef-long", 0UL, 0UL, 0UL))
231 memset(returned, 0xA5,
sizeof(returned));
232 if (prctl(PR_GET_NAME, returned, 0UL, 0UL, 0UL) || memcmp(returned,
"0123456789abcde", 15) ||
237 if (prctl(-1, 0UL, 0UL, 0UL, 0UL) != -1 || errno != EINVAL)
240 if (prctl(PR_GET_NAME, (
char*)-1, 0UL, 0UL, 0UL) != -1 || errno != EFAULT)
243 if (prctl(PR_SET_NAME, (
char*)-1, 0UL, 0UL, 0UL) != -1 || errno != EFAULT)
246 if (prctl(PR_SET_NAME, original, 0UL, 0UL, 0UL))