Skip to content

Commit eb7b607

Browse files
simonlindholmaustrin
authored andcommitted
Reset signal dispositions before running exec
1 parent fbda1cb commit eb7b607

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

problemtools/run/program.py

+18
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)