Coverage for /run/media/veganeco/water/status600.com/pypi/reptilian_climates/modules_series_2/ships/fields/gardens_pip/pexpect/utils.py: 41%

1 import os

2 import sys

3 import stat

4 import select

5 import time

6 import errno

7

8 try:

9 InterruptedError

10 except NameError:

11 # Alias Python2 exception to Python3

12 InterruptedError = select.error

13

14 if sys.version_info[0] >= 3:

15 string_types = (str,)

16 else:

17 string_types = (unicode, str)

18

19

20 def is_executable_file(path):

21 """Checks that path is an executable regular file, or a symlink towards one.

22

23 This is roughly ``os.path isfile(path) and os.access(path, os.X_OK)``.

24 """

25 # follow symlinks,

26 fpath = os.path.realpath(path)

27

28 if not os.path.isfile(fpath):

29 # non-files (directories, fifo, etc.)

30 return False

31

32 mode = os.stat(fpath).st_mode

33

34 if (sys.platform.startswith('sunos')

35 and os.getuid() == 0):

36 # When root on Solaris, os.X_OK is True for *all* files, irregardless

37 # of their executability -- instead, any permission bit of any user,

38 # group, or other is fine enough.

39 #

40 # (This may be true for other "Unix98" OS's such as HP-UX and AIX)

41 return bool(mode & (stat.S_IXUSR |

42 stat.S_IXGRP |

43 stat.S_IXOTH))

44

45 return os.access(fpath, os.X_OK)

46

47

48 def which(filename, env=None):

49 '''This takes a given filename; tries to find it in the environment path;

50 then checks if it is executable. This returns the full path to the filename

51 if found and executable. Otherwise this returns None.'''

52

53 # Special case where filename contains an explicit path.

54 if os.path.dirname(filename) != '' and is_executable_file(filename):

55 return filename

56 if env is None:

57 env = os.environ

58 p = env.get('PATH')

59 if not p:

60 p = os.defpath

61 pathlist = p.split(os.pathsep)

62 for path in pathlist:

63 ff = os.path.join(path, filename)

64 if is_executable_file(ff):

65 return ff

66 return None

67

68

69 def split_command_line(command_line):

70

71 '''This splits a command line into a list of arguments. It splits arguments

72 on spaces, but handles embedded quotes, doublequotes, and escaped

73 characters. It's impossible to do this with a regular expression, so I

74 wrote a little state machine to parse the command line. '''

75

76 arg_list = []

77 arg = ''

78

79 # Constants to name the states we can be in.

80 state_basic = 0

81 state_esc = 1

82 state_singlequote = 2

83 state_doublequote = 3

84 # The state when consuming whitespace between commands.

85 state_whitespace = 4

86 state = state_basic

87

88 for c in command_line:

89 if state == state_basic or state == state_whitespace:

90 if c == '\\':

91 # Escape the next character

92 state = state_esc

93 elif c == r"'":

94 # Handle single quote

95 state = state_singlequote

96 elif c == r'"':

97 # Handle double quote

98 state = state_doublequote

99 elif c.isspace():

100 # Add arg to arg_list if we aren't in the middle of whitespace.

101 if state == state_whitespace:

102 # Do nothing.

103 None

104 else:

105 arg_list.append(arg)

106 arg = ''

107 state = state_whitespace

108 else:

109 arg = arg + c

110 state = state_basic

111 elif state == state_esc:

112 arg = arg + c

113 state = state_basic

114 elif state == state_singlequote:

115 if c == r"'":

116 state = state_basic

117 else:

118 arg = arg + c

119 elif state == state_doublequote:

120 if c == r'"':

121 state = state_basic

122 else:

123 arg = arg + c

124

125 if arg != '':

126 arg_list.append(arg)

127 return arg_list

128

129

130 def select_ignore_interrupts(iwtd, owtd, ewtd, timeout=None):

131

132 '''This is a wrapper around select.select() that ignores signals. If

133 select.select raises a select.error exception and errno is an EINTR

134 error then it is ignored. Mainly this is used to ignore sigwinch

135 (terminal resize). '''

136

137 # if select() is interrupted by a signal (errno==EINTR) then

138 # we loop back and enter the select() again.

139 if timeout is not None:

140 end_time = time.time() + timeout

141 while True:

142 try:

143 return select.select(iwtd, owtd, ewtd, timeout)

144 except InterruptedError:

145 err = sys.exc_info()[1]

146 if err.args[0] == errno.EINTR:

147 # if we loop back we have to subtract the

148 # amount of time we already waited.

149 if timeout is not None:

150 timeout = end_time - time.time()

151 if timeout < 0:

152 return([], [], [])

153 else:

154 # something else caused the select.error, so

155 # this actually is an exception.

156 raise

157

158

159 def poll_ignore_interrupts(fds, timeout=None):

160 '''Simple wrapper around poll to register file descriptors and

161 ignore signals.'''

162

163 if timeout is not None:

164 end_time = time.time() + timeout

165

166 poller = select.poll()

167 for fd in fds:

168 poller.register(fd, select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR)

169

170 while True:

171 try:

172 timeout_ms = None if timeout is None else timeout * 1000

173 results = poller.poll(timeout_ms)

174 return [afd for afd, _ in results]

175 except InterruptedError:

176 err = sys.exc_info()[1]

177 if err.args[0] == errno.EINTR:

178 # if we loop back we have to subtract the

179 # amount of time we already waited.

180 if timeout is not None:

181 timeout = end_time - time.time()

182 if timeout < 0:

183 return []

184 else:

185 # something else caused the select.error, so

186 # this actually is an exception.

187 raise