From 135d1c161a55807d20d87d3d18238c70e81c1696 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Mon, 22 Nov 2010 01:48:02 -0800 Subject: [PATCH] builder.py: set FD_CLOEXEC flag on $3 when running a .do file. Otherwise it could be inherited by other jwack jobs started from the same parent process, resulting in some very-hard-to-debug race conditions, let me tell you. --- builder.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/builder.py b/builder.py index e3e66b0..2085ec2 100644 --- a/builder.py +++ b/builder.py @@ -1,4 +1,4 @@ -import sys, os, random +import sys, os, random, fcntl import vars, jwack, state from helpers import log, log_, debug2, err, unlink @@ -31,6 +31,14 @@ def _nice(t): return os.path.normpath(os.path.join(vars.PWD, t)) +def _close_on_exec(fd, yes): + fl = fcntl.fcntl(fd, fcntl.F_GETFD) + fl &= ~fcntl.FD_CLOEXEC + if yes: + fl |= fcntl.FD_CLOEXEC + fcntl.fcntl(fd, fcntl.F_SETFD, fl) + + class BuildJob: def __init__(self, t, lock, shouldbuildfunc, donefunc): self.t = t @@ -62,7 +70,9 @@ class BuildJob: return self._after2(1) state.stamp(dofile) unlink(tmpname) - self.f = open(tmpname, 'w+') + ffd = os.open(tmpname, os.O_CREAT|os.O_RDWR|os.O_EXCL) + _close_on_exec(ffd, True) + self.f = os.fdopen(ffd, 'w+') # this will run in the dofile's directory, so use only basenames here argv = ['sh', '-e', os.path.basename(dofile), @@ -87,7 +97,9 @@ class BuildJob: os.chdir(dn) os.dup2(self.f.fileno(), 1) os.close(self.f.fileno()) + _close_on_exec(1, False) os.execvp(self.argv[0], self.argv) + assert(0) # returns only if there's an exception def _after(self, t, rv):