[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,
|
||||
"import sys ; sys.path[:0] = %r" % (plist,),
|
||||
"import os ; os.environ['PYTHONPATH'] = %r" % ppath,
|
||||
# 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
|
||||
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)
|
||||
""")),
|
||||
str(py.code.Source(stdouterrin_setnull)),
|
||||
"stdouterrin_setnull()",
|
||||
""
|
||||
])
|
||||
super(PopenGateway, self)._remote_bootstrap_gateway(io, s)
|
||||
|
@ -176,6 +151,46 @@ class SshGateway(PopenCmdGateway):
|
|||
cmd += ' -i %s' % (identity,)
|
||||
cmdline.insert(0, cmd)
|
||||
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):
|
||||
def remote_exec_sync_stdcapture(self, lines, callback):
|
||||
|
@ -224,3 +239,4 @@ class ExecGateway(PopenGateway):
|
|||
callback = self.callbacks[answerid]
|
||||
del self.callbacks[answerid]
|
||||
callback(value)
|
||||
|
||||
|
|
|
@ -25,6 +25,20 @@ def test_getsource_no_colision():
|
|||
(name, dottedname, olddottedname))
|
||||
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:
|
||||
def test_wire_protocol(self):
|
||||
for cls in gateway.Message._types.values():
|
||||
|
@ -177,12 +191,12 @@ class BasicRemoteExecution:
|
|||
|
||||
# check that the both sides previous channels are really gone
|
||||
channel.waitclose(0.3)
|
||||
assert channel.id not in self.gw._channelfactory._channels
|
||||
#assert c.id not in self.gw._channelfactory
|
||||
newchan = self.gw.remote_exec('''
|
||||
assert %d not in channel.gateway._channelfactory._channels
|
||||
''' % (channel.id))
|
||||
newchan.waitclose(0.3)
|
||||
assert channel.id not in self.gw._channelfactory._channels
|
||||
|
||||
def test_channel_receiver_callback(self):
|
||||
l = []
|
||||
|
@ -454,9 +468,6 @@ class TestSshGateway(BasicRemoteExecution):
|
|||
py.test.skip("no known ssh target, use -S to set one")
|
||||
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):
|
||||
assert self.gw.remoteaddress == option.sshtarget
|
||||
|
||||
|
|
Loading…
Reference in New Issue