Skip to content

Commit 4c7398a

Browse files
author
James William Pye
committed
Be more careful about closing file descriptors associated with the process.
1 parent 9459ff7 commit 4c7398a

1 file changed

Lines changed: 34 additions & 24 deletions

File tree

postgresql/cluster.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ def init(self,
237237

238238
supw_file = ()
239239
supw_tmp = None
240+
p = None
240241
try:
241242
if password is not None:
242243
# got a superuserpass, store it in a tempfile for initdb
@@ -269,34 +270,43 @@ def init(self,
269270
except OSError as e:
270271
if e.errno != errno.EINTR:
271272
raise
273+
finally:
274+
if p.stdout is not None:
275+
p.stdout.close()
276+
277+
if rc != 0:
278+
# initdb returned non-zero, pickup stderr and attach to exception.
279+
280+
r = p.stderr.read().strip()
281+
try:
282+
msg = r.decode('utf-8')
283+
except UnicodeDecodeError:
284+
# split up the lines, and use rep.
285+
msg = os.linesep.join([
286+
repr(x)[2:-1] for x in r.splitlines()
287+
])
288+
raise InitDBError(
289+
"initdb exited with non-zero status",
290+
details = {
291+
'command': cmd,
292+
'stderr': msg,
293+
'stdout': msg,
294+
},
295+
creator = self
296+
)
272297
finally:
273-
# stdlib fail. Make sure the temp gets deleted.
274-
# NamedTemporaryFile has inconsistencies across platforms. :(
298+
if p is not None:
299+
for x in (p.stderr, p.stdin, p.stdout):
300+
if x is not None:
301+
x.close()
302+
275303
if supw_tmp is not None:
276304
n = supw_tmp.name
277305
supw_tmp.close()
306+
# XXX: win32 compensation.
278307
if os.path.exists(n):
279308
os.unlink(n)
280309

281-
if rc != 0:
282-
r = p.stderr.read().strip()
283-
try:
284-
msg = r.decode('utf-8')
285-
except UnicodeDecodeError:
286-
# split up the lines, and use rep.
287-
msg = os.linesep.join([
288-
repr(x)[2:-1] for x in r.splitlines()
289-
])
290-
raise InitDBError(
291-
"initdb exited with non-zero status",
292-
details = {
293-
'command': cmd,
294-
'stderr': msg,
295-
'stdout': msg,
296-
},
297-
creator = self
298-
)
299-
300310
def drop(self):
301311
"""
302312
Stop the cluster and remove it from the filesystem
@@ -312,9 +322,7 @@ def drop(self):
312322
except ClusterTimeoutError:
313323
ClusterWarning(
314324
'cluster failed to shutdown after kill',
315-
details = {
316-
'hint' : 'Shared memory may be leaked.'
317-
},
325+
details = {'hint' : 'Shared memory may have been leaked.'},
318326
creator = self
319327
).emit()
320328
# Really, using rm -rf would be the best, but use this for portability.
@@ -633,6 +641,8 @@ def wait_until_stopped(self,
633641
# pickup the exit code.
634642
if self.daemon_process is not None:
635643
self.last_exit_code = self.daemon_process.poll()
644+
else:
645+
self.last_exit_code = pg_kill(self.get_pid_from_file(), 0)
636646
if time.time() - start >= timeout:
637647
raise ClusterTimeoutError(
638648
'timeout on shutdown',

0 commit comments

Comments
 (0)