Trying to understand flock()
Henrik W Lund
henrik.w.lund at broadpark.no
Thu Nov 4 13:03:42 PST 2004
Ronald F. Guilmette wrote:
> Greetings friends,
>
> I wonder if someone would be kind enough to enlighten me about the
> semantics of the flock(2) function. I have RTFM'd, and I am sad to
> say that I am still rather mystified that flock() doesn't seem to
> do what it is documented as doing. (I am testing it on 4.10-RELEASE,
> by the way.)
>
> The short test program attached below illustrates the source of my
> abundant confusion. When I compile this program with -DUSE_FCNTL
> (thus forcing it to use fcntl(2) to implement exclusive file locking)
> and then execute it, the resulting behavior is exactly what I expect,
> i.e. the program prints the string "Temp file locked (1)", and then it
> pauses for 10 seconds, and then it prints "Temp file locked (2)". The
> delay time between the appearance of the two message indicates clearly
> that exclusive file locking is working as expected.
>
> When I compile this program WITHOUT the -DUSE_FCNTL option however
> (thus forcing the program to use flock() rather then fcntl() for file
> locking), there is no apparent delay between the printing of the first
> message and the printing of the second message.
>
> That is what has me mystified.
>
> Obviously, there is something (or maybe several things) about the actual
> semantics of flock(2) that I don't understand. I would appreciate it if
> someone would enlighten me about that.
>
>
> Regards,
> rfg
>
>
> P.S. My apologies in advance if you try to Cc: me directly on your reply
> to this posting, and if your response gets rejected by the local spam
> filters. It's nothing personal. Really. We just have about 2/5ths of
> the entire Internet blacklisted here due to past spamming incidents. I
> will look for replies also in the freebsd-general list archives, so if
> you prefer, you can just repl to the list. Thanks and hasta la vista.
>
>
> ========================================================================
> #include <stdio.h>
> #include <string.h>
> #include <errno.h>
> #include <unistd.h>
> #include <sys/file.h>
> #include <fcntl.h>
>
> static void
> die (register char const *const fmt)
> {
> fprintf (stderr, fmt, strerror (errno));
> fprintf (stderr, "\n");
> exit (1);
> }
>
> static int
> lock_exclusive (register int const fd)
> {
> #if USE_FCNTL
> auto struct flock fl;
>
> fl.l_start = 0;
> fl.l_len = 0;
> fl.l_pid = 0;
> fl.l_type = F_WRLCK;
> fl.l_whence = SEEK_SET;
> return fcntl (fd, F_SETLKW, &fl);
> #else
> return flock (fd, LOCK_EX);
> #endif
> }
>
> int
> main (void)
> {
> static char template[] = "/tmp/temp.XXXXXXXXXX";
> register int fd;
>
> fd = mkstemp (template);
> unlink (template);
>
> if (lock_exclusive (fd) == -1)
> die ("Error creating exclusive lock: %s");
> fprintf (stderr, "Temp file locked (1)\n");
>
> if (fork () == 0)
> {
> if (lock_exclusive (fd) == -1)
> die ("Error creating exclusive lock: %s");
> fprintf (stderr, "Temp file locked (2)\n");
> }
>
> sleep (10);
>
> close (fd);
> return 0;
> }
Greetings!
From the flock manpage:
"...file descriptors duplicated through dup(2) or fork(2) do not result
in multiple instances of a lock, but rather multiple references to the
same lock."
You're basically trying to place a lock you already hold, making the
flock function return immediately (this is what I gather, anyhow). The
fcntl function seems to operate slightly differently in this respect.
This is the only explanation I can think of, others might think
differently, though.
--
Henrik W Lund
More information about the freebsd-questions
mailing list