require 'sinatra' require 'sinatra/reloader' require 'logger' require 'timeout' require 'open3' require "cgi/escape" #logger = Logger.new(STDOUT) get '/' do erb :index end post '/' do if params[:codes] codes=params[:codes].split("\n") cmd="ruby -e '#{codes.join("\n")}'" stdin=params[:stdin].split("\n") stdout=Array.new stderr=Array.new Open3.popen3(cmd) do |i, o, e, w| #=>|stdin, stdout, stderr, wait_thr(status)| begin Timeout.timeout(5) do i.write stdin.join("\n") i.close o.each do |line| stdout.push(line.chomp!.to_s) end e.each do |line| stderr.push(line.chomp!.to_s) end status=w.value @stdout=CGI.escapeHTML(stdout.join("\n")) @stderr=CGI.escapeHTML(stderr.join("\n")) @status=CGI.escapeHTML(status.to_s) end rescue Timeout::Error => error Process.kill("KILL", w.pid) @stderr="Fatal error: Maximum execution time of 5 seconds exceeded\n#{error}" end end @codes=CGI.escapeHTML(codes.join("\n")) @stdin=CGI.escapeHTML(stdin.join("\n")) end erb :index end