[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