1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """Utility functions wrapping other functions.
22
23 """
24
25 import sys
26 import time
27 import socket
28 import errno
29 import tempfile
30 import fcntl
31 import os
32 import select
33 import logging
34
35
37 """Sleep for a fixed amount of time.
38
39 @type duration: float
40 @param duration: the sleep duration, in seconds
41 @rtype: (boolean, str)
42 @return: False for negative value, and an accompanying error message;
43 True otherwise (and msg is None)
44
45 """
46 if duration < 0:
47 return False, "Invalid sleep duration"
48 time.sleep(duration)
49 return True, None
50
51
53 """Close a file descriptor ignoring errors.
54
55 @type fd: int
56 @param fd: the file descriptor
57 @type retries: int
58 @param retries: how many retries to make, in case we get any
59 other error than EBADF
60
61 """
62 try:
63 os.close(fd)
64 except OSError, err:
65 if err.errno != errno.EBADF:
66 if retries > 0:
67 CloseFdNoError(fd, retries - 1)
68
69
70
71
73 """Sets or unsets the close-on-exec flag on a file descriptor.
74
75 @type fd: int
76 @param fd: File descriptor
77 @type enable: bool
78 @param enable: Whether to set or unset it.
79
80 """
81 flags = fcntl.fcntl(fd, fcntl.F_GETFD)
82
83 if enable:
84 flags |= fcntl.FD_CLOEXEC
85 else:
86 flags &= ~fcntl.FD_CLOEXEC
87
88 fcntl.fcntl(fd, fcntl.F_SETFD, flags)
89
90
92 """Sets or unsets the O_NONBLOCK flag on on a file descriptor.
93
94 @type fd: int
95 @param fd: File descriptor
96 @type enable: bool
97 @param enable: Whether to set or unset it
98
99 """
100 flags = fcntl.fcntl(fd, fcntl.F_GETFL)
101
102 if enable:
103 flags |= os.O_NONBLOCK
104 else:
105 flags &= ~os.O_NONBLOCK
106
107 fcntl.fcntl(fd, fcntl.F_SETFL, flags)
108
109
111 """Calls a function again if it failed due to EINTR.
112
113 """
114 while True:
115 try:
116 return fn(*args, **kwargs)
117 except EnvironmentError, err:
118 if err.errno != errno.EINTR:
119 raise
120 except (socket.error, select.error), err:
121
122
123 if not (err.args and err.args[0] == errno.EINTR):
124 raise
125
126
128 """Ignores ESRCH when calling a process-related function.
129
130 ESRCH is raised when a process is not found.
131
132 @rtype: bool
133 @return: Whether process was found
134
135 """
136 try:
137 fn(*args, **kwargs)
138 except EnvironmentError, err:
139
140 if err.errno == errno.ESRCH:
141 return False
142 raise
143
144 return True
145
146
148 """Tries to call a function ignoring failures due to EINTR.
149
150 """
151 try:
152 return fn(*args, **kwargs)
153 except EnvironmentError, err:
154 if err.errno == errno.EINTR:
155 return None
156 else:
157 raise
158 except (select.error, socket.error), err:
159
160
161 if err.args and err.args[0] == errno.EINTR:
162 return None
163 else:
164 raise
165
166
168 """Creates a temporary file and returns its path.
169
170 """
171 (fd, path) = tempfile.mkstemp(*args, **kwargs)
172 CloseFdNoError(fd)
173 return path
174
175
177 """Checks whether a file exists and is executable.
178
179 @type filename: string
180 @param filename: Filename
181 @rtype: bool
182
183 """
184 return os.path.isfile(filename) and os.access(filename, os.X_OK)
185
186
188 """Resets the random name generator of the tempfile module.
189
190 This function should be called after C{os.fork} in the child process to
191 ensure it creates a newly seeded random generator. Otherwise it would
192 generate the same random parts as the parent process. If several processes
193 race for the creation of a temporary file, this could lead to one not getting
194 a temporary name.
195
196 """
197
198 if ((sys.hexversion >= 0x020703F0 and sys.hexversion < 0x03000000) or
199 sys.hexversion >= 0x030203F0):
200
201 return
202
203 try:
204 lock = tempfile._once_lock
205 lock.acquire()
206 try:
207
208 if tempfile._name_sequence:
209 tempfile._name_sequence.rng.seed(hash(_time()) ^ os.getpid())
210 finally:
211 lock.release()
212 except AttributeError:
213 logging.critical("The tempfile module misses at least one of the"
214 " '_once_lock' and '_name_sequence' attributes")
215