[svn r37790] fix Ssh remote sanitzing of FD 1 and 0 and factor
out the code in a function --HG-- branch : trunk
This commit is contained in:
parent
084460ffd4
commit
24539c3797
|
@ -97,33 +97,8 @@ class PopenGateway(PopenCmdGateway):
|
||||||
s = "\n".join([extra,
|
s = "\n".join([extra,
|
||||||
"import sys ; sys.path[:0] = %r" % (plist,),
|
"import sys ; sys.path[:0] = %r" % (plist,),
|
||||||
"import os ; os.environ['PYTHONPATH'] = %r" % ppath,
|
"import os ; os.environ['PYTHONPATH'] = %r" % ppath,
|
||||||
# redirect file descriptors 0 and 1 to /dev/null, to avoid
|
str(py.code.Source(stdouterrin_setnull)),
|
||||||
# complete confusion (this is independent from the sys.stdout
|
"stdouterrin_setnull()",
|
||||||
# and sys.stderr redirection that gateway.remote_exec() can do)
|
|
||||||
# note that we redirect fd 2 on win too, since for some reason that
|
|
||||||
# blocks there, while it works (sending to stderr if possible else
|
|
||||||
# ignoring) on *nix
|
|
||||||
str(py.code.Source("""
|
|
||||||
try:
|
|
||||||
devnull = os.devnull
|
|
||||||
except AttributeError:
|
|
||||||
if os.name == 'nt':
|
|
||||||
devnull = 'NUL'
|
|
||||||
else:
|
|
||||||
devnull = '/dev/null'
|
|
||||||
sys.stdin = os.fdopen(os.dup(0), 'rb', 0)
|
|
||||||
sys.stdout = os.fdopen(os.dup(1), 'wb', 0)
|
|
||||||
if os.name == 'nt':
|
|
||||||
sys.stderr = os.fdopen(os.dup(2), 'wb', 0)
|
|
||||||
fd = os.open(devnull, os.O_RDONLY)
|
|
||||||
os.dup2(fd, 0)
|
|
||||||
os.close(fd)
|
|
||||||
fd = os.open(devnull, os.O_WRONLY)
|
|
||||||
os.dup2(fd, 1)
|
|
||||||
if os.name == 'nt':
|
|
||||||
os.dup2(fd, 2)
|
|
||||||
os.close(fd)
|
|
||||||
""")),
|
|
||||||
""
|
""
|
||||||
])
|
])
|
||||||
super(PopenGateway, self)._remote_bootstrap_gateway(io, s)
|
super(PopenGateway, self)._remote_bootstrap_gateway(io, s)
|
||||||
|
@ -177,6 +152,46 @@ class SshGateway(PopenCmdGateway):
|
||||||
cmdline.insert(0, cmd)
|
cmdline.insert(0, cmd)
|
||||||
super(SshGateway, self).__init__(' '.join(cmdline))
|
super(SshGateway, self).__init__(' '.join(cmdline))
|
||||||
|
|
||||||
|
def _remote_bootstrap_gateway(self, io, s=""):
|
||||||
|
extra = "\n".join([
|
||||||
|
str(py.code.Source(stdouterrin_setnull)),
|
||||||
|
"stdouterrin_setnull()",
|
||||||
|
s,
|
||||||
|
])
|
||||||
|
super(SshGateway, self)._remote_bootstrap_gateway(io, extra)
|
||||||
|
|
||||||
|
def stdouterrin_setnull():
|
||||||
|
# redirect file descriptors 0 and 1 to /dev/null, to avoid
|
||||||
|
# complete confusion (this is independent from the sys.stdout
|
||||||
|
# and sys.stderr redirection that gateway.remote_exec() can do)
|
||||||
|
# note that we redirect fd 2 on win too, since for some reason that
|
||||||
|
# blocks there, while it works (sending to stderr if possible else
|
||||||
|
# ignoring) on *nix
|
||||||
|
import sys, os
|
||||||
|
try:
|
||||||
|
devnull = os.devnull
|
||||||
|
except AttributeError:
|
||||||
|
if os.name == 'nt':
|
||||||
|
devnull = 'NUL'
|
||||||
|
else:
|
||||||
|
devnull = '/dev/null'
|
||||||
|
sys.stdin = os.fdopen(os.dup(0), 'rb', 0)
|
||||||
|
sys.stdout = os.fdopen(os.dup(1), 'wb', 0)
|
||||||
|
if os.name == 'nt':
|
||||||
|
sys.stderr = os.fdopen(os.dup(2), 'wb', 0)
|
||||||
|
fd = os.open(devnull, os.O_RDONLY)
|
||||||
|
os.dup2(fd, 0)
|
||||||
|
os.close(fd)
|
||||||
|
fd = os.open(devnull, os.O_WRONLY)
|
||||||
|
os.dup2(fd, 1)
|
||||||
|
if os.name == 'nt':
|
||||||
|
os.dup2(fd, 2)
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
# XXX
|
||||||
|
# XXX unusued code below
|
||||||
|
# XXX
|
||||||
|
|
||||||
class ExecGateway(PopenGateway):
|
class ExecGateway(PopenGateway):
|
||||||
def remote_exec_sync_stdcapture(self, lines, callback):
|
def remote_exec_sync_stdcapture(self, lines, callback):
|
||||||
# hack: turn the content of the cell into
|
# hack: turn the content of the cell into
|
||||||
|
@ -224,3 +239,4 @@ class ExecGateway(PopenGateway):
|
||||||
callback = self.callbacks[answerid]
|
callback = self.callbacks[answerid]
|
||||||
del self.callbacks[answerid]
|
del self.callbacks[answerid]
|
||||||
callback(value)
|
callback(value)
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,20 @@ def test_getsource_no_colision():
|
||||||
(name, dottedname, olddottedname))
|
(name, dottedname, olddottedname))
|
||||||
seen[name] = (dottedname, value)
|
seen[name] = (dottedname, value)
|
||||||
|
|
||||||
|
def test_stdouterrin_setnull():
|
||||||
|
cap = py.io.StdCaptureFD()
|
||||||
|
from py.__.execnet.register import stdouterrin_setnull
|
||||||
|
stdouterrin_setnull()
|
||||||
|
import os
|
||||||
|
os.write(1, "hello")
|
||||||
|
if os.name == "nt":
|
||||||
|
os.write(2, "world")
|
||||||
|
os.read(0, 1)
|
||||||
|
out, err = cap.reset()
|
||||||
|
assert not out
|
||||||
|
assert not err
|
||||||
|
|
||||||
|
|
||||||
class TestMessage:
|
class TestMessage:
|
||||||
def test_wire_protocol(self):
|
def test_wire_protocol(self):
|
||||||
for cls in gateway.Message._types.values():
|
for cls in gateway.Message._types.values():
|
||||||
|
@ -177,12 +191,12 @@ class BasicRemoteExecution:
|
||||||
|
|
||||||
# check that the both sides previous channels are really gone
|
# check that the both sides previous channels are really gone
|
||||||
channel.waitclose(0.3)
|
channel.waitclose(0.3)
|
||||||
assert channel.id not in self.gw._channelfactory._channels
|
|
||||||
#assert c.id not in self.gw._channelfactory
|
#assert c.id not in self.gw._channelfactory
|
||||||
newchan = self.gw.remote_exec('''
|
newchan = self.gw.remote_exec('''
|
||||||
assert %d not in channel.gateway._channelfactory._channels
|
assert %d not in channel.gateway._channelfactory._channels
|
||||||
''' % (channel.id))
|
''' % (channel.id))
|
||||||
newchan.waitclose(0.3)
|
newchan.waitclose(0.3)
|
||||||
|
assert channel.id not in self.gw._channelfactory._channels
|
||||||
|
|
||||||
def test_channel_receiver_callback(self):
|
def test_channel_receiver_callback(self):
|
||||||
l = []
|
l = []
|
||||||
|
@ -454,9 +468,6 @@ class TestSshGateway(BasicRemoteExecution):
|
||||||
py.test.skip("no known ssh target, use -S to set one")
|
py.test.skip("no known ssh target, use -S to set one")
|
||||||
cls.gw = py.execnet.SshGateway(option.sshtarget)
|
cls.gw = py.execnet.SshGateway(option.sshtarget)
|
||||||
|
|
||||||
def test_confusion_from_os_write_stdout(self):
|
|
||||||
py.test.skip("writing to FD 1 with SshGateways not supported yet")
|
|
||||||
|
|
||||||
def test_sshaddress(self):
|
def test_sshaddress(self):
|
||||||
assert self.gw.remoteaddress == option.sshtarget
|
assert self.gw.remoteaddress == option.sshtarget
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue