@@ -76,17 +76,35 @@ def __run_wait(argv, infile, outfile, errfile, timelim, memlim):
76
76
pid = os .fork ()
77
77
if pid == 0 : # child
78
78
try :
79
+ # The Python interpreter internally sets some signal dispositions
80
+ # to SIG_IGN (notably SIGPIPE), and unless we reset them manually
81
+ # this leaks through to the program we exec. That can has some
82
+ # funny side effects, like programs not crashing as expected when
83
+ # trying to write to an interactive validator that has terminated
84
+ # and closed the read end of a pipe.
85
+ #
86
+ # This *shouldn't* cause any verdict changes given the setup for
87
+ # interactive problems, but reset them anyway, for sanity.
88
+ if hasattr (signal , "SIGPIPE" ):
89
+ signal .signal (signal .SIGPIPE , signal .SIG_DFL )
90
+ if hasattr (signal , "SIGXFZ" ):
91
+ signal .signal (signal .SIGXFZ , signal .SIG_DFL )
92
+ if hasattr (signal , "SIGXFSZ" ):
93
+ signal .signal (signal .SIGXFSZ , signal .SIG_DFL )
94
+
79
95
if timelim is not None :
80
96
limit .try_limit (resource .RLIMIT_CPU , timelim , timelim + 1 )
81
97
if memlim is not None :
82
98
limit .try_limit (resource .RLIMIT_AS , memlim * (1024 ** 2 ), resource .RLIM_INFINITY )
83
99
limit .try_limit (resource .RLIMIT_STACK ,
84
100
resource .RLIM_INFINITY , resource .RLIM_INFINITY )
101
+
85
102
Program .__setfd (0 , infile , os .O_RDONLY )
86
103
Program .__setfd (1 , outfile ,
87
104
os .O_WRONLY | os .O_CREAT | os .O_TRUNC )
88
105
Program .__setfd (2 , errfile ,
89
106
os .O_WRONLY | os .O_CREAT | os .O_TRUNC )
107
+
90
108
os .execvp (argv [0 ], argv )
91
109
except Exception as exc :
92
110
print ("Oops. Fatal error in child process:" )
0 commit comments