From: Christian Herdtweck Date: Tue, 19 Jul 2016 10:54:15 +0000 (+0200) Subject: close files if there is trouble with new_volume_handler X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=64a6dd3e34bcc145498e702d4b66218abc2e555c;p=python-delta-tar close files if there is trouble with new_volume_handler --- diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index 1115373..1bb56d3 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -2729,7 +2729,6 @@ class TarFile(object): raise Exception("We need to create a new volume and you " "didn't supply a new_volume_handler") - # the new volume handler should do everything needed to # start working in a new volume. usually, the handler calls # to self.open_volume @@ -2744,6 +2743,26 @@ class TarFile(object): # the “new_volume_handler” is supposed to call .close() on the # “fileobj” _Stream self.new_volume_handler(self, self.base_name, self.volume_number) + try: + if not self.new_volume_handler or\ + not callable(self.new_volume_handler): + + # complain + raise Exception("We need to create a new volume and " + "you didn't supply a " + "new_volume_handler") + + self.new_volume_handler(self, self.base_name, + self.volume_number) + except Exception: + # close files + if fileobj: + fileobj.close() + if self.fileobj: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise self.volume_tarinfo = None @@ -3049,40 +3068,41 @@ class TarFile(object): source.seek(tarinfo.offset_data) decrypt = False iterate = True - target = bltn_open(targetpath, "wb") + target = None + try: + target = bltn_open(targetpath, "wb") - if tarinfo.sparse is not None: - try: + if tarinfo.sparse is not None: for offset, size in tarinfo.sparse: target.seek(offset) copyfileobj(source, target, size) target.seek(tarinfo.size) target.truncate() - finally: - target.close() return - while iterate: - iterate = False - try: - copyfileobj(source, target, tarinfo.size) - except OSError: - source.close() - # only if we are extracting a multivolume this can be treated - if not self.new_volume_handler: - raise Exception("We need to read a new volume and you" - " didn't supply a new_volume_handler") - - # the new volume handler should do everything needed to - # start working in a new volume. usually, the handler calls - # to self.open_volume - self.volume_number += 1 - self.new_volume_handler(self, self.base_name, self.volume_number) - tarinfo = self.firstmember - source = self.fileobj - iterate = True - finally: - if iterate is False: target.close() + while iterate: + iterate = False + try: + copyfileobj(source, target, tarinfo.size) + except OSError: + source.close() + # only if we are extracting a multivolume this can be treated + if not self.new_volume_handler: + raise Exception("We need to read a new volume and you" + " didn't supply a new_volume_handler") + + # the new volume handler should do everything needed to + # start working in a new volume. usually, the handler calls + # to self.open_volume + self.volume_number += 1 + self.new_volume_handler(self, self.base_name, self.volume_number) + tarinfo = self.firstmember + source = self.fileobj + iterate = True + + finally: + if target: + target.close() def makeunknown(self, tarinfo, targetpath):