Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Global flock file accessible by every user / Introducing FlockContext manager #1697

Merged
merged 14 commits into from
May 18, 2024
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Back In Time

Version 1.4.4-dev (development of upcoming release)
* Fix: Global flock for multiple users (#1122, #1676)
* Fix: Validation of diff command settings in compare snapshots dialog (#1662) (@stcksmsh Kosta Vukicevic)
* Fix bug: Open symlinked folders in file view (#1476)
* Fix bug: Respect dark mode using color roles (#1601)
Expand Down
29 changes: 15 additions & 14 deletions common/applicationinstance.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
# Back In Time
# Copyright (C) 2008-2022 Oprea Dan, Bart de Koning, Richard Bailey, Germar Reitze
# Back In Time
# Copyright (C) 2008-2022 Oprea Dan, Bart de Koning, Richard Bailey,
# Germar Reitze
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""
This module holds the ApplicationInstance class, used to handle
the one application instance mechanism
the one application instance mechanism.
"""

import os
Expand Down
64 changes: 64 additions & 0 deletions common/flock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# SPDX-FileCopyrightText: © 2024 Christian BUHTZ <c.buhtz@posteo.jp>
buhtz marked this conversation as resolved.
Show resolved Hide resolved
#
# SPDX-License-Identifier: GPL-2.0
#
# This file is part of the program "Back In time" which is released under GNU
# General Public License v2 (GPLv2).
# See file LICENSE or go to <https://www.gnu.org/licenses/#GPL>.
import os
import fcntl
from pathlib import Path
import logger


class FlockContext:
"""Context manager to manage flock.

Usage example ::

with FlockContext('backintime.lock'):
do_fancy_things()

"""
def __init__(self, filename: str, folder: Path = None):
# default
if folder is None:
folder = Path(Path.cwd().root) / 'run' / 'lock'

# out-dated default
if not folder.exists():
folder = Path(Path.cwd().root) / 'var' / 'lock'

self._file_path = folder / filename
"""Path to used for flock"""

def __enter__(self):
self._log('Set')

# Open (and create if needed) the file
mode = 'r' if self._file_path.exists() else 'w'
self._flock_handle = self._file_path.open(mode)

# blocks (waits) until an existing flock is released
fcntl.flock(self._flock_handle, fcntl.LOCK_EX)

# If new created file set itspermissions to "rw-rw-rw".
# otherwise a foreign user is not able to use it.
if mode == 'w':
self._file_path.chmod(int('0o666', 8))

return self

def __exit__(self, exc_type, exc_value, exc_tb):
self._log('Release')
fcntl.fcntl(self._flock_handle, fcntl.LOCK_UN)
self._flock_handle.close()

def _log(self, prefix: str):
logger.debug(f'{prefix} flock {self._file_path} by PID {os.getpid()}',
self)


class GlobalFlock(FlockContext):
buhtz marked this conversation as resolved.
Show resolved Hide resolved
def __init__(self):
super().__init__('backintime.lock')