]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/helpers.py
helpers: rename realpath to resolve_parent
[bup.git] / lib / bup / helpers.py
index 5bae5dee943d477a97f6dd65c73cc154eec089f8..b052b63021511b035a94ac9945e01dce1099637d 100644 (file)
@@ -41,11 +41,15 @@ def atof(s):
 buglvl = atoi(os.environ.get('BUP_DEBUG', 0))
 
 
-# If the platform doesn't have fdatasync (OS X), fall back to fsync.
-try:
-    fdatasync = os.fdatasync
-except AttributeError:
-    fdatasync = os.fsync
+if sys.platform.startswith('darwin'):
+    # Apparently fsync on OS X doesn't guarantee to sync all the way down
+    import fcntl
+    fdatasync = lambda fd : fcntl.fcntl(fd, fcntl.F_FULLFSYNC)
+else: # If the platform doesn't have fdatasync, fall back to fsync
+    try:
+        fdatasync = os.fdatasync
+    except AttributeError:
+        fdatasync = os.fsync
 
 
 # Write (blockingly) to sockets that may or may not be in blocking mode.
@@ -243,8 +247,8 @@ to return multiple strings in order to respect ARG_MAX)."""
         yield readpipe(command + sub_args, preexec_fn=preexec_fn)
 
 
-def realpath(p):
-    """Get the absolute path of a file.
+def resolve_parent(p):
+    """Return the absolute path of a file without following any final symlink.
 
     Behaves like os.path.realpath, but doesn't follow a symlink for the last
     element. (ie. if 'p' itself is a symlink, this one won't follow it, but it
@@ -891,15 +895,15 @@ def parse_excludes(options, fatal):
     for flag in options:
         (option, parameter) = flag
         if option == '--exclude':
-            excluded_paths.append(realpath(parameter))
+            excluded_paths.append(resolve_parent(parameter))
         elif option == '--exclude-from':
             try:
-                f = open(realpath(parameter))
+                f = open(resolve_parent(parameter))
             except IOError as e:
                 raise fatal("couldn't read %s" % parameter)
             for exclude_path in f.readlines():
                 # FIXME: perhaps this should be rstrip('\n')
-                exclude_path = realpath(exclude_path.strip())
+                exclude_path = resolve_parent(exclude_path.strip())
                 if exclude_path:
                     excluded_paths.append(exclude_path)
     return sorted(frozenset(excluded_paths))
@@ -919,7 +923,7 @@ def parse_rx_excludes(options, fatal):
                 fatal('invalid --exclude-rx pattern (%s): %s' % (parameter, ex))
         elif option == '--exclude-rx-from':
             try:
-                f = open(realpath(parameter))
+                f = open(resolve_parent(parameter))
             except IOError as e:
                 raise fatal("couldn't read %s" % parameter)
             for pattern in f.readlines():