Skip to content

Instantly share code, notes, and snippets.

@ahoward
Last active October 16, 2016 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahoward/13c28e523615b43b49e9a2bccf0b9b73 to your computer and use it in GitHub Desktop.
Save ahoward/13c28e523615b43b49e9a2bccf0b9b73 to your computer and use it in GitHub Desktop.
require 'tmpdir'
require 'securerandom'
class Assassin
def Assassin.ate(*args, &block)
new(*args, &block)
end
attr_accessor :parent_pid
attr_accessor :child_pid
attr_accessor :pid
attr_accessor :path
def initialize(child_pid, options = {})
@child_pid = child_pid.to_s.to_i
@parent_pid = Process.pid
@pid, @path = Assassin.generate(@child_pid, options)
end
def Assassin.generate(child_pid, options = {})
path = File.join(Dir.tmpdir, "assassin-#{ child_pid }-#{ SecureRandom.uuid }.rb")
script = Assassin.script_for(child_pid, options)
IO.binwrite(path, script)
pid = Process.spawn "ruby #{ path }"
Process.detach(pid)
[pid, path]
end
def Assassin.script_for(child_pid, options = {})
parent_pid = Process.pid
assassin = <<-__
parent_pid = #{ parent_pid }
child_pid = #{ child_pid }
m = 24*60*60
n = 4242
m.times do
begin
Process.kill(0, parent_pid)
rescue Object => e
if e.is_a?(Errno::ESRCH)
n.times do
begin
Process.kill(15, child_pid) rescue nil
sleep(rand + rand)
Process.kill(9, child_pid) rescue nil
sleep(rand + rand)
Process.kill(0, child_pid)
rescue Errno::ESRCH
break
end
end
end
exit
end
sleep(1)
end
__
end
end
if $0 == __FILE__
pipe = IO.popen 'ruby', 'r+'
pipe.puts 'sleep'
pipe.close_write
pid = pipe.pid
system "ps wwwaux |grep #{ pid }"
puts "after this program exits you can check that #{ pid } is no longer running"
puts "hit return to continue..."
STDIN.gets
Assassin.ate(pid)
rand > 0.42 ? exit! : Process.kill(9, Process.pid)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment