34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/gemlings/sandbox.rb', line 34
def call(timeout, &block)
reader, writer = IO.pipe
pid = Process.fork do
reader.close
Marshal.dump(block.call, writer)
rescue => e
Marshal.dump({ error: "#{e.class}: #{e.message}" }, writer)
ensure
writer.close
exit!(0)
end
writer.close
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
loop do
_, status = Process.waitpid2(pid, Process::WNOHANG)
if status
break
elsif Process.clock_gettime(Process::CLOCK_MONOTONIC) > deadline
Process.kill("KILL", pid)
Process.waitpid(pid)
reader.close
return { error: "Execution timed out after #{timeout}s" }
end
sleep 0.05
end
data = reader.read
reader.close
data.empty? ? { output: "", result: nil, is_final_answer: false } : Marshal.load(data) end
|