def spawn(self): self.set_post_defaults() self.plash_setup() if plash.env.under_plash: my_execve = kernel_execve else: my_execve = os.execve assert isinstance(self.cmd, str) for arg in [self.arg0] + self.args: assert isinstance(arg, str) # Doing this in Python is a little risky. We must ensure that # no freeing of Plash objects occurs before the call to # cap_close_all_connections() in the newly-forked process, # otherwise both processes could try to use the same connection # to send the "Drop" message, leading to a protocol violation. # We're probably OK with the refcounting C implementation of # Python, but another implementation might do GC at any point. pid = os.fork() if pid == 0: try: plash_core.cap_close_all_connections() if plash.env.under_plash: # Unset this variable so that the connection # does not get reinstated after resetting it. if "PLASH_COMM_FD" in os.environ: del os.environ["PLASH_COMM_FD"] # This lets us close() the FD for libc's connection. plash_core.libc_reset_connection() self._set_up_fds() try: my_execve(self.cmd, [self.arg0] + self.args, self.env) except Exception, ex: os.write(STDERR_FILENO, "execve failed: %s: %s\n" % (type(ex).__name__, str(ex))) finally: os._exit(1) else: # We must drop our references to the client's FDs so that # we do not hold its connections open even after the # client has exited. self.fds.clear() return pid
def tearDown(self): super(CapProtocolCTests, self).tearDown() plash_core.cap_close_all_connections() self.assertFalse(plash_core.cap_server_exporting())
def tearDown(self): self._temp_maker.destroy() plash_core.cap_close_all_connections()