Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 04 Nov 2004 22:03:40 +0100
From:      Henrik W Lund <henrik.w.lund@broadpark.no>
To:        "Ronald F. Guilmette" <rfg@monkeys.com>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: Trying to understand flock()
Message-ID:  <418A992C.6040806@broadpark.no>
In-Reply-To: <37501.1099507538@monkeys.com>
References:  <37501.1099507538@monkeys.com>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?418A992C.6040806>