Skip to content

Commit 8c1d919

Browse files
Merge pull request #9097 from valtron/fix-win-fileurl
Fix windows file URLs
2 parents ca70665 + 1f76b6a commit 8c1d919

3 files changed

Lines changed: 31 additions & 4 deletions

File tree

src/borg/legacyremote.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from .version import parse_version, format_version
3333
from .checksums import xxh64
3434
from .helpers.datastruct import EfficientCollectionQueue
35+
from .platform import is_win32
3536

3637
logger = create_logger(__name__)
3738

@@ -276,7 +277,13 @@ def __init__(self, location, create=False, exclusive=False, lock_wait=None, lock
276277
logger.debug("SSH command line: %s", borg_cmd)
277278
# we do not want the ssh getting killed by Ctrl-C/SIGINT because it is needed for clean shutdown of borg.
278279
self.p = Popen(
279-
borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint
280+
borg_cmd,
281+
bufsize=0,
282+
stdin=PIPE,
283+
stdout=PIPE,
284+
stderr=PIPE,
285+
env=env,
286+
preexec_fn=None if is_win32 else ignore_sigint,
280287
) # nosec B603
281288
self.stdin_fd = self.p.stdin.fileno()
282289
self.stdout_fd = self.p.stdout.fileno()

src/borg/remote.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from .version import parse_version, format_version
4040
from .checksums import xxh64
4141
from .helpers.datastruct import EfficientCollectionQueue
42+
from .platform import is_win32
4243

4344
logger = create_logger(__name__)
4445

@@ -577,7 +578,13 @@ def __init__(self, location, create=False, exclusive=False, lock_wait=1.0, lock=
577578
logger.debug("SSH command line: %s", borg_cmd)
578579
# we do not want the ssh getting killed by Ctrl-C/SIGINT because it is needed for clean shutdown of borg.
579580
self.p = Popen(
580-
borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint
581+
borg_cmd,
582+
bufsize=0,
583+
stdin=PIPE,
584+
stdout=PIPE,
585+
stderr=PIPE,
586+
env=env,
587+
preexec_fn=None if is_win32 else ignore_sigint,
581588
) # nosec B603
582589
self.stdin_fd = self.p.stdin.fileno()
583590
self.stdout_fd = self.p.stdout.fileno()

src/borg/repository.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import sys
23
import time
34

45
from borgstore.store import Store
@@ -105,11 +106,11 @@ def __init__(
105106
if isinstance(path_or_location, Location):
106107
location = path_or_location
107108
if location.proto == "file":
108-
url = f"file://{location.path}" # frequently users give without file:// prefix
109+
url = _local_abspath_to_file_url(location.path) # frequently users give without file:// prefix
109110
else:
110111
url = location.processed # location as given by user, processed placeholders
111112
else:
112-
url = "file://%s" % os.path.abspath(path_or_location)
113+
url = _local_abspath_to_file_url(os.path.abspath(path_or_location))
113114
location = Location(url)
114115
self._location = location
115116
self.url = url
@@ -565,3 +566,15 @@ def store_delete(self, name, *, deleted=False):
565566
def store_move(self, name, new_name=None, *, delete=False, undelete=False, deleted=False):
566567
self._lock_refresh()
567568
return self.store.move(name, new_name, delete=delete, undelete=undelete, deleted=deleted)
569+
570+
def _local_abspath_to_file_url(path: str) -> str:
571+
"""Create a file URL from a local, absolute path.
572+
573+
Expects `path` to be an absolute path on the local filesystem, e.g.:
574+
- POSIX: `/foo/bar`
575+
- Windows: `c:/foo/bar` (or `c:\foo\bar`)
576+
The easiest way to ensure this is for the caller to pass `path` through `os.path.abspath` first.
577+
"""
578+
if sys.platform in ("win32", "msys", "cygwin"):
579+
path = "/" + path.replace("\\", "/")
580+
return "file://%s" % path

0 commit comments

Comments
 (0)