Fix chmod of writable but unowned files (issue530)
authorThomas Arendsen Hein <thomas@intevation.de>
Tue, 25 Dec 2007 14:05:26 +0100
changeset 5668 ca4f10c76ea7
parent 5667 f29b7c8419cb
child 5669 a0eb8a418442
child 5691 8e495dd6662e
Fix chmod of writable but unowned files (issue530) This could happen e.g. in group writable local repositories where a file should become executable on update. (Patch by Benoit Boissinot attached to issue530)
mercurial/util.py
--- a/mercurial/util.py	Fri Dec 21 12:07:02 2007 +0100
+++ b/mercurial/util.py	Tue Dec 25 14:05:26 2007 +0100
@@ -1106,6 +1106,17 @@
         """check whether a file is executable"""
         return (os.lstat(f).st_mode & 0100 != 0)
 
+    def force_chmod(f, s):
+        try:
+            os.chmod(f, s)
+        except OSError, inst:
+            if inst.errno != errno.EPERM:
+                raise
+            # maybe we don't own the file, try copying it
+            new_f = mktempcopy(f)
+            os.chmod(new_f, s)
+            os.rename(new_f, f)
+
     def set_exec(f, mode):
         s = os.lstat(f).st_mode
         if stat.S_ISLNK(s) or (s & 0100 != 0) == mode:
@@ -1113,9 +1124,9 @@
         if mode:
             # Turn on +x for every +r bit when making a file executable
             # and obey umask.
-            os.chmod(f, s | (s & 0444) >> 2 & ~_umask)
+            force_chmod(f, s | (s & 0444) >> 2 & ~_umask)
         else:
-            os.chmod(f, s & 0666)
+            force_chmod(f, s & 0666)
 
     def set_link(f, mode):
         """make a file a symbolic link/regular file