[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