httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Slemko <>
Subject Re: general/1056: USE_FLOCK_SERIALIZED_ACCEPT is no use. (fwd)
Date Mon, 08 Sep 1997 03:58:25 GMT
Grr.  He is right.  Now I recall why I hate flock().  It references
vnodes, not descriptors.

The man pages says:

     Locks are on files, not file descriptors.  That is, file descriptors du-
     plicated through dup(2) or fork(2) do not result in multiple instances of
     a lock, but rather multiple references to a single lock.  If a process
     holding a lock on a file forks and the child explicitly unlocks the file,
     the parent will lose its lock.

...which really makes _no_ sense once you start trying to figure out
what they mean by a "file".  Replace "file" with "vnode" and it becomes
much clearer.  

So we have to do something along the lines of what is suggested in
PR#1056.  I am not convinced that the exact patch given will work,
right because we create the lockfile as the user that starts Apache
in mode 644, then try to open it for writing as the user Apache
runs as.

I am confused about what I am seeing with the current code, though,
since it seems to work.

---------- Forwarded message ----------
Date: Mon, 8 Sep 1997 12:03:45 +0900
From: Tetsuya Furukawa <>
Subject: Re: general/1056: USE_FLOCK_SERIALIZED_ACCEPT is no use.

Marc Slemko wrote:
>I am unable to duplicate this problem on FreeBSD.  Are
>you mounting things via NFS?

No, I didn't use NFS.
I don't know why you couldn't duplicate it.

The problem is neither caused by NFS, nor FreeBSD.
The Apache's programmers seem to suppose that flock() is compatible
with fcntl().
However, the supposition is wrong.

The following program will tell you the proper usage of flock().
#include <sys/file.h>
#include <sys/errno.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

main(int argc, char **argv)
    int fd;
    int bad = argc >= 2 && strcmp(argv[1], "bad") == 0;

    if (bad)
	fd = open("lockfile", O_WRONLY | O_CREAT, 0666);
    if (fork() == 0) {
	/* child */
	if (!bad)
	    fd = open("lockfile", O_WRONLY | O_CREAT, 0666);
	flock(fd, LOCK_EX);

    /* parent */
    if (!bad)
	fd = open("lockfile", O_WRONLY);
    if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
	if (errno == EWOULDBLOCK)
	    printf("flock works fine.\n");
	    printf("flock fails: %s\n", strerror(errno));
    } else
	printf("flock doesn't work.\n");
    return 0;

The platforms, the command lines and the corresponding outputs are below.

FreeBSD | ./a.out     | locking works file.
FreeBSD | ./a.out bad | locking doesn't work.
Solaris | ./a.out     | locking works file.
Solaris | ./a.out bad | locking works file.

Note: Solaris's flock() seems to be using fcntl() internally,
      so it often has the funny behavior.

Tetsuya FURUKAWA, Tokyo, Japan.

View raw message