Serenity Operating System
at master 179 lines 4.7 kB view raw
1/* 2 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8#include <signal.h> 9#include <time.h> 10#include <unistd.h> 11 12TEST_CASE(sigwait) 13{ 14 sigset_t mask; 15 16 int rc = sigemptyset(&mask); 17 EXPECT_EQ(rc, 0); 18 rc = sigaddset(&mask, SIGUSR1); 19 EXPECT_EQ(rc, 0); 20 rc = sigprocmask(SIG_BLOCK, &mask, nullptr); 21 EXPECT_EQ(rc, 0); 22 23 int child_pid = fork(); 24 EXPECT(child_pid >= 0); 25 if (child_pid == 0) { 26 sleep(1); 27 kill(getppid(), SIGUSR1); 28 exit(EXIT_SUCCESS); 29 } else { 30 int sig; 31 rc = sigwait(&mask, &sig); 32 EXPECT_EQ(rc, 0); 33 EXPECT_EQ(sig, SIGUSR1); 34 } 35 36 // cancel pending signal 37 struct sigaction act_ignore = { { SIG_IGN }, 0, 0 }; 38 rc = sigaction(SIGUSR1, &act_ignore, nullptr); 39 EXPECT_EQ(rc, 0); 40 rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr); 41 EXPECT_EQ(rc, 0); 42 struct sigaction act_default = { { SIG_DFL }, 0, 0 }; 43 rc = sigaction(SIGUSR1, &act_default, nullptr); 44 EXPECT_EQ(rc, 0); 45 sigset_t pending; 46 rc = sigpending(&pending); 47 EXPECT_EQ(rc, 0); 48 EXPECT_EQ(pending, 0u); 49} 50 51TEST_CASE(sigwaitinfo) 52{ 53 sigset_t mask; 54 55 int rc = sigemptyset(&mask); 56 EXPECT_EQ(rc, 0); 57 rc = sigaddset(&mask, SIGUSR1); 58 EXPECT_EQ(rc, 0); 59 rc = sigprocmask(SIG_BLOCK, &mask, nullptr); 60 EXPECT_EQ(rc, 0); 61 62 int child_pid = fork(); 63 EXPECT(child_pid >= 0); 64 if (child_pid == 0) { 65 sleep(1); 66 kill(getppid(), SIGUSR1); 67 exit(EXIT_SUCCESS); 68 } else { 69 siginfo_t info; 70 rc = sigwaitinfo(&mask, &info); 71 EXPECT_EQ(rc, SIGUSR1); 72 EXPECT_EQ(info.si_signo, SIGUSR1); 73 } 74 75 // cancel pending signal 76 struct sigaction act_ignore = { { SIG_IGN }, 0, 0 }; 77 rc = sigaction(SIGUSR1, &act_ignore, nullptr); 78 EXPECT_EQ(rc, 0); 79 rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr); 80 EXPECT_EQ(rc, 0); 81 struct sigaction act_default = { { SIG_DFL }, 0, 0 }; 82 rc = sigaction(SIGUSR1, &act_default, nullptr); 83 EXPECT_EQ(rc, 0); 84 sigset_t pending; 85 rc = sigpending(&pending); 86 EXPECT_EQ(rc, 0); 87 EXPECT_EQ(pending, 0u); 88} 89 90TEST_CASE(sigtimedwait_normal) 91{ 92 sigset_t mask; 93 94 int rc = sigemptyset(&mask); 95 EXPECT_EQ(rc, 0); 96 rc = sigaddset(&mask, SIGUSR1); 97 EXPECT_EQ(rc, 0); 98 rc = sigprocmask(SIG_BLOCK, &mask, nullptr); 99 EXPECT_EQ(rc, 0); 100 101 int child_pid = fork(); 102 EXPECT(child_pid >= 0); 103 if (child_pid == 0) { 104 sleep(1); 105 kill(getppid(), SIGUSR1); 106 exit(EXIT_SUCCESS); 107 } else { 108 siginfo_t info; 109 struct timespec timeout = { .tv_sec = 2, .tv_nsec = 0 }; 110 rc = sigtimedwait(&mask, &info, &timeout); 111 EXPECT_EQ(rc, SIGUSR1); 112 EXPECT_EQ(info.si_signo, SIGUSR1); 113 } 114 115 // cancel pending signal 116 struct sigaction act_ignore = { { SIG_IGN }, 0, 0 }; 117 rc = sigaction(SIGUSR1, &act_ignore, nullptr); 118 EXPECT_EQ(rc, 0); 119 rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr); 120 EXPECT_EQ(rc, 0); 121 struct sigaction act_default = { { SIG_DFL }, 0, 0 }; 122 rc = sigaction(SIGUSR1, &act_default, nullptr); 123 EXPECT_EQ(rc, 0); 124 sigset_t pending; 125 rc = sigpending(&pending); 126 EXPECT_EQ(rc, 0); 127 EXPECT_EQ(pending, 0u); 128} 129 130TEST_CASE(sigtimedwait_poll) 131{ 132 sigset_t mask; 133 134 int rc = sigemptyset(&mask); 135 EXPECT_EQ(rc, 0); 136 rc = sigaddset(&mask, SIGUSR1); 137 EXPECT_EQ(rc, 0); 138 rc = sigprocmask(SIG_BLOCK, &mask, nullptr); 139 EXPECT_EQ(rc, 0); 140 141 struct timespec poll_timeout = { .tv_sec = 0, .tv_nsec = 0 }; 142 rc = sigtimedwait(&mask, nullptr, &poll_timeout); 143 EXPECT_EQ(rc, -1); 144 EXPECT_EQ(errno, EAGAIN); 145 146 kill(getpid(), SIGUSR1); 147 148 siginfo_t info; 149 rc = sigtimedwait(&mask, &info, &poll_timeout); 150 EXPECT_EQ(rc, SIGUSR1); 151 EXPECT_EQ(info.si_signo, SIGUSR1); 152 153 // cancel pending signal 154 struct sigaction act_ignore = { { SIG_IGN }, 0, 0 }; 155 rc = sigaction(SIGUSR1, &act_ignore, nullptr); 156 EXPECT_EQ(rc, 0); 157 rc = sigprocmask(SIG_UNBLOCK, &mask, nullptr); 158 EXPECT_EQ(rc, 0); 159 struct sigaction act_default = { { SIG_DFL }, 0, 0 }; 160 rc = sigaction(SIGUSR1, &act_default, nullptr); 161 EXPECT_EQ(rc, 0); 162 sigset_t pending; 163 rc = sigpending(&pending); 164 EXPECT_EQ(rc, 0); 165 EXPECT_EQ(pending, 0u); 166} 167 168TEST_CASE(sigtimedwait_timeout) 169{ 170 sigset_t mask; 171 int rc = sigemptyset(&mask); 172 EXPECT_EQ(rc, 0); 173 rc = sigaddset(&mask, SIGUSR1); 174 EXPECT_EQ(rc, 0); 175 struct timespec timeout = { .tv_sec = 1, .tv_nsec = 0 }; 176 rc = sigtimedwait(&mask, nullptr, &timeout); 177 EXPECT_EQ(rc, -1); 178 EXPECT_EQ(errno, EAGAIN); 179}