Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 14168:135e244776f0
prevent transient leaks of file handle by using new helper functions
These leaks may occur in environments that don't employ a reference
counting GC, i.e. PyPy.
This implies:
- changing opener(...).read() calls to opener.read(...)
- changing opener(...).write() calls to opener.write(...)
- changing open(...).read(...) to util.readfile(...)
- changing open(...).write(...) to util.writefile(...)
author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
---|---|
date | Mon, 02 May 2011 10:11:18 +0200 |
parents | 301725c3df9a |
children | 4ab6e2d597cc |
comparison
equal
deleted
inserted
replaced
14167:0e4753807c93 | 14168:135e244776f0 |
---|---|
54 if self.ui.configbool('format', 'usefncache', True): | 54 if self.ui.configbool('format', 'usefncache', True): |
55 requirements.append("fncache") | 55 requirements.append("fncache") |
56 if self.ui.configbool('format', 'dotencode', True): | 56 if self.ui.configbool('format', 'dotencode', True): |
57 requirements.append('dotencode') | 57 requirements.append('dotencode') |
58 # create an invalid changelog | 58 # create an invalid changelog |
59 self.opener("00changelog.i", "a").write( | 59 self.opener.append( |
60 "00changelog.i", | |
60 '\0\0\0\2' # represents revlogv2 | 61 '\0\0\0\2' # represents revlogv2 |
61 ' dummy changelog to prevent using the old repo layout' | 62 ' dummy changelog to prevent using the old repo layout' |
62 ) | 63 ) |
63 if self.ui.configbool('format', 'parentdelta', False): | 64 if self.ui.configbool('format', 'parentdelta', False): |
64 requirements.append("parentdelta") | 65 requirements.append("parentdelta") |
68 raise error.RepoError(_("repository %s already exists") % path) | 69 raise error.RepoError(_("repository %s already exists") % path) |
69 else: | 70 else: |
70 # find requirements | 71 # find requirements |
71 requirements = set() | 72 requirements = set() |
72 try: | 73 try: |
73 requirements = set(self.opener("requires").read().splitlines()) | 74 requirements = set(self.opener.read("requires").splitlines()) |
74 except IOError, inst: | 75 except IOError, inst: |
75 if inst.errno != errno.ENOENT: | 76 if inst.errno != errno.ENOENT: |
76 raise | 77 raise |
77 for r in requirements - self.supported: | 78 for r in requirements - self.supported: |
78 raise error.RequirementError( | 79 raise error.RequirementError( |
79 _("requirement '%s' not supported") % r) | 80 _("requirement '%s' not supported") % r) |
80 | 81 |
81 self.sharedpath = self.path | 82 self.sharedpath = self.path |
82 try: | 83 try: |
83 s = os.path.realpath(self.opener("sharedpath").read()) | 84 s = os.path.realpath(self.opener.read("sharedpath")) |
84 if not os.path.exists(s): | 85 if not os.path.exists(s): |
85 raise error.RepoError( | 86 raise error.RepoError( |
86 _('.hg/sharedpath points to nonexistent directory %s') % s) | 87 _('.hg/sharedpath points to nonexistent directory %s') % s) |
87 self.sharedpath = s | 88 self.sharedpath = s |
88 except IOError, inst: | 89 except IOError, inst: |
650 | 651 |
651 def wread(self, filename): | 652 def wread(self, filename): |
652 if self._link(filename): | 653 if self._link(filename): |
653 data = os.readlink(self.wjoin(filename)) | 654 data = os.readlink(self.wjoin(filename)) |
654 else: | 655 else: |
655 data = self.wopener(filename, 'r').read() | 656 data = self.wopener.read(filename) |
656 return self._filter(self._encodefilterpats, filename, data) | 657 return self._filter(self._encodefilterpats, filename, data) |
657 | 658 |
658 def wwrite(self, filename, data, flags): | 659 def wwrite(self, filename, data, flags): |
659 data = self._filter(self._decodefilterpats, filename, data) | 660 data = self._filter(self._decodefilterpats, filename, data) |
660 if 'l' in flags: | 661 if 'l' in flags: |
661 self.wopener.symlink(data, filename) | 662 self.wopener.symlink(data, filename) |
662 else: | 663 else: |
663 self.wopener(filename, 'w').write(data) | 664 fp = self.wopener.write(filename, data) |
664 if 'x' in flags: | 665 if 'x' in flags: |
665 util.set_flags(self.wjoin(filename), False, True) | 666 util.set_flags(self.wjoin(filename), False, True) |
666 | 667 |
667 def wwritedata(self, filename, data): | 668 def wwritedata(self, filename, data): |
668 return self._filter(self._decodefilterpats, filename, data) | 669 return self._filter(self._decodefilterpats, filename, data) |
677 raise error.RepoError( | 678 raise error.RepoError( |
678 _("abandoned transaction found - run hg recover")) | 679 _("abandoned transaction found - run hg recover")) |
679 | 680 |
680 # save dirstate for rollback | 681 # save dirstate for rollback |
681 try: | 682 try: |
682 ds = self.opener("dirstate").read() | 683 ds = self.opener.read("dirstate") |
683 except IOError: | 684 except IOError: |
684 ds = "" | 685 ds = "" |
685 self.opener("journal.dirstate", "w").write(ds) | 686 self.opener.write("journal.dirstate", ds) |
686 self.opener("journal.branch", "w").write( | 687 self.opener.write("journal.branch", |
687 encoding.fromlocal(self.dirstate.branch())) | 688 encoding.fromlocal(self.dirstate.branch())) |
688 self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc)) | 689 self.opener.write("journal.desc", |
690 "%d\n%s\n" % (len(self), desc)) | |
689 | 691 |
690 renames = [(self.sjoin("journal"), self.sjoin("undo")), | 692 renames = [(self.sjoin("journal"), self.sjoin("undo")), |
691 (self.join("journal.dirstate"), self.join("undo.dirstate")), | 693 (self.join("journal.dirstate"), self.join("undo.dirstate")), |
692 (self.join("journal.branch"), self.join("undo.branch")), | 694 (self.join("journal.branch"), self.join("undo.branch")), |
693 (self.join("journal.desc"), self.join("undo.desc"))] | 695 (self.join("journal.desc"), self.join("undo.desc"))] |
718 try: | 720 try: |
719 wlock = self.wlock() | 721 wlock = self.wlock() |
720 lock = self.lock() | 722 lock = self.lock() |
721 if os.path.exists(self.sjoin("undo")): | 723 if os.path.exists(self.sjoin("undo")): |
722 try: | 724 try: |
723 args = self.opener("undo.desc", "r").read().splitlines() | 725 args = self.opener.read("undo.desc").splitlines() |
724 if len(args) >= 3 and self.ui.verbose: | 726 if len(args) >= 3 and self.ui.verbose: |
725 desc = _("repository tip rolled back to revision %s" | 727 desc = _("repository tip rolled back to revision %s" |
726 " (undo %s: %s)\n") % ( | 728 " (undo %s: %s)\n") % ( |
727 int(args[0]) - 1, args[1], args[2]) | 729 int(args[0]) - 1, args[1], args[2]) |
728 elif len(args) >= 2: | 730 elif len(args) >= 2: |
739 util.rename(self.join("undo.dirstate"), self.join("dirstate")) | 741 util.rename(self.join("undo.dirstate"), self.join("dirstate")) |
740 if os.path.exists(self.join('undo.bookmarks')): | 742 if os.path.exists(self.join('undo.bookmarks')): |
741 util.rename(self.join('undo.bookmarks'), | 743 util.rename(self.join('undo.bookmarks'), |
742 self.join('bookmarks')) | 744 self.join('bookmarks')) |
743 try: | 745 try: |
744 branch = self.opener("undo.branch").read() | 746 branch = self.opener.read("undo.branch") |
745 self.dirstate.setbranch(branch) | 747 self.dirstate.setbranch(branch) |
746 except IOError: | 748 except IOError: |
747 self.ui.warn(_("named branch could not be reset, " | 749 self.ui.warn(_("named branch could not be reset, " |
748 "current branch is still: %s\n") | 750 "current branch is still: %s\n") |
749 % self.dirstate.branch()) | 751 % self.dirstate.branch()) |