@ -436,6 +436,13 @@ class Connection(ConnectionBase):
for fd in rpipes :
for fd in rpipes :
fcntl . fcntl ( fd , fcntl . F_SETFL , fcntl . fcntl ( fd , fcntl . F_GETFL ) | os . O_NONBLOCK )
fcntl . fcntl ( fd , fcntl . F_SETFL , fcntl . fcntl ( fd , fcntl . F_GETFL ) | os . O_NONBLOCK )
# If we can send initial data without waiting for anything, we do so
# before we call select.
if states [ state ] == ' ready_to_send ' and in_data :
self . _send_initial_data ( stdin , in_data )
state + = 1
while True :
while True :
rfd , wfd , efd = select . select ( rpipes , [ ] , rpipes , timeout )
rfd , wfd , efd = select . select ( rpipes , [ ] , rpipes , timeout )
@ -518,18 +525,11 @@ class Connection(ConnectionBase):
# Once we're sure that the privilege escalation prompt, if any, has
# Once we're sure that the privilege escalation prompt, if any, has
# been dealt with, we can send any initial data and start waiting
# been dealt with, we can send any initial data and start waiting
# for output. (Note that we have to close the process's stdin here,
# for output.
# otherwise, for example, "sftp -b -" will just hang forever waiting
# for more commands.)
if states [ state ] == ' ready_to_send ' :
if states [ state ] == ' ready_to_send ' :
if in_data :
if in_data :
self . _display . debug ( ' Sending initial data ( %d bytes) ' % len ( in_data ) )
self . _send_initial_data ( stdin , in_data )
try :
stdin . write ( in_data )
stdin . close ( )
except ( OSError , IOError ) :
raise AnsibleConnectionFailure ( ' SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh ' )
state + = 1
state + = 1
# Now we just wait for the process to exit. Output is already being
# Now we just wait for the process to exit. Output is already being
@ -567,6 +567,21 @@ class Connection(ConnectionBase):
return ( p . returncode , stdout , stderr )
return ( p . returncode , stdout , stderr )
def _send_initial_data ( self , fh , in_data ) :
'''
Writes initial data to the stdin filehandle of the subprocess and closes
it . ( The handle must be closed ; otherwise , for example , " sftp -b - " will
just hang forever waiting for more commands . )
'''
self . _display . debug ( ' Sending initial data ( %d bytes) ' % len ( in_data ) )
try :
fh . write ( in_data )
fh . close ( )
except ( OSError , IOError ) :
raise AnsibleConnectionFailure ( ' SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh ' )
# This is a separate method because we need to do the same thing for stdout
# This is a separate method because we need to do the same thing for stdout
# and stderr.
# and stderr.