]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/metadata.py
metadata: accept EOPNOTSUPP for lchmod()
[bup.git] / lib / bup / metadata.py
index 0d577806abda2ff4256688d227a6f62b3a2f6eda..83f04f771475457641c96e369d500b45be946a0b 100644 (file)
@@ -6,15 +6,13 @@
 # Public License as described in the bup LICENSE file.
 
 from __future__ import absolute_import, print_function
-from binascii import hexlify
 from copy import deepcopy
 from errno import EACCES, EINVAL, ENOTTY, ENOSYS, EOPNOTSUPP
 from io import BytesIO
 from time import gmtime, strftime
-import errno, os, sys, stat, time, pwd, grp, socket, struct
+import errno, os, sys, stat, time, socket, struct
 
-from bup import compat, vint, xstat
-from bup.compat import py_maj
+from bup import vint, xstat
 from bup.drecurse import recursive_dirlist
 from bup.helpers import add_error, mkdirp, log, is_superuser, format_filesize
 from bup.io import path_msg
@@ -455,8 +453,13 @@ class Metadata:
         if _have_lchmod:
             try:
                 os.lchmod(path, stat.S_IMODE(self.mode))
-            except errno.ENOSYS:  # Function not implemented
-                pass
+            except OSError as e:
+                # - "Function not implemented"
+                # - "Operation not supported" might be generated by glibc
+                if e.errno in (errno.ENOSYS, errno.EOPNOTSUPP):
+                    pass
+                else:
+                    raise
         elif not stat.S_ISLNK(self.mode):
             os.chmod(path, stat.S_IMODE(self.mode))
 
@@ -479,6 +482,9 @@ class Metadata:
         try:
             if stat.S_ISLNK(st.st_mode):
                 self.symlink_target = os.readlink(path)
+                # might have read a different link than the
+                # one that was in place when we did stat()
+                self.size = len(self.symlink_target)
         except OSError as e:
             add_error('readlink: %s' % e)
 
@@ -884,7 +890,7 @@ class Metadata:
 
 def from_path(path, statinfo=None, archive_path=None,
               save_symlinks=True, hardlink_target=None,
-              normalized=False):
+              normalized=False, after_stat=None):
     # This function is also a test hook; see test-save-errors
     """Return the metadata associated with the path.  When normalized is
     true, return the metadata appropriate for a typical save, which
@@ -892,6 +898,8 @@ def from_path(path, statinfo=None, archive_path=None,
     result = Metadata()
     result.path = archive_path
     st = statinfo or xstat.lstat(path)
+    if after_stat:
+        after_stat(path)
     result._add_common(path, st)
     if save_symlinks:
         result._add_symlink_target(path, st)