@@ -76,17 +76,35 @@ def __run_wait(argv, infile, outfile, errfile, timelim, memlim):
7676 pid = os .fork ()
7777 if pid == 0 : # child
7878 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+
7995 if timelim is not None :
8096 limit .try_limit (resource .RLIMIT_CPU , timelim , timelim + 1 )
8197 if memlim is not None :
8298 limit .try_limit (resource .RLIMIT_AS , memlim * (1024 ** 2 ), resource .RLIM_INFINITY )
8399 limit .try_limit (resource .RLIMIT_STACK ,
84100 resource .RLIM_INFINITY , resource .RLIM_INFINITY )
101+
85102 Program .__setfd (0 , infile , os .O_RDONLY )
86103 Program .__setfd (1 , outfile ,
87104 os .O_WRONLY | os .O_CREAT | os .O_TRUNC )
88105 Program .__setfd (2 , errfile ,
89106 os .O_WRONLY | os .O_CREAT | os .O_TRUNC )
107+
90108 os .execvp (argv [0 ], argv )
91109 except Exception as exc :
92110 print ("Oops. Fatal error in child process:" )
0 commit comments