Mercurial > hg-stable
comparison mercurial/util.py @ 30253:b496a464399c stable
util: add utility function to skip avoiding file stat ambiguity if EPERM
Now, advancing stat.st_mtime by os.utime() is used to avoid file stat
ambiguity. But according to POSIX specification, utime(2) with an
explicit time information is permitted only for a process with:
- the effective user ID equal to the user ID of the file, or
- appropriate privileges
http://pubs.opengroup.org/onlinepubs/9699919799/functions/utime.html
Therefore, just having group write access to a file causes EPERM at
applying os.utime() on it (e.g. working on the repository shared by
group access permission).
This patch adds class filestat utility function avoidamgig() to avoid
file stat ambiguity but skip it if EPERM.
It is reasonable to always ignore EPERM, because utime(2) causes EPERM
only in the case described above (EACCES is used only for utime(2)
with NULL).
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Sun, 13 Nov 2016 06:06:23 +0900 |
parents | 7356e6b1f5b8 |
children | 854190becacb |
comparison
equal
deleted
inserted
replaced
30252:4ed8bb8a153f | 30253:b496a464399c |
---|---|
1495 try: | 1495 try: |
1496 return (self.stat.st_ctime == old.stat.st_ctime) | 1496 return (self.stat.st_ctime == old.stat.st_ctime) |
1497 except AttributeError: | 1497 except AttributeError: |
1498 return False | 1498 return False |
1499 | 1499 |
1500 def avoidambig(self, path, old): | |
1501 """Change file stat of specified path to avoid ambiguity | |
1502 | |
1503 'old' should be previous filestat of 'path'. | |
1504 | |
1505 This skips avoiding ambiguity, if a process doesn't have | |
1506 appropriate privileges for 'path'. | |
1507 """ | |
1508 advanced = (old.stat.st_mtime + 1) & 0x7fffffff | |
1509 try: | |
1510 os.utime(path, (advanced, advanced)) | |
1511 except OSError as inst: | |
1512 if inst.errno == errno.EPERM: | |
1513 # utime() on the file created by another user causes EPERM, | |
1514 # if a process doesn't have appropriate privileges | |
1515 return | |
1516 raise | |
1517 | |
1500 def __ne__(self, other): | 1518 def __ne__(self, other): |
1501 return not self == other | 1519 return not self == other |
1502 | 1520 |
1503 class atomictempfile(object): | 1521 class atomictempfile(object): |
1504 '''writable file object that atomically updates a file | 1522 '''writable file object that atomically updates a file |