diff --git a/autodriver/autograde_wrapper.py b/autodriver/autograde_wrapper.py index e8ffc721..b7b69bad 100644 --- a/autodriver/autograde_wrapper.py +++ b/autodriver/autograde_wrapper.py @@ -4,31 +4,61 @@ import os import pwd import shutil -import subprocess +import threading #print("Running "+ str(sys.argv)) +# Wait for all processes, since we are pid 1 in the container, +# terminate once the interesting process exits +class WaitLoop(object): + def __init__(self, pid=None): + self.waitfor=pid + self.status=None + def __call__(self): + try: + (np, self.status)=os.wait() + while pid is None or np != self.waitfor: + (np, self.status)=os.wait() + except OSError: + if pid: + print("Chld process {} never exited, but no more children left".format(self.waitfor)) + self.status=-1 + for f in os.listdir("mount"): src=os.path.join("mount", f) dst=os.path.join("autolab", f) shutil.copy(src, dst) autolabuser=pwd.getpwnam("autolab") +(r_p, w_p)=os.pipe() pid=os.fork() if pid == 0: + os.close(r_p) os.setgroups([]) os.setgid(autolabuser.pw_gid) os.setuid(autolabuser.pw_uid) - outfile=open("output/feedback", "w") args=["autodriver"] args.extend(sys.argv[1:]) args.append("autolab") - print("Executing "+str(args), file=outfile) - sys.exit(subprocess.call(args, stdout=outfile, stderr=outfile, close_fds=True)) -(np, status)=os.waitpid(pid, 0) + if w_p != 1: + os.dup2(w_p, 1) + if w_p != 2: + os.dup2(w_p, 2) + if w_p > 2: + os.close(w_p) + os.execvp(args[0], args) +os.close(w_p) +waiter=WaitLoop(pid) +thr=threading.Thread(target=waiter) +thr.start() +rpf=os.fdopen(r_p) +shutil.copyfileobj(rpf, open("mount/feedback", "w")) +#print("Copied output") +rpf.close() +thr.join() # if core, exit -1, else pass through code. -if status & 0xff: +if os.WIFSIGNALED(waiter.status): status=-1 else: - status>>=8; -shutil.copy("output/feedback", "mount/feedback") + status=os.WEXITSTATUS(waiter.status) +#print("Status is {}".format(status)) sys.exit(status)