@ -24,7 +24,11 @@ import termios
import time
import time
import tty
import tty
from os import isatty
from os import (
getpgrp ,
isatty ,
tcgetpgrp ,
)
from ansible . errors import AnsibleError
from ansible . errors import AnsibleError
from ansible . module_utils . _text import to_text , to_native
from ansible . module_utils . _text import to_text , to_native
from ansible . module_utils . parsing . convert_bool import boolean
from ansible . module_utils . parsing . convert_bool import boolean
@ -67,6 +71,19 @@ def clear_line(stdout):
stdout . write ( b ' \x1b [ %s ' % CLEAR_TO_EOL )
stdout . write ( b ' \x1b [ %s ' % CLEAR_TO_EOL )
def is_interactive ( fd = None ) :
if fd is None :
return False
if isatty ( fd ) :
# Compare the current process group to the process group associated
# with terminal of the given file descriptor to determine if the process
# is running in the background.
return getpgrp ( ) == tcgetpgrp ( fd )
else :
return False
class ActionModule ( ActionBase ) :
class ActionModule ( ActionBase ) :
''' pauses execution for a length or time, or until input is received '''
''' pauses execution for a length or time, or until input is received '''
@ -177,11 +194,10 @@ class ActionModule(ActionBase):
stdout_fd = stdout . fileno ( )
stdout_fd = stdout . fileno ( )
except ( ValueError , AttributeError ) :
except ( ValueError , AttributeError ) :
# ValueError: someone is using a closed file descriptor as stdin
# ValueError: someone is using a closed file descriptor as stdin
# AttributeError: someone is using a null file descriptor as stdin on windo e z
# AttributeError: someone is using a null file descriptor as stdin on windo ze
stdin = None
stdin = None
interactive = is_interactive ( stdin_fd )
if stdin_fd is not None :
if interactive :
if isatty ( stdin_fd ) :
# grab actual Ctrl+C sequence
# grab actual Ctrl+C sequence
try :
try :
intr = termios . tcgetattr ( stdin_fd ) [ 6 ] [ termios . VINTR ]
intr = termios . tcgetattr ( stdin_fd ) [ 6 ] [ termios . VINTR ]
@ -214,21 +230,20 @@ class ActionModule(ActionBase):
termios . tcflush ( stdin , termios . TCIFLUSH )
termios . tcflush ( stdin , termios . TCIFLUSH )
while True :
while True :
if not interactive :
display . warning ( " Not waiting for response to prompt as stdin is not interactive " )
if seconds is not None :
# Give the signal handler enough time to timeout
time . sleep ( seconds + 1 )
break
try :
try :
if stdin_fd is not None :
key_pressed = stdin . read ( 1 )
key_pressed = stdin . read ( 1 )
if key_pressed == intr : # value for Ctrl+C
if key_pressed == intr : # value for Ctrl+C
clear_line ( stdout )
clear_line ( stdout )
raise KeyboardInterrupt
raise KeyboardInterrupt
if not seconds :
if stdin_fd is None or not isatty ( stdin_fd ) :
display . warning ( " Not waiting for response to prompt as stdin is not interactive " )
break
# read key presses and act accordingly
# read key presses and act accordingly
if key_pressed in ( b ' \r ' , b ' \n ' ) :
if key_pressed in ( b ' \r ' , b ' \n ' ) :
clear_line ( stdout )
clear_line ( stdout )