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