def kill(signal, *pids)
case signal
when 'SIGINT', 'INT'
signal = 2
when 'SIGBRK', 'BRK'
signal = 3
when 'SIGKILL', 'KILL'
signal = 9
when 0..9
else
raise ProcessError, "Invalid signal '#{signal}'"
end
killed_pids = []
pids.each{ |pid|
if pid == 0
pid = Process.pid
end
if signal == 0
access = PROCESS_QUERY_INFORMATION|PROCESS_VM_READ
handle = OpenProcess(access, 0 , pid)
else
handle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
end
case signal
when 0
if handle != 0
killed_pids.push(pid)
CloseHandle(handle)
else
if GetLastError() == ERROR_ACCESS_DENIED
killed_pids.push(pid)
else
raise ProcessError, get_last_error
end
end
when 2
if GenerateConsoleCtrlEvent(CTRL_C_EVENT, pid)
killed_pids.push(pid)
end
when 3
if GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid)
killed_pids.push(pid)
end
when 9
if TerminateProcess(handle, pid)
CloseHandle(handle)
killed_pids.push(pid)
@child_pids.delete(pid)
else
raise ProcessError, get_last_error
end
else
if handle != 0
thread_id = [0].pack('L')
dll = 'kernel32'
proc = 'ExitProcess'
thread = CreateRemoteThread(
handle,
0,
0,
GetProcAddress(GetModuleHandle(dll), proc),
0,
0,
thread_id
)
if thread
WaitForSingleObject(thread, 5)
CloseHandle(handle)
killed_pids.push(pid)
@child_pids.delete(pid)
else
CloseHandle(handle)
raise ProcessError, get_last_error
end
else
raise ProcessError, get_last_error
end
@child_pids.delete(pid)
end
}
killed_pids
end