62 lines
1.2 KiB
Ruby
62 lines
1.2 KiB
Ruby
|
require 'fiddle'
|
||
|
require 'fiddle/import'
|
||
|
|
||
|
class NS
|
||
|
extend Fiddle::Importer
|
||
|
dlload Fiddle.dlopen( nil)
|
||
|
SetNS_Function = Fiddle::Function.new handler['setns'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT
|
||
|
|
||
|
class <<self
|
||
|
def setns fd, t
|
||
|
r = SetNS_Function.call fd.to_i, t.to_i
|
||
|
SystemCallError.new "setns(#{fd.to_i})", Fiddle.last_error if -1 == r
|
||
|
r
|
||
|
end
|
||
|
|
||
|
def _open_nsfd pid, type
|
||
|
File.open "/proc/%d/ns/%s" % [pid, type]
|
||
|
end
|
||
|
|
||
|
def open pid, *types, &exe
|
||
|
ns = new pid, *types
|
||
|
if block_given?
|
||
|
begin yield ns
|
||
|
ensure ns.close
|
||
|
end
|
||
|
else ns
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def change pid, *types, &exe
|
||
|
open pid, *types do |ns|
|
||
|
ns.change &exe
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
attr_reader :pid, :fds, :types
|
||
|
|
||
|
def initialize pid, *types
|
||
|
@pid, @fds = pid, {}
|
||
|
types.map {|t| @fds[t] = self.class._open_nsfd pid, t }
|
||
|
end
|
||
|
|
||
|
def close
|
||
|
@fds.each {|t, fd| fd.close }
|
||
|
end
|
||
|
|
||
|
def change &block
|
||
|
@owns = @fds.map {|t, _f| Own[t] }
|
||
|
begin
|
||
|
@fds.each {|type, fd| self.class.setns fd, 0 }
|
||
|
yield
|
||
|
ensure
|
||
|
@owns.each {|fd| self.class.setns fd, 0 }
|
||
|
end
|
||
|
end
|
||
|
|
||
|
Own = Hash.new {|h, ns| h[ns] = _open_nsfd $$, ns }
|
||
|
end
|
||
|
|
||
|
|