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())