> All of these lock functions succeed when the same process asks for a
> lock that it already has. That is:
>
> fcntl(fd, ...);
> fcntl(fd, ...); /* success -- no error returned */
>
> For flock() only, the lock is inherited by a child process along
> with the file descriptor so the child can re-issue the flock()
> call and that will pass, too:
>
> flock(fd, ...);
> pid = fork();
> if (pid == 0)
> flock(fd, ...); /* success -- no error returned */
True...
> For fcntl() and lockf() the locks are not inherited, and the
> call in a child fails:
>
> fcntl(fd, ...);
> pid = fork();
> if (pid == 0)
> fcntl(fd, ...); /* will fail and return -1 */
>
> In no case does just closing the file descriptor in the child lose
> the parent's lock. I rationalise this as follows:
>
> 1. flock() is using a "last close" semantic, so closing the file
> descriptor is documented not to lose the lock
Yep.
> 2. lockf() and fcntl() use a "first close", but because the locks
> are not inherited by the child process the child can't unlock
> them
And at least old linux system call manuals seems to reflect this
(incorrectly) when they state that file locks are not inherited (should
be "record locks obtained by fcntl").
> One additional warning: this stuff *is* potentially filesystem
> dependent, per the source code I looked at, which would call
> filesystem specific routines.
>
> I only used whole file locking (no byte ranges) and didn't prove that
> a lock taken by flock() is still held after a child calls close() as
> it is documented to be.
I tested this on Linux 2.4.x ext2 fs and it seems to follow the spec
exactly. If child is forked and it closes the file, parent still has the
lock until it's killed or it has also closed the file.
What about having two different lock files: one that would indicate that
there are some child processes still running and another which would
indicate that there's postmaster's parent process running? - Using flock
and fcntl semantics respectively (or flock semantics with children
immediately closing their fds).
And of course locking is file system dependant, just think NFS on linux
where virtually no locking semantics actually work :)
--
Antti Haapala