[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:
hpk 2007-02-02 02:44:31 +01:00
parent 084460ffd4
commit 24539c3797
2 changed files with 58 additions and 31 deletions

View File

@ -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)

View File

@ -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