test-sigaction-fork 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/bin/sh
  2. exec guile -q -s "$0" "$@"
  3. !#
  4. ;;; test-sigaction-fork --- Signal thread vs. fork, again.
  5. ;;;
  6. ;;; Copyright (C) 2024 Free Software Foundation, Inc.
  7. ;;;
  8. ;;; This library is free software; you can redistribute it and/or
  9. ;;; modify it under the terms of the GNU Lesser General Public
  10. ;;; License as published by the Free Software Foundation; either
  11. ;;; version 3 of the License, or (at your option) any later version.
  12. ;;;
  13. ;;; This library is distributed in the hope that it will be useful,
  14. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. ;;; Lesser General Public License for more details.
  17. ;;;
  18. ;;; You should have received a copy of the GNU Lesser General Public
  19. ;;; License along with this library; if not, write to the Free Software
  20. ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. ;;; Test the bug described at <https://bugs.gnu.org/68087>: the signal
  22. ;;; thread would not be restarted after a call to 'primitive-fork',
  23. ;;; leading signals to be silently ignored.
  24. (use-modules (ice-9 match))
  25. (define signals-handled
  26. ;; List of signals handled.
  27. '())
  28. (define parent
  29. ;; PID of the parent process.
  30. (getpid))
  31. (unless (provided? 'fork)
  32. (exit 77))
  33. ;; This call spawns the signal delivery thread as a side effect.
  34. (sigaction SIGALRM
  35. (lambda (signal)
  36. (call-with-blocked-asyncs
  37. (lambda ()
  38. (set! signals-handled
  39. (cons `(first-handler . ,(getpid))
  40. signals-handled))))))
  41. (kill (getpid) SIGALRM)
  42. (while (null? signals-handled) ;let the async run
  43. (sleep 1))
  44. (match (primitive-fork)
  45. (0
  46. (pk 'child (getpid) signals-handled)
  47. (kill (getpid) SIGALRM) ;first handler
  48. (sleep 1) ;let the async run
  49. (sigaction SIGALRM
  50. (lambda (signal)
  51. (call-with-blocked-asyncs
  52. (lambda ()
  53. (set! signals-handled
  54. (cons `(second-handler . ,(getpid))
  55. signals-handled))))))
  56. (kill (getpid) SIGALRM) ;second handler
  57. (sleep 1) ;give asyncs one more chance to run
  58. (format (current-error-port) "signals handled by the child + parent: ~s~%"
  59. signals-handled)
  60. (exit (equal? signals-handled
  61. `((second-handler . ,(getpid))
  62. (first-handler . ,(getpid))
  63. (first-handler . ,parent)))))
  64. (child
  65. (kill (getpid) SIGALRM) ;first handler
  66. (sleep 1) ;give asyncs one more chance to run
  67. (format (current-error-port) "signals handled by the parent: ~s~%"
  68. signals-handled)
  69. (exit (and (equal? signals-handled
  70. `((first-handler . ,parent)
  71. (first-handler . ,parent)))
  72. (zero? (cdr (waitpid child)))))))
  73. ;;; Local Variables:
  74. ;;; mode: scheme
  75. ;;; End: