terminate.py.in 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!@PYTHON@
  2. # This file is part of GNUnet.
  3. # (C) 2011, 2018 Christian Grothoff (and other contributing authors)
  4. #
  5. # GNUnet is free software: you can redistribute it and/or modify it
  6. # under the terms of the GNU Affero General Public License as published
  7. # by the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # GNUnet is distributed in the hope that it will be useful, but
  11. # WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. # SPDX-License-Identifier: AGPL3.0-or-later
  19. #
  20. # Utility module that implements safe process termination for W32.
  21. # For other platforms it's equivalent to Popen.kill ()
  22. # Requires pywin32 on W32.
  23. import sys
  24. import subprocess
  25. import os
  26. if os.name == 'nt':
  27. import win32api
  28. import win32process
  29. class dummyobj (object):
  30. pass
  31. def safe_terminate_process_by_pid(pid, code):
  32. if os.name == 'nt':
  33. p = dummyobj()
  34. p._handle = win32api.OpenProcess(2 | 1024 | 8 | 32 | 16, 0, pid)
  35. result = safe_terminate_process(p, code)
  36. win32api.CloseHandle(p._handle)
  37. return result
  38. else:
  39. # XXX (F821): Undefined name 'SIGKILL'
  40. return os.kill(int(pid), SIGKILL)
  41. def safe_terminate_process(proc, code):
  42. if os.name == 'nt':
  43. cp = win32api.GetCurrentProcess()
  44. result = False
  45. dupproc = win32api.DuplicateHandle(cp, proc._handle, cp, 2 | 1024 | 8 | 32 | 16, 0, 0)
  46. try:
  47. exitcode = win32process.GetExitCodeProcess(dupproc)
  48. if exitcode == 0x103:
  49. kernel32 = win32api.GetModuleHandle("kernel32")
  50. exitprocess = win32api.GetProcAddress(kernel32, "ExitProcess")
  51. th, tid = win32process.CreateRemoteThread(dupproc, None, 0, exitprocess, code, 0)
  52. win32api.CloseHandle(th)
  53. result = True
  54. else:
  55. result = True
  56. # except failed to get exit code? failed to get module handle?
  57. finally:
  58. win32api.CloseHandle(dupproc)
  59. return result
  60. else:
  61. return proc.kill()