archival: our filenames are bytes, not strs
Differential Revision: https://phab.mercurial-scm.org/D2656
archival: tar file modes need to be sysstrs
Differential Revision: https://phab.mercurial-scm.org/D2655
archival: fsdecode paths before passing to tar or zip objects
Both of these traffic in unicodes for filenames on Python 3, and
inspection of the tarfile module shows that it uses the filesystem
encoding, so fsdecode is the right choice.
Differential Revision: https://phab.mercurial-scm.org/D2654
py3: add b'' prefixes in tests/test-minirst.py
# skip-blame because just b'' prefixes
Differential Revision: https://phab.mercurial-scm.org/D2653
py3: make sure __repr__ returns a str
# skip-blame because just r'' prefix
Differential Revision: https://phab.mercurial-scm.org/D2652
py3: make sure regular expressions are bytes
# skip-blame because just b'' prefix
Differential Revision: https://phab.mercurial-scm.org/D2651
py3: use bytes instead of str to make sure we use bytes internally
Differential Revision: https://phab.mercurial-scm.org/D2650
py3: use util.forcebytestr instead of str to convert error messages
Differential Revision: https://phab.mercurial-scm.org/D2649
lock: block signal interrupt while making a lock file
On Windows where symlink isn't supported, util.makelock() could leave an empty
file if interrupted immediately after os.open(). This empty lock never dies
as it has no process id recorded.
ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
# an interrupt may occur here
os.write(ld, info)
os.close(ld)
This was a long-standing bug of TortoiseHg which runs a command-server and
kills it by CTRL_C_EVENT, reported by random Windows users.
https://bitbucket.org/tortoisehg/thg/issues/4873/#comment-
43591129
At first, I tried to fix makelock() to clean up a stale lock file, which
turned out to be hard because any instructions may be interrupted by a
signal.
ld = None
try:
# CALL_FUNCTION # os.open(...)
# an interrupt may occur here
# STORE_FAST # ld = ...
ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)
os.write(ld, info)
...
return True
except:
if ld:
...
os.unlink(pathname)
return False
So I decided to block signals by temporarily replacing the signal handlers
so makelcok() and held = 1 will never be interrupted.
Many thanks to Fernando Najera for investigating the issue.
fuzz: add some more docs about building/running fuzzers
Differential Revision: https://phab.mercurial-scm.org/D2635