TestSigWait.cpp 4.6 KB

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