Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
File locking
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== In Unix-like systems == [[Unix-like]] operating systems (including [[Linux]] and Apple's [[macOS]]) do not normally automatically lock open files. Several kinds of file-locking mechanisms are available in different flavors of Unix, and many operating systems support more than one kind for compatibility. The most common mechanism is <code>{{man|sh|fcntl|SUS||inline}}</code>. Two other such mechanisms are {{man|2|flock|FreeBSD||inline}} and <code>{{man|3|lockf|FreeBSD||inline}}</code>, each of which may be implemented atop <code>fcntl</code> or may be implemented separately from <code>fcntl</code>. Although some types of locks can be configured to be mandatory, file locks under Unix are by default ''advisory''. This means that cooperating processes may use locks to coordinate access to a file among themselves, but uncooperative processes are also free to ignore locks and access the file in any way they choose. In other words, file locks lock out other file lockers only, not I/O. Two kinds of locks are offered: shared locks and exclusive locks. In the case of <code>fcntl</code>, different kinds of locks may be applied to different sections (byte ranges) of a file, or else to the whole file. Shared locks can be held by multiple processes at the same time, but an exclusive lock can only be held by one process, and cannot coexist with a shared lock. To acquire a shared lock, a process must wait until no processes hold any exclusive locks. To acquire an exclusive lock, a process must wait until no processes hold either kind of lock. Unlike locks created by <code>fcntl</code>, those created by <code>flock</code> are preserved across <code>fork</code>s, making them useful in forking servers. It is therefore possible for more than one process to hold an exclusive lock on the same file, provided these processes share a filial relationship and the exclusive lock was initially created in a single process before being duplicated across a <code>fork</code>. Shared locks are sometimes called "read locks" and exclusive locks are sometimes called "write locks". However, because locks on Unix are advisory, this isn't enforced. Thus it is possible for a database to have a concept of "shared writes" vs. "exclusive writes"; for example, changing a field in place may be permitted under shared access, whereas garbage-collecting and rewriting the database may require exclusive access. File locks apply to the actual file, rather than the file name. This is important since Unix allows multiple names to refer to the same file. Together with non-mandatory locking, this leads to great flexibility in accessing files from multiple processes. On the other hand, the cooperative locking approach can lead to problems when a process writes to a file without obeying file locks set by other processes. For this reason, some Unix-like operating systems also offer limited support for ''mandatory locking''.<ref>{{cite web | title = Mandatory File Locking for the Linux Operating System | series = Documentation / File Systems | website = kernel.org | url = http://kernel.org/doc/Documentation/filesystems/mandatory-locking.txt | access-date = 2011-10-08}}</ref> On such systems, a file whose <code>setgid</code> bit is on but whose group execution bit is off when that file is opened will be subject to automatic mandatory locking if the underlying filesystem supports it. However, non-local NFS partitions tend to disregard this bit.<ref>{{cite web | title = Use <code>Setuid</code>, <code>Setgid</code>, and Sticky Bits with Server for NFS | url = https://technet.microsoft.com/en-us/library/cc731734(WS.10).aspx | id = cc731734(WS.10) | access-date = 2011-10-08}}</ref> If a file is subject to mandatory locking, attempts to read from a region that is locked with an exclusive lock, or to write to a region that is locked with a shared or exclusive lock, will block until the lock is released. This strategy first originated in System V, and can be seen today in the [[Solaris (operating system)|Solaris]], [[HP-UX]], and Linux operating systems. It is not part of POSIX, however, and BSD-derived operating systems such as [[FreeBSD]], [[OpenBSD]], [[NetBSD]], and Apple's [[macOS]] do not support it.<ref>{{cite book |author1=Viega, John |edition=1st |author2=Messier, Matt |year=2003 |title=Secure Programming Cookbook for C and C++ |publisher=O'Reilly Media |location=Sabastopol, CA |isbn=978-0-596-00394-4 |chapter=2.8 Locking Files |page=792 |url=http://shop.oreilly.com/product/9780596003944.do |quote=Support for mandatory locks varies greatly from one Unix variant to another. Both Linux and Solaris support mandatory locks, but [[Darwin (operating system)|Darwin]], [[FreeBSD]], [[NetBSD]], and [[OpenBSD]] do not, even though they export the interface used by Linux and Solaris to support them. On such systems, this interface creates advisory locks. Support for mandatory locking does not extend to NFS.}}</ref> Linux also supports ''mandatory locking'' through the special ''<code>-o mand</code>'' parameter for file system mounting (<code>{{man|8|mount|Linux||inline}}</code>), but this is rarely used. Some Unix-like operating systems prevent attempts to open the executable file of a running program for writing; this is a third form of locking, separate from those provided by <code>fcntl</code> and <code>flock</code>. === {{Anchor|POSIX}}Problems === More than one process can hold an exclusive <code>flock</code> on a given file if the exclusive lock was duplicated across a later <code>fork</code>. This simplifies coding for network servers and helps prevent race conditions, but can be confusing to the unaware. Mandatory locks have no effect on the <code>unlink</code> system call. Consequently, certain programs may, effectively, circumvent mandatory locking. Stevens & Rago (2005) observed that the <code>ed</code> editor indeed did that.<ref>{{cite book |first1=W. Richard |last1=Stevens |first2=Stephen A. |last2=Rago |date=27 June 2005 |title=Advanced Programming in the UNIX Environment |publisher=Addison-Wesley Professional |edition=Second |isbn=978-0201433074 |page=456}}</ref> Whether and how <code>flock</code> locks work on network filesystems, such as [[Network File System (protocol)|NFS]], is implementation dependent. On [[BSD]] systems, <code>flock</code> calls on a file descriptor open to a file on an NFS-mounted partition are successful [[NOP (code)|no-ops]]. On [[Linux]] prior to 2.6.12, <code>flock</code> calls on NFS files would act only locally. Kernel 2.6.12 and above implement <code>flock</code> calls on NFS files using POSIX byte-range locks. These locks will be visible to other NFS clients that implement <code>fcntl</code>-style ''POSIX locks'', but invisible to those that do not.<ref>{{cite web |url=http://nfs.sourceforge.net/ |series=Linux NFS FAQ: D |title=Commonly occurring error messages |website=nfs.sourceforge.net |publisher=Source Forge}}</ref> Lock upgrades and downgrades ''release'' the old lock before applying the new lock. If an application downgrades an exclusive lock to a shared lock while another application is blocked waiting for an exclusive lock, the latter application may get the exclusive lock and lock the first application out. This means that lock downgrades can block, which may be counter-intuitive. ''All'' <code>fcntl</code> locks associated with a file for a given process are removed when ''any'' file descriptor for that file is closed by that process, even if a lock was never requested for that file descriptor. Also, <code>fcntl</code> locks are not inherited by a child process. The <code>fcntl</code> close semantics are particularly troublesome for applications that call subroutine libraries that may access files. Neither of these "bugs" occurs using real <code>flock</code>-style locks. Preservation of the lock status on open file descriptors passed to another process using a [[Unix domain socket]] is implementation dependent. === Buffered I/O problems === One source of lock failure occurs when buffered I/O has buffers assigned in the user's local workspace, rather than in an operating system buffer pool. <code>fread</code> and <code>fwrite</code> are commonly used to do buffered I/O, and once a section of a file is read, another attempt to read that same section will, most likely, obtain the data from the local buffer. The problem is another user attached to the same file has their own local buffers, and the same thing is happening for them. An <code>fwrite</code> of data obtained from the buffer by <code>fread</code> will '''''not''''' be obtaining the data from the file itself, and some other user could have changed it. Both could use <code>flock</code> to ensure exclusive access, which prevents simultaneous writes, but since the reads are reading from the buffer and not the file itself, any data changed by user #1 can be lost by user #2 (over-written). The best solution to this problem is to use unbuffered I/O (<code>read</code> and <code>write</code>) with <code>flock</code>, which also means using <code>lseek</code> instead of <code>fseek</code> and <code>ftell</code>. Of course, you'll have to make adjustments for function parameters and results returned. Generally speaking, buffered I/O is ''unsafe'' when used with shared files.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)