Description:
Merge branch 'master' of git://github.com/nattee/cafe-grader-judge-scripts into nattee-master Conflicts: installer/install.sh
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r207:41f5b5c73eba - - 11 files changed: 277 inserted, 32 deleted

@@ -0,0 +1,66
1 + #!/usr/bin/env ruby
2 +
3 + problem_home = ENV['PROBLEM_HOME']
4 + require "#{problem_home}/script/test_dsl.rb"
5 +
6 + if ARGV.length < 2
7 + puts "Usage: check <language> <test-number> [<output-file>]"
8 + exit(0)
9 + end
10 +
11 + language = ARGV[0]
12 + test_num = ARGV[1].to_i
13 + if ARGV.length >= 3
14 + output_file_name = ARGV[2]
15 + else
16 + output_file_name = "output.txt"
17 + end
18 +
19 + load "#{problem_home}/test_cases/all_tests.cfg"
20 + problem = Problem.get_instance
21 +
22 + output_file = File.new(output_file_name, "r")
23 + answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 + result_file = File.new("check_result", "w")
25 +
26 + output_file_content = output_file.read
27 + answer_file_content = answer_file.read
28 +
29 + report_correct = lambda {
30 + result_file.write "Correct\n"
31 + result_file.write problem.get_score(test_num)
32 + result_file.write "\n"
33 + result_file.close
34 + exit(0)
35 + }
36 +
37 + report_wrong = lambda {
38 + result_file.write "Incorrect\n"
39 + result_file.write "0\n"
40 + result_file.close
41 + exit(0)
42 + }
43 +
44 + ##################
45 + # Your code here #
46 + ##################
47 +
48 + ########### THIS IS FOR CHECKING FLOAT with EPSILON error ##########
49 +
50 + EPSILON = 0.000001
51 +
52 + out_items = output_file_content.split
53 + ans_items = answer_file_content.split
54 +
55 + if out_items.length != ans_items.length
56 + report_wrong.call
57 + else
58 + out_items.length.times do |i|
59 + out_value = out_items[i].to_f
60 + ans_value = ans_items[i].to_f
61 + if (out_value - ans_value).abs > EPSILON * [out_value.abs,ans_value.abs].max
62 + report_wrong.call
63 + end
64 + end
65 + report_correct.call
66 + end
@@ -54,17 +54,20
54 54 queue: repeatedly check the task queue and grade any available tasks
55 55
56 56 prob: re-grade every user latest submission of the specific problem.
57 57 the problem name must be specified by the next argument.
58 58
59 59 additional options:
60 + --all-sub re-grade every submissions instead of just the latest submission of each user.
60 61
61 - --all-sub re-grade every submissions instead of just the latest submission of each user.
62 62 sub: re-grader the specified submission.
63 63 The submission ID to be re-graded must be specified by the next argument.
64 64
65 + options:
66 + --err-log log error to a file in the log dir
67 +
65 68 (3) create stop-file to stop running grader in queue mode
66 69 (4) You are here.
67 70 USAGE
68 71 end
69 72
70 73 def process_options_and_stop_file
@@ -131,12 +134,14
131 134 puts "Report currently works only for 'prob' or 'contest' modes."
132 135 exit(0)
133 136 end
134 137
135 138 options[:all_sub] = (ARGV.delete('--all-sub') != nil)
136 139
140 + options[:err_log] = (ARGV.delete('--err-log') != nil)
141 +
137 142 return options
138 143 end
139 144
140 145 class ResultCollector
141 146 def initialize
142 147 @results = {}
@@ -417,12 +422,19
417 422 else
418 423 grader_proc = nil
419 424 end
420 425
421 426 #set loggin environment
422 427 ENV['GRADER_LOGGING'] = log_file_name
428 + if options[:err_log]
429 + err_file_name = log_file_name + '.err'
430 + $stderr.reopen(err_file_name,"a")
431 + log "STDERR log to file [#{err_file_name}]"
432 + warn "start logging for grader PID #{Process.pid} on #{Time.now.in_time_zone}"
433 + end
434 +
423 435
424 436 # register exit handler to report inactive, and terminated
425 437 at_exit do
426 438 if grader_proc!=nil
427 439 grader_proc.report_inactive
428 440 grader_proc.terminate
@@ -1,27 +1,27
1 1 #!/bin/sh
2 2
3 3 echo "This script will install and configure Cafe grader."
4 4
5 - $RUBY_VERSION="2.2.0"
5 + $RUBY_VERSION="2.1.2"
6 6 echo "This will install Ruby $RUBY_VERSION under RVM"
7 7
8 8 echo "Installing required apts"
9 9
10 10 sudo apt-get update
11 11 sudo apt-get install mysql-server mysql-client \
12 12 g++ gcc apache2 libmysqlclient15-dev build-essential \
13 13 git-core openssl libreadline6 libreadline6-dev \
14 14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
15 15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
16 16 ncurses-dev automake libtool bison subversion \
17 - pkg-config curl nodejs unzip
17 + pkg-config curl nodejs unzip pyflakes ruby default-jdk
18 18
19 19 echo "Installing RVM"
20 20 curl -k -L https://get.rvm.io | bash -s stable
21 - ~/.rvm/scripts/rvm
21 + source ~/.rvm/scripts/rvm
22 22
23 23 echo "Installing Ruby $RUBY_VERSION in RVM"
24 24
25 25 rvm install $RUBY_VERSION
26 26 rvm use $RUBY_VERSION
27 27
@@ -154,12 +154,21
154 154 # create new environment.rb file
155 155 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
156 156 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
157 157 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
158 158 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
159 159
160 + # compiling box
161 + MACHINE_TYPE=`uname -m`
162 + if [ ${MACHINE_TYPE} == 'x86_64' ]; then
163 + gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
164 + else
165 + g++ -o scripts/std-script/box scripts/std-script/box.cc
166 + fi
167 +
168 +
160 169 cd ..
161 170
162 171 echo "Now you are ready to run cafe grader...."
163 172 echo
164 173 echo "Try:"
165 174 echo
@@ -115,14 +115,16
115 115 def call_judge(problem_home,language,grading_dir,fname)
116 116 ENV['PROBLEM_HOME'] = problem_home
117 117 ENV['RUBYOPT'] = ''
118 118
119 119 talk grading_dir
120 120 Dir.chdir grading_dir
121 - cmd = "#{problem_home}/script/judge #{language} #{fname}"
121 + script_name = "#{problem_home}/script/judge"
122 + cmd = "#{script_name} #{language} #{fname}"
122 123 talk "CMD: #{cmd}"
124 + warn "ERROR: file does not exists #{script_name}" unless File.exists? script_name
123 125 system(cmd)
124 126 end
125 127
126 128 def get_std_script_dir
127 129 GRADER_ROOT + '/std-script'
128 130 end
@@ -42,13 +42,13
42 42 end
43 43 end
44 44 end
45 45 end
46 46
47 47 def grade_submission(submission)
48 - puts "Submission: #{submission.id} by #{submission.user.full_name}"
48 + puts "Submission: #{submission.id} by #{submission.try(:user).try(:full_name)}"
49 49 @engine.grade(submission)
50 50 end
51 51
52 52 def grade_oldest_test_request
53 53 test_request = TestRequest.get_inqueue_and_change_status(Task::STATUS_GRADING)
54 54 if test_request!=nil
@@ -62,13 +62,14
62 62 cmp_file.close
63 63 else
64 64 cmp_msg = ""
65 65 end
66 66
67 67 result_fname = "#{test_result_dir}/result"
68 - comment_fname = "#{test_result_dir}/comment"
68 + comment_fname = "#{test_result_dir}/comment"
69 + runstat_fname = "#{test_result_dir}/run_stat"
69 70 if FileTest.exist?(result_fname)
70 71 comment = ""
71 72 begin
72 73 result_file = File.open(result_fname)
73 74 result = result_file.readline.to_i
74 75 result_file.close
@@ -82,15 +83,28
82 83 comment += comment_file.readline.chomp
83 84 comment_file.close
84 85 rescue
85 86 comment += ""
86 87 end
87 88
88 - return {:points => result,
89 - :comment => comment,
90 - :cmp_msg => cmp_msg}
89 + begin
90 + runstat_file = File.open(runstat_fname)
91 + max_runtime = runstat_file.readline.to_f
92 + peak_memory = runstat_file.readline.to_i
93 + rescue
94 + max_runtime = -1
95 + peak_memory = -1
96 + end
97 +
98 +
99 + return {points: result,
100 + comment: comment,
101 + cmp_msg: cmp_msg,
102 + max_runtime: max_runtime,
103 + peak_memory: peak_memory
104 + }
91 105 else
92 106 if FileTest.exist?("#{test_result_dir}/a.out")
93 107 return {:points => 0,
94 108 :comment => 'error during grading',
95 109 :cmp_msg => cmp_msg}
96 110 else
@@ -105,12 +119,16
105 119 problem = submission.problem
106 120 submission.graded_at = Time.now.gmtime
107 121 points = result[:points]
108 122 submission.points = points
109 123 comment = @config.report_comment(result[:comment])
110 124
125 + submission.peak_memory = result[:peak_memory]
126 + submission.max_runtime = result[:max_runtime]
127 + submission.effective_code_length =submission.source.length
128 +
111 129 #
112 130 # TODO: FIX THIS MESSAGE
113 131 #
114 132 if problem == nil
115 133 submission.grader_comment = 'PASSED: ' + comment + '(problem is nil)'
116 134 elsif points == problem.full_score
@@ -195,13 +195,13
195 195 else
196 196 seconds = nil
197 197 time_stat = "Time used: n/a sec."
198 198 end
199 199
200 200 # extract memory usage
201 - if res = /s(.*)m/.match(running_stat_line)
201 + if res = /s(.*)kbytes/.match(running_stat_line)
202 202 memory_used = res[1].to_i
203 203 else
204 204 memory_used = -1
205 205 end
206 206
207 207 return {
@@ -23,16 +23,24
23 23 end
24 24 end
25 25
26 26 C_COMPILER = "/usr/bin/gcc"
27 27 CPLUSPLUS_COMPILER = "/usr/bin/g++"
28 28 PASCAL_COMPILER = "/usr/bin/fpc"
29 + JAVA_COMPILER = "/usr/bin/javac"
30 + RUBY_INTERPRETER = "/usr/bin/ruby"
31 + PYTHON_INTERPRETER = "/usr/bin/python"
32 + PYTHON_CHECKER = "/usr/bin/pyflakes"
33 + PHP_INTERPRETER = "/usr/bin/php"
29 34
30 35 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
31 - CPLUSPLUS_OPTIONS = "-O2 -s -static -DCONTEST -lm -Wall"
36 + CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall"
32 37 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
38 + JAVA_OPTIONS = ""
39 + PYTHON_OPTIONS = ""
40 + PHP_OPTIONS = "-l"
33 41
34 42 # Check for the correct number of arguments. Otherwise, print usage.
35 43 if ARGV.length == 0 or ARGV.length > 4
36 44 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
37 45 puts
38 46 puts "<source-file> is defaulted to \"source\"."
@@ -81,26 +89,93
81 89 params[:prog_lang] = 'c++'
82 90 end
83 91
84 92 # Compile.
85 93 case params[:prog_lang]
86 94
87 - when "c"
88 - command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS} 2> #{params[:message_file]}"
89 - system(command)
95 + when "c"
96 + command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS}"
97 + system(command, err: params[:message_file])
98 +
99 + when "c++"
100 + command = "#{CPLUSPLUS_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS}"
101 + system(command, err: params[:message_file])
102 +
103 + when "pas"
104 + command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS}"
105 + system(command,out: params[:message_file])
106 + FileUtils.mv("output", params[:output_file])
107 +
108 + when "java"
109 + #rename the file to the public class name
110 +
111 + #get the class name
112 + classname = 'DUMMY'
113 + source = Array.new
114 + File.foreach(params[:source_file],'r:UTF-8') do |line|
115 + line.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
116 + md = /\s*public\s*class\s*(\w*)/.match(line)
117 + classname=md[1] if md
118 + source << line unless line =~ /\s*package\s*\w+\s*\;/
119 + end
120 + File.open("#{classname}.java","w") do |file|
121 + source.each do |s|
122 + file.puts s
123 + end
124 + end
125 + #system("cp #{params[:source_file]} #{classname}.java")
126 + command = "#{JAVA_COMPILER} -encoding utf8 #{classname}.java"
127 + system(command, err: params[:message_file])
128 + if File.exists?(classname + ".class")
129 + File.open(params[:output_file],"w") {|file| file.write("#{classname}")}
130 + end
131 + if classname == 'DUMMY'
132 + File.open(params[:message_file],"w") {|file| file.write("Cannot find any public class in the source code\n")}
133 + end
90 134
91 - when "c++"
92 - command = "#{CPLUSPLUS_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{CPLUSPLUS_OPTIONS} 2> #{params[:message_file]}"
93 - system(command)
94 -
95 - when "pas"
96 - command = "#{PASCAL_COMPILER} #{params[:source_file]} -ooutpas #{PASCAL_OPTIONS} > #{params[:message_file]}"
97 - system(command)
98 - FileUtils.mv("output", params[:output_file])
99 -
100 - else
135 + when "ruby"
136 + command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}"
137 + if system(command, err: params[:message_file])
138 + File.open(params[:output_file],"w") do |out_file|
139 + out_file.puts "#!#{RUBY_INTERPRETER}"
140 + File.open(params[:source_file],"r").each do |line|
141 + out_file.print line
142 + end
143 + end
144 + File.chmod(0755, params[:output_file])
145 + end
146 +
147 + when "python"
148 + command = "#{PYTHON_CHECKER} #{params[:source_file]}"
149 + if system(command, out: params[:message_file])
150 + #compile to python bytecode
151 + command = "#{PYTHON_INTERPRETER} -m py_compile #{params[:source_file]}"
152 + puts "compile: #{command}"
153 + system(command)
154 + puts "pwd: " + Dir.pwd
155 + Dir.new('.').each {|file| puts file}
156 + File.open(params[:output_file],"w") do |out_file|
157 + out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
158 + end
159 + File.chmod(0755, params[:output_file])
160 + FileUtils.cp("#{params[:source_file]}c",params[:output_file])
161 + end
162 +
163 + when "php"
164 + command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
165 + if system(command, err: params[:message_file])
166 + File.open(params[:output_file],"w") do |out_file|
167 + out_file.puts "#!#{PHP_INTERPRETER}"
168 + File.open(params[:source_file],"r").each do |line|
169 + out_file.print line
170 + end
171 + end
172 + File.chmod(0755, params[:output_file])
173 + end
174 +
175 + else
101 176 talk("ERROR: Invalid language specified!")
102 177 open(params[:message_file],"w") do |f|
103 178 f.puts "ERROR: Invalid language specified!"
104 179 end
105 180 exit(127)
106 181 end
@@ -28,24 +28,37
28 28 res[1]
29 29 else
30 30 RUN_ERROR_MARK # these are run time errors
31 31 end
32 32 end
33 33
34 + def extract_time(t)
35 + #puts "TIME: #{t}"
36 + if (result=/^(.*)r(.*)u(.*)s(.*)kbytes/.match(t))
37 + {:real => result[1], :user => result[2], :sys => result[3], :mem => result[4]}
38 + else
39 + #{:real => 0, :user => 0, :sys => 0}
40 + #puts "ERROR READING RUNNING TIME: #{t}"
41 + raise "Error reading running time: #{t}"
42 + end
43 + end
44 +
34 45 problem_home = ENV['PROBLEM_HOME']
35 46 require "#{problem_home}/script/test_dsl.rb"
36 47 load "#{problem_home}/test_cases/all_tests.cfg"
37 48 problem = Problem.get_instance
38 49
39 50 if problem.well_formed? == false
40 51 log "The problem specification is not well formed."
41 52 exit(127)
42 53 end
43 54
44 55 all_score = 0
45 56 all_comment = ''
57 + peak_memory = -1
58 + max_runtime = -1
46 59 (1..(problem.runs.length-1)).each do |k|
47 60 log "grade run #{k}"
48 61 run = problem.runs[k]
49 62 run_score = nil
50 63 run_comment = ''
51 64 run_comment_short = ''
@@ -55,16 +68,21
55 68 run_comment += "result file for test #{test_num} not found\n"
56 69 run_comment_short += RUN_ERROR_MARK
57 70 log "Cannot find the file #{test_num}/result!"
58 71 else
59 72 result_file = File.new(result_file_name, "r")
60 73 result_file_lines = result_file.readlines
61 - if result_file_lines.length>=2
74 + if result_file_lines.length>=3
62 75 current_run_score = result_file_lines[1].to_i
63 76 run_comment += result_file_lines[0]
64 77 run_comment_short += char_comment(result_file_lines[0].chomp)
78 +
79 + #update max runtime & memory
80 + run_stat = extract_time result_file_lines[2]
81 + peak_memory = [peak_memory,run_stat[:mem].to_i].max
82 + max_runtime = [max_runtime,run_stat[:user].to_f + run_stat[:sys].to_f].max
65 83 else
66 84 current_run_score = 0
67 85 run_comment += "result file for test #{test_num} error\n"
68 86 run_comment_short += RUN_ERROR_MARK
69 87 log "Error in #{test_num}/result!"
70 88 end
@@ -101,6 +119,16
101 119 result_file.write "\n"
102 120 result_file.close
103 121
104 122 comment_file = File.new("comment", "w")
105 123 comment_file.write "#{all_comment}\n"
106 124 comment_file.close
125 +
126 +
127 + File.open("run_stat","w") do |file|
128 + file.puts max_runtime
129 + file.puts peak_memory
130 + end
131 +
132 + puts "#{all_score} #{all_comment}"
133 + log "score = #{all_score}\ncomment = #{all_comment}"
134 + log "max_runtime = #{max_runtime}\npeak_memory = #{peak_memory}"
@@ -50,18 +50,19
50 50 puts " <test-result-directory> is defaulted to ./test-result"
51 51 puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it."
52 52 exit(127)
53 53 end
54 54
55 55 language = ARGV[0]
56 - if language != "c" && language != "c++" && language != "pas"
56 + if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby" && language != "python" && language != "php"
57 57 log "You specified a language that is not supported: #{language}."
58 58 exit(127)
59 59 end
60 60
61 61 source_file = ARGV[1]
62 + ENV['SOURCE_NAME'] = source_file
62 63 if File.exist?(source_file) == false
63 64 log "The source file does not exist."
64 65 exit(127)
65 66 end
66 67
67 68 log "Making test result and sandbox directories..."
@@ -107,12 +108,14
107 108 if !FileTest.exist?("a.out")
108 109 log "Cannot compile the source code. See message in #{test_result_dir}/compile_message"
109 110 exit(127)
110 111 else
111 112 call_and_log("Cannot move the compiled program to #{test_result_dir}") {
112 113 FileUtils.mv("a.out",test_result_dir)
114 + if language == "java" then Dir["*.class"].each { |file| FileUtils.mv(file,test_result_dir)} end
115 + if language == "python" then Dir["*.pyc"].each { |file| FileUtils.mv(file,test_result_dir)} end
113 116 }
114 117 FileUtils.rm_rf("#{sandbox_dir}/.")
115 118 end
116 119
117 120 require "#{problem_home}/script/test_dsl.rb"
118 121 load "#{problem_home}/test_cases/all_tests.cfg"
@@ -130,16 +133,18
130 133 $stdout.flush
131 134
132 135 log "Test number: #{test_num}"
133 136
134 137 call_and_log("Cannot copy the compiled program into #{sandbox_dir}") {
135 138 FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true)
139 + if language == "java" then Dir["#{test_result_dir}/*.class"].each { |file| FileUtils.cp(file,sandbox_dir)} end
140 + if language == "python" then Dir["#{test_result_dir}/*.pyc"].each { |file| FileUtils.cp(file,sandbox_dir)} end
136 141 }
137 142
138 143 begin
139 - execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script")
144 + execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script")
140 145 rescue
141 146 # do nothing
142 147 end
143 148
144 149 call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") {
145 150 FileUtils.mkdir "#{test_result_dir}/#{test_num}"
@@ -40,16 +40,19
40 40 program_name = ARGV[2]
41 41 else
42 42 program_name = "a.out"
43 43 end
44 44
45 45 problem_home = ENV['PROBLEM_HOME']
46 + source_name = ENV['SOURCE_NAME']
46 47 require "#{problem_home}/script/test_dsl.rb"
47 48 load "#{problem_home}/test_cases/all_tests.cfg"
48 49 problem = Problem.get_instance
49 50
51 + sandbox_dir = Dir.getwd
52 +
50 53 if problem.well_formed? == false
51 54 log "The problem specification is not well formed."
52 55 exit(127)
53 56 end
54 57
55 58 # Check if the test number is okay.
@@ -78,22 +81,48
78 81 compile_box("#{problem_home}/script/box.cc",
79 82 "#{problem_home}/script/box")
80 83 end
81 84
82 85 # Hide PROBLEM_HOME
83 86 ENV['PROBLEM_HOME'] = nil
87 + ENV['SOURCE_NAME'] = nil
84 88
85 89 # Run the program.
86 90 #run_command = "/usr/bin/time -f \"#{time_output_format}\" 2>run_result #{problem_home}/script/box_new -a 2 -f -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name}"
91 + #
87 92
88 - run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} 2>run_result"
93 + JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
94 + RUBY_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /lib64/ -p /dev/urandom -p #{sandbox_dir}/#{program_name} -p #{sandbox_dir}/ -s set_robust_list -s sched_getaffinity -s clock_gettime -s sigaltstack -s pipe2 -s clone -s futex -s openat -s pipe"
95 + PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -s set_robust_list -s openat -s recvmsg -s connect -s socket -s sendto -s futex -E PYTHONNOUSERSITE=yes"
96 + PHP_OPTION = "-p /usr/lib64/ -p/lib64/ -p /usr/bin/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p /usr/share/ -s setfsuid -s setfsgid -s openat -s set_robust_list -s futex -s clone -s socket -s connect"
97 +
98 + case language
99 + when "java"
100 + # for java, extract the classname
101 + # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
102 + classname = 'DUMMY'
103 + File.open(program_name,"r").each do |line|
104 + classname = line
105 + end
106 + #for java, we cannot really check the memory limit...
107 + run_command = "#{problem_home}/script/box -a 3 -f -T -t #{time_limit} #{JAVA_OPTION} -i #{input_file_name} -o output.txt /usr/bin/java -A -Xmx#{mem_limit}k -A #{classname} "
108 + when "ruby"
109 + run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{RUBY_OPTION} -i #{input_file_name} -o output.txt /usr/bin/ruby #{program_name} "
110 + when "python"
111 + run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python #{program_name} "
112 + when "php"
113 + run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128*1024,mem_limit].max} #{PHP_OPTION} -i #{input_file_name} -o output.txt /usr/bin/php -A -d -A memory_limit=#{mem_limit}k -A #{program_name} "
114 + else # for c++, pascal, we do the normal checking
115 + run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} "
116 + end
117 +
89 118
90 119 log "Running test #{test_num}..."
91 120 log run_command
92 - log
93 - system(run_command)
121 + log
122 + system(run_command,err: 'run_result')
94 123
95 124 # Restore PROBLEM_HOME
96 125 ENV['PROBLEM_HOME'] = problem_home
97 126
98 127 # Create the result file.
99 128 result_file = File.new("result", "w")
@@ -129,18 +158,19
129 158 comment_file.close
130 159
131 160 log "Done!"
132 161 exit(0)
133 162 }
134 163
164 +
135 165 if run_result[0][0,2] != "OK"
136 166 log "There was a runtime error."
137 167 report.call(run_result[0], 0, "No comment.\n")
138 168 end
139 169
140 - if running_time[:user].to_f + running_time[:sys].to_f > time_limit
170 + if running_time[:user].to_f > time_limit
141 171 log "Time limit exceeded."
142 172 report.call("Time limit exceeded", 0, "No comment.\n")
143 173 end
144 174
145 175 # Run 'check' to evaluate the output.
146 176 #puts "There was no runtime error. Proceed to checking the output."
You need to be logged in to leave comments. Login now