3

I've found boilerplate flock(1) code which looks promising. Now I want to understand the components before blindly using it.

Seems like these functions are using the third form of flock

flock [-sxun] [-w timeout] fd

The third form is convenient inside shell scripts, and is usually used the following manner:

(
 flock -s 200 
 # ... commands executed under lock ... 
) 200>/var/lock/mylockfile

The piece I'm lost on (from the sample wrapper functions) is this notation

eval "exec $LOCKFD>\"$LOCKFILE\""

or in shorthand from the flock manpage

200>/var/lock/mylockfile

What does that accomplish?

I notice subsequent commands to flock passed a value other than the one in the initial redirect cause flock to complain

flock: 50: Bad file descriptor

It seems like flock is using the file descriptors as a map to know which file to operate on. In order for that to work though, those descriptors would have to still be around and associated with the file, right?

After the redirect is finished, and the lock file is created, isn't the file closed, and file descriptors associated with the open file vaporized? I thought file descriptors were only associated with open files.

What's going on here?

Community
  • 1
  • 1
quickshiftin
  • 66,362
  • 10
  • 68
  • 89

1 Answers1

4
200>/var/lock/mylockfile

This creates a file /var/lock/mylockfile which can be written to via file descriptor 200 inside the sub-shell. The number 200 is an arbitrary one. Picking a high number reduces the chance of any of the commands inside the sub-shell "noticing" the extra file descriptor.

(Typically, file descriptors 0, 1, and 2 are used by stdin, stdout, and stderr, respectively. This number could have been as low as 3.)

flock -s 200

Then flock is used to lock the file via the previously created file descriptor. It needs write access to the file, which the > in 200> provided. Note that this happens after the redirection above.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • So there's really no harm in calling `200>/var/lock/mylockfile` from another process, since the call to `flock -xn 200` will still bomb if that process wasn't also the one that acquired the lock initially? – quickshiftin Feb 10 '14 at 23:30
  • 1
    As long as you keep in mind that each process has its own file descriptors. Child processes inherit them, but unrelated processes do not share descriptors. 200 can refer to different files in different processes. I don't know if that answers your question? – John Kugelman Feb 10 '14 at 23:39
  • I'm a bit confused, so what happens if `200` is being used by the shell elsewhere. Also don't get why it doesn't it use 3-9, which are definitely not going to be used by bash unless you explicitly defined one elsewhere?. Or why not check /proc/self/fd before arbitrarily assigning one? – Reinstate Monica Please Feb 10 '14 at 23:45
  • The only thing I'm still missing is, even though `flock -xn 200` is called *after* `200>/var/lock/mylockfile`, hasn't `/var/lock/mylockfile` been closed by then and thus file descriptor *200* no longer associated with the file in that process? So how would `flock` know *50* for example wasn't used to create the file to begin with. It seems to, with an error like `flock: 50: Bad file descriptor`. – quickshiftin Feb 10 '14 at 23:46
  • 1
    The `200>` applies for everything inside the parentheses. `/var/lock/mylockfile` isn't closed until the entire sub-shell has finished. File descriptor 200 will still be open when `flock` runs, and since child processes inherit their parents' file descriptors, it too can write to fd 200. – John Kugelman Feb 11 '14 at 00:28
  • "I'm a bit confused, so what happens if 200 is being used by the shell elsewhere." Under normal circumstances, a shell script will only have 0, 1, and 2 open. It is safe to write scripts assuming those are the only open descriptors. That's why I say it'd be (fairly) safe to use 3 instead of 200 here. – John Kugelman Feb 11 '14 at 00:30
  • Thanks John, very helpful. I still have a ways to go w/ my BASH scripting skills, but I'm getting there. – quickshiftin Feb 11 '14 at 00:31
  • @JohnKugelman Right, it's unlikely the script will have them open, but can't the shell be using them for something else (e.g. my shell is currently using 255 as well), and the bash man page has "Redirections using file descriptors greater than 9 should be used with care, as they may conflict with file descriptors the shell uses internally." Though I might be misinterpreting how this works. – Reinstate Monica Please Feb 11 '14 at 18:06