test-signal.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to
  5. * deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  7. * sell copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  19. * IN THE SOFTWARE.
  20. */
  21. #include "uv.h"
  22. #include "task.h"
  23. #ifndef _WIN32
  24. #include <unistd.h>
  25. #endif
  26. TEST_IMPL(kill_invalid_signum) {
  27. uv_pid_t pid;
  28. pid = uv_os_getpid();
  29. ASSERT(uv_kill(pid, -1) == UV_EINVAL);
  30. #ifdef _WIN32
  31. /* NSIG is not available on all platforms. */
  32. ASSERT(uv_kill(pid, NSIG) == UV_EINVAL);
  33. #endif
  34. ASSERT(uv_kill(pid, 4096) == UV_EINVAL);
  35. MAKE_VALGRIND_HAPPY();
  36. return 0;
  37. }
  38. /* For Windows we test only signum handling */
  39. #ifdef _WIN32
  40. static void signum_test_cb(uv_signal_t* handle, int signum) {
  41. FATAL("signum_test_cb should not be called");
  42. }
  43. TEST_IMPL(win32_signum_number) {
  44. uv_signal_t signal;
  45. uv_loop_t* loop;
  46. loop = uv_default_loop();
  47. uv_signal_init(loop, &signal);
  48. ASSERT(uv_signal_start(&signal, signum_test_cb, 0) == UV_EINVAL);
  49. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGINT) == 0);
  50. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGBREAK) == 0);
  51. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGHUP) == 0);
  52. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGWINCH) == 0);
  53. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGILL) == 0);
  54. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGABRT_COMPAT) == 0);
  55. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGFPE) == 0);
  56. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGSEGV) == 0);
  57. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGTERM) == 0);
  58. ASSERT(uv_signal_start(&signal, signum_test_cb, SIGABRT) == 0);
  59. ASSERT(uv_signal_start(&signal, signum_test_cb, -1) == UV_EINVAL);
  60. ASSERT(uv_signal_start(&signal, signum_test_cb, NSIG) == UV_EINVAL);
  61. ASSERT(uv_signal_start(&signal, signum_test_cb, 1024) == UV_EINVAL);
  62. MAKE_VALGRIND_HAPPY();
  63. return 0;
  64. }
  65. #else
  66. #include <errno.h>
  67. #include <signal.h>
  68. #include <stdarg.h>
  69. #include <stdio.h>
  70. #include <stdlib.h>
  71. #include <string.h>
  72. #include <unistd.h>
  73. #define NSIGNALS 10
  74. struct timer_ctx {
  75. unsigned int ncalls;
  76. uv_timer_t handle;
  77. int signum;
  78. };
  79. struct signal_ctx {
  80. enum { CLOSE, STOP, NOOP } stop_or_close;
  81. unsigned int ncalls;
  82. uv_signal_t handle;
  83. int signum;
  84. int one_shot;
  85. };
  86. static void signal_cb(uv_signal_t* handle, int signum) {
  87. struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
  88. ASSERT(signum == ctx->signum);
  89. if (++ctx->ncalls == NSIGNALS) {
  90. if (ctx->stop_or_close == STOP)
  91. uv_signal_stop(handle);
  92. else if (ctx->stop_or_close == CLOSE)
  93. uv_close((uv_handle_t*)handle, NULL);
  94. else
  95. ASSERT(0);
  96. }
  97. }
  98. static void signal_cb_one_shot(uv_signal_t* handle, int signum) {
  99. struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
  100. ASSERT(signum == ctx->signum);
  101. ASSERT(++ctx->ncalls == 1);
  102. if (ctx->stop_or_close == CLOSE)
  103. uv_close((uv_handle_t*)handle, NULL);
  104. }
  105. static void timer_cb(uv_timer_t* handle) {
  106. struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
  107. raise(ctx->signum);
  108. if (++ctx->ncalls == NSIGNALS)
  109. uv_close((uv_handle_t*)handle, NULL);
  110. }
  111. static void start_watcher(uv_loop_t* loop,
  112. int signum,
  113. struct signal_ctx* ctx,
  114. int one_shot) {
  115. ctx->ncalls = 0;
  116. ctx->signum = signum;
  117. ctx->stop_or_close = CLOSE;
  118. ctx->one_shot = one_shot;
  119. ASSERT(0 == uv_signal_init(loop, &ctx->handle));
  120. if (one_shot)
  121. ASSERT(0 == uv_signal_start_oneshot(&ctx->handle, signal_cb_one_shot, signum));
  122. else
  123. ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
  124. }
  125. static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) {
  126. ctx->ncalls = 0;
  127. ctx->signum = signum;
  128. ASSERT(0 == uv_timer_init(loop, &ctx->handle));
  129. ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5));
  130. }
  131. TEST_IMPL(we_get_signal) {
  132. struct signal_ctx sc;
  133. struct timer_ctx tc;
  134. uv_loop_t* loop;
  135. loop = uv_default_loop();
  136. start_timer(loop, SIGCHLD, &tc);
  137. start_watcher(loop, SIGCHLD, &sc, 0);
  138. sc.stop_or_close = STOP; /* stop, don't close the signal handle */
  139. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  140. ASSERT(tc.ncalls == NSIGNALS);
  141. ASSERT(sc.ncalls == NSIGNALS);
  142. start_timer(loop, SIGCHLD, &tc);
  143. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  144. ASSERT(tc.ncalls == NSIGNALS);
  145. ASSERT(sc.ncalls == NSIGNALS);
  146. sc.ncalls = 0;
  147. sc.stop_or_close = CLOSE; /* now close it when it's done */
  148. uv_signal_start(&sc.handle, signal_cb, SIGCHLD);
  149. start_timer(loop, SIGCHLD, &tc);
  150. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  151. ASSERT(tc.ncalls == NSIGNALS);
  152. ASSERT(sc.ncalls == NSIGNALS);
  153. MAKE_VALGRIND_HAPPY();
  154. return 0;
  155. }
  156. TEST_IMPL(we_get_signals) {
  157. struct signal_ctx sc[4];
  158. struct timer_ctx tc[2];
  159. uv_loop_t* loop;
  160. unsigned int i;
  161. loop = uv_default_loop();
  162. start_watcher(loop, SIGUSR1, sc + 0, 0);
  163. start_watcher(loop, SIGUSR1, sc + 1, 0);
  164. start_watcher(loop, SIGUSR2, sc + 2, 0);
  165. start_watcher(loop, SIGUSR2, sc + 3, 0);
  166. start_timer(loop, SIGUSR1, tc + 0);
  167. start_timer(loop, SIGUSR2, tc + 1);
  168. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  169. for (i = 0; i < ARRAY_SIZE(sc); i++)
  170. ASSERT(sc[i].ncalls == NSIGNALS);
  171. for (i = 0; i < ARRAY_SIZE(tc); i++)
  172. ASSERT(tc[i].ncalls == NSIGNALS);
  173. MAKE_VALGRIND_HAPPY();
  174. return 0;
  175. }
  176. TEST_IMPL(we_get_signal_one_shot) {
  177. struct signal_ctx sc;
  178. struct timer_ctx tc;
  179. uv_loop_t* loop;
  180. loop = uv_default_loop();
  181. start_timer(loop, SIGCHLD, &tc);
  182. start_watcher(loop, SIGCHLD, &sc, 1);
  183. sc.stop_or_close = NOOP;
  184. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  185. ASSERT(tc.ncalls == NSIGNALS);
  186. ASSERT(sc.ncalls == 1);
  187. start_timer(loop, SIGCHLD, &tc);
  188. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  189. ASSERT(sc.ncalls == 1);
  190. sc.ncalls = 0;
  191. sc.stop_or_close = CLOSE; /* now close it when it's done */
  192. uv_signal_start_oneshot(&sc.handle, signal_cb_one_shot, SIGCHLD);
  193. start_timer(loop, SIGCHLD, &tc);
  194. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  195. ASSERT(tc.ncalls == NSIGNALS);
  196. ASSERT(sc.ncalls == 1);
  197. MAKE_VALGRIND_HAPPY();
  198. return 0;
  199. }
  200. TEST_IMPL(we_get_signals_mixed) {
  201. struct signal_ctx sc[4];
  202. struct timer_ctx tc;
  203. uv_loop_t* loop;
  204. loop = uv_default_loop();
  205. /* 2 one-shot */
  206. start_timer(loop, SIGCHLD, &tc);
  207. start_watcher(loop, SIGCHLD, sc + 0, 1);
  208. start_watcher(loop, SIGCHLD, sc + 1, 1);
  209. sc[0].stop_or_close = CLOSE;
  210. sc[1].stop_or_close = CLOSE;
  211. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  212. ASSERT(tc.ncalls == NSIGNALS);
  213. ASSERT(sc[0].ncalls == 1);
  214. ASSERT(sc[1].ncalls == 1);
  215. /* 2 one-shot, 1 normal then remove normal */
  216. start_timer(loop, SIGCHLD, &tc);
  217. start_watcher(loop, SIGCHLD, sc + 0, 1);
  218. start_watcher(loop, SIGCHLD, sc + 1, 1);
  219. sc[0].stop_or_close = CLOSE;
  220. sc[1].stop_or_close = CLOSE;
  221. start_watcher(loop, SIGCHLD, sc + 2, 0);
  222. uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
  223. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  224. ASSERT(tc.ncalls == NSIGNALS);
  225. ASSERT(sc[0].ncalls == 1);
  226. ASSERT(sc[1].ncalls == 1);
  227. ASSERT(sc[2].ncalls == 0);
  228. /* 2 normal, 1 one-shot then remove one-shot */
  229. start_timer(loop, SIGCHLD, &tc);
  230. start_watcher(loop, SIGCHLD, sc + 0, 0);
  231. start_watcher(loop, SIGCHLD, sc + 1, 0);
  232. sc[0].stop_or_close = CLOSE;
  233. sc[1].stop_or_close = CLOSE;
  234. start_watcher(loop, SIGCHLD, sc + 2, 1);
  235. uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
  236. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  237. ASSERT(tc.ncalls == NSIGNALS);
  238. ASSERT(sc[0].ncalls == NSIGNALS);
  239. ASSERT(sc[1].ncalls == NSIGNALS);
  240. ASSERT(sc[2].ncalls == 0);
  241. /* 2 normal, 2 one-shot then remove 2 normal */
  242. start_timer(loop, SIGCHLD, &tc);
  243. start_watcher(loop, SIGCHLD, sc + 0, 0);
  244. start_watcher(loop, SIGCHLD, sc + 1, 0);
  245. start_watcher(loop, SIGCHLD, sc + 2, 1);
  246. start_watcher(loop, SIGCHLD, sc + 3, 1);
  247. sc[2].stop_or_close = CLOSE;
  248. sc[3].stop_or_close = CLOSE;
  249. uv_close((uv_handle_t*)&(sc[0]).handle, NULL);
  250. uv_close((uv_handle_t*)&(sc[1]).handle, NULL);
  251. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  252. ASSERT(tc.ncalls == NSIGNALS);
  253. ASSERT(sc[0].ncalls == 0);
  254. ASSERT(sc[1].ncalls == 0);
  255. ASSERT(sc[2].ncalls == 1);
  256. ASSERT(sc[2].ncalls == 1);
  257. /* 1 normal, 1 one-shot, 2 normal then remove 1st normal, 2nd normal */
  258. start_timer(loop, SIGCHLD, &tc);
  259. start_watcher(loop, SIGCHLD, sc + 0, 0);
  260. start_watcher(loop, SIGCHLD, sc + 1, 1);
  261. start_watcher(loop, SIGCHLD, sc + 2, 0);
  262. start_watcher(loop, SIGCHLD, sc + 3, 0);
  263. sc[3].stop_or_close = CLOSE;
  264. uv_close((uv_handle_t*)&(sc[0]).handle, NULL);
  265. uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
  266. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  267. ASSERT(tc.ncalls == NSIGNALS);
  268. ASSERT(sc[0].ncalls == 0);
  269. ASSERT(sc[1].ncalls == 1);
  270. ASSERT(sc[2].ncalls == 0);
  271. ASSERT(sc[3].ncalls == NSIGNALS);
  272. MAKE_VALGRIND_HAPPY();
  273. return 0;
  274. }
  275. #endif /* _WIN32 */