from __future__ import with_statement
+from auto import HOME
+import errno as E
import itertools as I
import os as OS; ENV = OS.environ
specified by the DELIM constructor argument.
The file is updated by writing a new version alongside, as `FILE.new', and
- renaming it over the old version. If a LOCK file is named then an
- exclusive fcntl(2)-style lock is taken out on `LOCKDIR/LOCK' (creating the
- file if necessary) during the update operation. Use of a lockfile is
- strongly recommended.
+ renaming it over the old version. If a LOCK is provided then this is done
+ while holding a lock. By default, an exclusive fcntl(2)-style lock is
+ taken out on `LOCKDIR/LOCK' (creating the file if necessary) during the
+ update operation, but subclasses can override the `dolocked' method to
+ provide alternative locking behaviour; the LOCK parameter is not
+ interpreted by any other methods. Use of a lockfile is strongly
+ recommended.
The DELIM constructor argument specifies the delimiter character used when
splitting lines into fields. The USER and PASSWD arguments give the field
## If there's a lockfile, then acquire it around the meat of this
## function; otherwise just do the job.
- if me._lock is None:
- doit()
- else:
- with U.lockfile(OS.path.join(CFG.LOCKDIR, me._lock), 5):
- doit()
+ if me._lock is None: doit()
+ else: me.dolocked(me._lock, doit)
+
+ def dolocked(me, lock, func):
+ """
+ Call FUNC with the LOCK held.
+
+ Subclasses can override this method in order to provide alternative
+ locking functionality.
+ """
+ try: OS.mkdir(CFG.LOCKDIR)
+ except OSError, e:
+ if e.errno != E.EEXIST: raise
+ with U.lockfile(OS.path.join(CFG.LOCKDIR, lock), 5):
+ func()
def _parse(me, line):
"""Convenience function for constructing a record."""