diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2025-05-20 11:57:55 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2025-05-21 18:57:50 +0200 |
commit | 9b192ebb312741672babd46523d8558b6e74ff9a (patch) | |
tree | 7af98a5c5526aaf486416c818c462192e16bc6ef /rename_exchange.py | |
parent | d3df2c2ef8d253ffa3365d0eec326bb611b9b7e2 (diff) |
webmap-import: Add option to generate Mapbox Vector Tiles (MVT).
Diffstat (limited to 'rename_exchange.py')
-rw-r--r-- | rename_exchange.py | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/rename_exchange.py b/rename_exchange.py new file mode 100644 index 0000000..b1b02cb --- /dev/null +++ b/rename_exchange.py @@ -0,0 +1,48 @@ +# © 2022 Nicko van Someren +# License: MIT + +# pylint: disable=missing-module-docstring + +from ctypes import CDLL, get_errno +from os import strerror, PathLike, fsencode +from platform import machine +from typing import Optional + +SYSCALL_ARCH_MAP = { + 'x86_64': 316, + 'armv6l': 382, + 'armv7l': 382, + 'aarch64': 276, + 'i386': 353, +} + +libc = CDLL('libc.so.6', use_errno=True) +syscall_function = libc.syscall +ARCH = machine() +RENAME_EXCHANGE = 2 +AT_FDCWD = -100 + +if ARCH not in SYSCALL_ARCH_MAP: + raise NotImplementedError(f'Unsupported architecture: {ARCH}') + +SYSCALL_RENAMEAT2 = SYSCALL_ARCH_MAP[ARCH] + +def rename_exchange(oldpath : PathLike, + newpath : PathLike, + olddirfd : Optional[int] = None, + newdirfd : Optional[int] = None) -> None: + """Atomically exchange oldpath and newpath. Both pathnames must + exist but may be of different types (e.g., one could be a non-empty + directory and the other a symbolic link).""" + + result = syscall_function( + SYSCALL_RENAMEAT2, + olddirfd if olddirfd is not None else AT_FDCWD, + fsencode(oldpath), + newdirfd if newdirfd is not None else AT_FDCWD, + fsencode(newpath), + RENAME_EXCHANGE, + ) + if result != 0: + errno = get_errno() + raise OSError(errno, strerror(errno)) |