Last active
October 30, 2023 15:54
-
-
Save rlcamp/175605ae1993eddfc854e921dc2de855 to your computer and use it in GitHub Desktop.
calls flock(2) for various use cases, behaves like unix flock, python and perl implementations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
use strict; | |
use Fcntl qw(:DEFAULT :flock); | |
if (!@ARGV) { die "Usage: $0 fd | { lockfile prog args }\n"; } | |
# get a filehandle to either the supplied filename or fd, depending on whether it is an integer | |
open(my $fh, $ARGV[0] =~ /^\d+$/ ? ">&=" : ">", $ARGV[0]) or die "cannot open: $!\n"; | |
# flock the filehandle | |
flock($fh, LOCK_EX) or die "cannot flock: $!\n"; | |
# if there are additional command line arguments, treat them as a command to run with the lock held | |
shift @ARGV; | |
if (@ARGV) { | |
# discard cloexec | |
fcntl($fh, F_SETFD, fcntl($fh, F_GETFD, 0) & ~FD_CLOEXEC) or die "cannot fcntl: $!\n"; | |
exec @ARGV; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from os import execvp, open, strerror, O_RDWR, O_CREAT | |
from stat import S_IRUSR, S_IWUSR | |
from fcntl import fcntl, flock, LOCK_EX, F_SETFD, F_GETFD, FD_CLOEXEC | |
from sys import argv | |
if len(argv) < 2: raise RuntimeError('usage: %s fd | { lockfile prog args}' % argv[0]) | |
fd = int(argv[1]) if argv[1].isnumeric() else open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR) | |
if -1 == fd: raise RuntimeError('cannot open: %s' % strerror(ctypes.get_errno)) | |
if -1 == flock(fd, LOCK_EX): raise RuntimeError('cannot flock: %s' % strerror(ctypes.get_errno)) | |
# if more arguments were given, treat them as a command to execute | |
if len(argv) > 2: | |
if -1 == fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC): | |
raise RuntimeError('cannot discard cloexec: %s' % strerror(ctypes.get_errno)) | |
if -1 == execvp(argv[2], argv[2::]): RuntimeError('cannot exec: %s' % strerror(ctypes.get_errno)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment