system is provided by the Scheme implementation, the
transact package provides functions for file-locking and
Unix file-locking is focussed on write permissions for segments of a existing file. While this might be employed for (binary) database access, it is not used for everyday contention (between users) for text files.
Microsoft has several file-locking protocols. Their model denies write access to a file if any reader has it open. This is too restrictive. Write access is denied even when the reader has reached end-of-file. And tracking read access (which is much more common than write access) causes havoc when remote hosts crash or disconnect.
It is bizarre that the concept of multi-user contention for modifying files has not been adequately addressed by either of the large operating system development efforts. There is further irony that both camps support contention detection and resolution only through weak conventions of some their document editing programs.
The file-lock procedures implement a transaction method for file replacement compatible with the methods used by the GNU emacs text editor on Unix systems and the Microsoft Word editor.
Both protocols employ what I term a certificate containing the user, hostname, time, and (on Unix) process-id. Intent to replace file is indicated by adding to file’s directory a certificate object whose name is derived from file.
The Microsoft Word certificate is contained in a 162 byte file named for the visited file with a ‘~$’ prefix. Emacs/Unix creates a symbolic link to a certificate named for the visited file prefixed with ‘.#’. Because Unix systems can import Microsoft file systems, these routines maintain and check both Emacs and Word certificates.
Returns the string ‘user@hostname’ associated with the lock owner of file path if locked; and #f otherwise.
path must be a string naming the file to be locked. If supplied, email
must be a string formatted as ‘user@hostname’. If
absent, email defaults to the value returned by
If path is already locked, then
file-lock! returns ‘#f’. If path is
file-lock! returns the certificate string associated with the
new lock for file path.
path must be a string naming the file to be unlocked. certificate must be the
string returned by
file-lock! for path.
If path is locked with certificate, then
file-unlock! removes the locks and returns
file-unlock! leaves the file system unaltered and returns
path must be a string naming a file. Optional argument prefix is a string
printed before each line of the message.
describe-file-lock prints to
(current-error-port) that path is locked for writing and lists
(describe-file-lock "my.txt" ">> ") -| >> "my.txt" is locked for writing by 'firstname.lastname@example.org:1200536423' >> (lock files are "~$my.txt" and ".#my.txt")
path must be a string. backup-style must be a symbol. Depending on backup-style,
the string "path~"
the string "path.~n~", where n is one greater than the highest number appearing in a filename matching "path.~*~". n defauls to 1 when no filename matches.
the string "path.~n~" if a numbered backup already exists in this directory; otherwise. "path~"
the string "path.orig"
the string "path.bak"
path must be a string naming an existing file. backup-style is one of the symbols none, simple, numbered, existing, orig, bak or #f; with meanings described above; or a string naming the location of a backup file. backup-style defaults to #f. If supplied, certificate is the certificate with which path is locked.
proc must be a procedure taking two string arguments:
If path is locked by other than certificate, or if certificate is supplied and path is not
transact-file-replacement returns #f. If certificate is not supplied, then,
temporary (Emacs and Word) locks for path during the transaction. The
lock status of path will be restored before
transact-file-replacement calls proc with path (which should not be modified) and a temporary
file path to be written.
If proc returns any value other than #t, then the file named by path
is not altered and
transact-file-replacement returns #f.
emacs:backup-name is called with path and backup-style. If it
returns a string, then path is renamed to it.
Finally, the temporary file is renamed path.
transact-file-replacement returns #t if path was successfully replaced; and #f otherwise.
user-email-address returns a string of the form ‘username@hostname’. If
this e-mail address cannot be obtained, #f is returned.