Skip to content

Instantly share code, notes, and snippets.

@dspinellis
Last active January 22, 2019 17:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dspinellis/eb924c195206f57e896d026dbe14befa to your computer and use it in GitHub Desktop.
Save dspinellis/eb924c195206f57e896d026dbe14befa to your computer and use it in GitHub Desktop.
Lock a file using lockf(3)
#!/usr/bin/env python
#
# Lock through a file using fcntl(2), i.e. lockf(3), rather than flock(2)
# as used in flock(1)
#
# Example: lockf /var/lib/dpkg/lock apt-get update
#
# Copyright 2018 Diomidis Spinellis
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import fcntl
import errno
import sys
import os
import time
if len(sys.argv) < 2:
sys.exit('Usage: lockf file [command [args ...]]')
try:
f = open(sys.argv[1], 'w')
except IOError as e:
sys.exit('lockf: Unable to open {} for writing: {}'.format(
sys.argv[1], os.strerror(e.errno)))
while True:
try:
fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
if len(sys.argv) > 2:
try:
os.execvp(sys.argv[2], sys.argv[2:])
except OSError as e:
sys.exit('lockf: Unable to execute {}: {}'.format(
sys.argv[2], os.strerror(e.errno)))
sys.exit(0)
except IOError as e:
if e.errno != errno.EAGAIN:
sys.exit('lockf: Unable to lock {}: {}'.format(
sys.argv[1], os.strerror(e.errno)))
time.sleep(1)
@dspinellis
Copy link
Author

dspinellis commented Dec 29, 2018

See also with-lock-ex. The advantage of this lockf.py small script over the with-lock-ex program is that lockf.py doesn't require installation via a package manager.

@lmpampaletakis
Copy link

Informational: It would be more elegant if you use argparse, in order to give a hint about the usage of commandline arguments!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment