Browse Source

Merge pull request #9097 from valtron/fix-win-fileurl

Fix windows file URLs
TW 1 week ago
parent
commit
8c1d919095
3 changed files with 31 additions and 4 deletions
  1. 8 1
      src/borg/legacyremote.py
  2. 8 1
      src/borg/remote.py
  3. 15 2
      src/borg/repository.py

+ 8 - 1
src/borg/legacyremote.py

@@ -32,6 +32,7 @@ from .legacyrepository import LegacyRepository
 from .version import parse_version, format_version
 from .checksums import xxh64
 from .helpers.datastruct import EfficientCollectionQueue
+from .platform import is_win32
 
 logger = create_logger(__name__)
 
@@ -276,7 +277,13 @@ class LegacyRemoteRepository:
             logger.debug("SSH command line: %s", borg_cmd)
             # we do not want the ssh getting killed by Ctrl-C/SIGINT because it is needed for clean shutdown of borg.
             self.p = Popen(
-                borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint
+                borg_cmd,
+                bufsize=0,
+                stdin=PIPE,
+                stdout=PIPE,
+                stderr=PIPE,
+                env=env,
+                preexec_fn=None if is_win32 else ignore_sigint,
             )  # nosec B603
             self.stdin_fd = self.p.stdin.fileno()
             self.stdout_fd = self.p.stdout.fileno()

+ 8 - 1
src/borg/remote.py

@@ -39,6 +39,7 @@ from .repository import Repository
 from .version import parse_version, format_version
 from .checksums import xxh64
 from .helpers.datastruct import EfficientCollectionQueue
+from .platform import is_win32
 
 logger = create_logger(__name__)
 
@@ -577,7 +578,13 @@ class RemoteRepository:
             logger.debug("SSH command line: %s", borg_cmd)
             # we do not want the ssh getting killed by Ctrl-C/SIGINT because it is needed for clean shutdown of borg.
             self.p = Popen(
-                borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint
+                borg_cmd,
+                bufsize=0,
+                stdin=PIPE,
+                stdout=PIPE,
+                stderr=PIPE,
+                env=env,
+                preexec_fn=None if is_win32 else ignore_sigint,
             )  # nosec B603
             self.stdin_fd = self.p.stdin.fileno()
             self.stdout_fd = self.p.stdout.fileno()

+ 15 - 2
src/borg/repository.py

@@ -1,4 +1,5 @@
 import os
+import sys
 import time
 
 from borgstore.store import Store
@@ -105,11 +106,11 @@ class Repository:
         if isinstance(path_or_location, Location):
             location = path_or_location
             if location.proto == "file":
-                url = f"file://{location.path}"  # frequently users give without file:// prefix
+                url = _local_abspath_to_file_url(location.path)  # frequently users give without file:// prefix
             else:
                 url = location.processed  # location as given by user, processed placeholders
         else:
-            url = "file://%s" % os.path.abspath(path_or_location)
+            url = _local_abspath_to_file_url(os.path.abspath(path_or_location))
             location = Location(url)
         self._location = location
         self.url = url
@@ -565,3 +566,15 @@ class Repository:
     def store_move(self, name, new_name=None, *, delete=False, undelete=False, deleted=False):
         self._lock_refresh()
         return self.store.move(name, new_name, delete=delete, undelete=undelete, deleted=deleted)
+
+def _local_abspath_to_file_url(path: str) -> str:
+    """Create a file URL from a local, absolute path.
+    
+    Expects `path` to be an absolute path on the local filesystem, e.g.:
+    - POSIX: `/foo/bar`
+    - Windows: `c:/foo/bar` (or `c:\foo\bar`)
+    The easiest way to ensure this is for the caller to pass `path` through `os.path.abspath` first.
+    """
+    if sys.platform in ("win32", "msys", "cygwin"):
+        path = "/" + path.replace("\\", "/")
+    return "file://%s" % path