Last active
October 21, 2017 07:29
-
-
Save olbat/f9f4c21a2f0ebb9479f2a5fc52b5d66e to your computer and use it in GitHub Desktop.
Ruby recursive Process.kill
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Process::KillRecursive | |
refine Process.singleton_class do | |
def children(pid) | |
pids = nil | |
if RbConfig::CONFIG['host_os'] =~ /linux/i | |
if File.exist?("/proc/#{pid}/task/#{pid}/children") | |
pids = File.read("/proc/#{pid}/task/#{pid}/children").split(/\s/) | |
end | |
elsif !Gem.win_platform? | |
pids = `ps --ppid #{pid} -o pid=`.split("\n") | |
raise NotImplementedError unless $?.success? | |
else | |
raise NotImplementedError | |
end | |
pids.tap{|ps| ps.map!{|p| p.strip.to_i }.uniq! } | |
end | |
def kill_recursive(pid) | |
# SIGSTOPs the process to avoid it creating new children | |
begin | |
Process.kill('STOP', pid) | |
rescue Errno::ESRCH # The process was already killed | |
return | |
end | |
# Gather the list of children before killing the parent (after the kill | |
# children are re-attached to init and impossible to find) | |
children = children(pid) | |
# TODO: check if this do not generate <defunct> children | |
# if it does, kill the process before it's children | |
children.each do |cpid| | |
kill_recursive(cpid) | |
end if children | |
begin | |
Process.kill('KILL', pid) | |
rescue Errno::ESRCH # The process was already killed | |
return | |
end | |
end | |
end | |
end | |
=begin | |
class SomeClass | |
using Process::KillRecursive | |
def some_method(pid) | |
Process.kill_recursive(pid) | |
end | |
end | |
=end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment