UnixSignalHandlerRegistration.cs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using Mono.Unix.Native;
  2. using System;
  3. using System.Runtime.InteropServices;
  4. namespace ARMeilleure.Signal
  5. {
  6. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  7. unsafe struct SigSet
  8. {
  9. fixed long sa_mask[16];
  10. }
  11. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  12. struct SigAction
  13. {
  14. public IntPtr sa_handler;
  15. public SigSet sa_mask;
  16. public int sa_flags;
  17. public IntPtr sa_restorer;
  18. }
  19. static class UnixSignalHandlerRegistration
  20. {
  21. private const int SA_SIGINFO = 0x00000004;
  22. [DllImport("libc", SetLastError = true)]
  23. private static extern int sigaction(int signum, ref SigAction sigAction, out SigAction oldAction);
  24. [DllImport("libc", SetLastError = true)]
  25. private static extern int sigemptyset(ref SigSet set);
  26. public static SigAction RegisterExceptionHandler(IntPtr action)
  27. {
  28. SigAction sig = new SigAction
  29. {
  30. sa_handler = action,
  31. sa_flags = SA_SIGINFO
  32. };
  33. sigemptyset(ref sig.sa_mask);
  34. int result = sigaction((int)Signum.SIGSEGV, ref sig, out SigAction old);
  35. if (result != 0)
  36. {
  37. throw new InvalidOperationException($"Could not register sigaction. Error: {result}");
  38. }
  39. return old;
  40. }
  41. public static bool RestoreExceptionHandler(SigAction oldAction)
  42. {
  43. return sigaction((int)Signum.SIGSEGV, ref oldAction, out SigAction _) == 0;
  44. }
  45. }
  46. }