diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2024-05-03 09:13:00 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2024-05-03 09:13:00 +0200 |
| commit | 064717fcc800d9ca94366745610305d12a5532a4 (patch) | |
| tree | 538e14ed2bccd4d176c163a22f709def397df9a1 /lockfiles.lua | |
| parent | 6bce026b0c664ba9686a37e614330cb84be3a5e6 (diff) | |
| download | vis-lockfiles-064717fcc800d9ca94366745610305d12a5532a4.tar.gz vis-lockfiles-064717fcc800d9ca94366745610305d12a5532a4.zip | |
split lock file functions into separate file to enable testing
Diffstat (limited to 'lockfiles.lua')
| -rw-r--r-- | lockfiles.lua | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/lockfiles.lua b/lockfiles.lua new file mode 100644 index 0000000..9e120bd --- /dev/null +++ b/lockfiles.lua @@ -0,0 +1,84 @@ +-- Copyright (c) 2024 Florian Fischer. All rights reserved. +-- +-- vis-lockfiles 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 3 of the License, or (at your option) any later +-- version. +-- +-- vis-lockfiles 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 +-- vis-lockfiles found in the LICENSE file. +-- If not, see <https://www.gnu.org/licenses/>. +-- Helper to execute a command and capture its output +local function capture_cmd(cmd) + local p = assert(io.popen(cmd, 'r')) + local s = assert(p:read('*a')) + local success, _, status = p:close() + if not success then + local err = cmd .. ' failed with exit code: ' .. status + vis:info('vis-lockfiles: ' .. err) + end + return s +end + +local function lock_file_path(lock_dir, path) + -- escape '%' first + local filename = path:gsub('%%', '%%25'):gsub('/', '%%2F') + return lock_dir .. '/' .. filename .. '.lock' +end + +-- determine vis' pid +local vis_pid +do + local vis_proc_file = io.open('/proc/self/stat', 'r') + if vis_proc_file then + vis_pid = vis_proc_file:read('*n') + vis_proc_file:close() + + else -- fallback if /proc/self/stat is not available + local out = capture_cmd('sh -c "echo $PPID"') + vis_pid = tonumber(out) + end +end +assert(vis_pid) + +local function create_lock_file(lock_dir, lfile_path) + local lock_file = io.open(lfile_path) + if lock_file then + lock_file:close() + return false + end + + -- create the lock file with our pid + if not io.open(lfile_path, 'w') then + assert(os.execute('mkdir -p "' .. lock_dir .. '"')) + end + lock_file = assert(io.open(lfile_path, 'w')) + lock_file:write(vis_pid) + lock_file:close() + + -- detect a possible race + lock_file = assert(io.open(lfile_path)) + local lock_pid = lock_file:read('*n') + lock_file:close() + local locked = tonumber(lock_pid) == vis_pid + + return locked +end + +local function delete_lock_file(lfile_path) + local success, err = os.remove(lfile_path) + if not success then + vis:info('vis-lockfiles: ' .. err) + end +end + +return { + capture_cmd = capture_cmd, + lock_file_path = lock_file_path, + delete_lock_file = delete_lock_file, + create_lock_file = create_lock_file, +} |
