Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wait_must_be_interruptible.c 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <signal.h>
  4. #include <sys/wait.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. /* Expected order is:
  8. * Child signals parent
  9. * Parent got signal
  10. * Child will exit now
  11. *
  12. * The bug we test for: under strace -f, last two lines are swapped
  13. * because wait syscall is suspended by strace and thus can't be interrupted.
  14. */
  15. static const char msg1[] = "Child signals parent\n";
  16. static const char msg2[] = "Parent got signal\n";
  17. static const char msg3[] = "Child will exit now\n";
  18. static void
  19. handler(int s)
  20. {
  21. write(1, msg2, sizeof(msg2)-1);
  22. }
  23. static void
  24. test(void)
  25. {
  26. /* Note: in Linux, signal() installs handler with SA_RESTART flag,
  27. * therefore wait will be restarted.
  28. */
  29. signal(SIGALRM, handler);
  30. if (fork() == 0) {
  31. /* child */
  32. sleep(1);
  33. write(1, msg1, sizeof(msg1)-1);
  34. kill(getppid(), SIGALRM);
  35. sleep(1);
  36. write(1, msg3, sizeof(msg3)-1);
  37. _exit(0);
  38. }
  39. /* parent */
  40. wait(NULL);
  41. _exit(0);
  42. }
  43. int
  44. main(void)
  45. {
  46. char buf1[80];
  47. char buf2[80];
  48. char buf3[80];
  49. int pipefd[2];
  50. printf("Please run me under 'strace -f'\n");
  51. pipe(pipefd);
  52. if (fork() == 0) {
  53. if (pipefd[1] != 1) {
  54. dup2(pipefd[1], 1);
  55. close(pipefd[1]);
  56. }
  57. test();
  58. }
  59. if (pipefd[0] != 0) {
  60. dup2(pipefd[0], 0);
  61. close(pipefd[0]);
  62. }
  63. fgets(buf1, 80, stdin); printf("%s", buf1);
  64. fgets(buf2, 80, stdin); printf("%s", buf2);
  65. fgets(buf3, 80, stdin); printf("%s", buf3);
  66. if (strcmp(buf1, msg1) != 0
  67. || strcmp(buf2, msg2) != 0
  68. || strcmp(buf3, msg3) != 0
  69. ) {
  70. printf("ERROR! Expected order:\n%s%s%s", msg1, msg2, msg3);
  71. return 1;
  72. }
  73. printf("Good: wait seems to be correctly interrupted by signals\n");
  74. return 0;
  75. }