Mercurial > hg
changeset 30539:29b35dac3b1f
fsmonitor: be robust in the face of bad state
fsmonitor could write out bad state if interrupted part way through, and
would then crash when it tried to read it back in.
Make both sides of the operation more robust - reading state should fail
cleanly, and we can use atomictemp to write out cleanly as the file is
small. Between the two, we shouldn't crash with an IndexError any more.
author | Simon Farnsworth <simonfar@fb.com> |
---|---|
date | Fri, 25 Nov 2016 07:30:46 -0800 |
parents | c2154979409d |
children | d955cebd8d6a |
files | hgext/fsmonitor/state.py |
diffstat | 1 files changed, 8 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/fsmonitor/state.py Wed Nov 23 23:47:38 2016 +0100 +++ b/hgext/fsmonitor/state.py Fri Nov 25 07:30:46 2016 -0800 @@ -59,6 +59,12 @@ state = file.read().split('\0') # state = hostname\0clock\0ignorehash\0 + list of files, each # followed by a \0 + if len(state) < 3: + self._ui.log( + 'fsmonitor', 'fsmonitor: state file truncated (expected ' + '3 chunks, found %d), nuking state\n', len(state)) + self.invalidate() + return None, None, None diskhostname = state[0] hostname = socket.gethostname() if diskhostname != hostname: @@ -85,12 +91,12 @@ return try: - file = self._opener('fsmonitor.state', 'wb') + file = self._opener('fsmonitor.state', 'wb', atomictemp=True) except (IOError, OSError): self._ui.warn(_("warning: unable to write out fsmonitor state\n")) return - try: + with file: file.write(struct.pack(_versionformat, _version)) file.write(socket.gethostname() + '\0') file.write(clock + '\0') @@ -98,8 +104,6 @@ if notefiles: file.write('\0'.join(notefiles)) file.write('\0') - finally: - file.close() def invalidate(self): try: