0

For example, say I have the following shell command.

~]$ foobar 2>> foobar.log

The above command redirects the standard error output (stderr, or file descriptor 2) to the file foobar.log, appending the output (the >> rather than just >).

Now, assume that two users are both running the exact same command. In this case, the output to the file is interleaved, making it rather difficult to read.

Programs can utilise "advisory file locking" (via the fcntl() C function) as a operating-system level mutual-exclusion on files, essentially coordinating the multiple process so that only one process writes to the file at any given time. Hence the output of the two processes is no longer interleaved and becomes easier to read.

However, how do shells implement the invocation above? If they use the pipe() system call, advisory file locking will not work. If, on the other hand, they use dup() (or some other variant) before calling fork()/exec(), then advisory file locking should work.

Which is the case, and should advisory file locking work on shell-redirected standard output (stdout, file descriptor 1) and standard error (stderr, file descriptor 2)?

magnus
  • 4,031
  • 7
  • 26
  • 48
  • You can inspect `errno` to find out more detail on what the error is. From my own testing, `fcntl(2, F_SETLKW, &lock)` worked fine on linux (when stderr was a terminal) - but it would also depend on the operating system, what file descriptor 2 is connnected to, and what arguments you provoded in the `lock` – nos Apr 05 '18 at 12:44
  • 1
    Please post a [MCVE]. – P.P Apr 05 '18 at 12:49
  • 1
    Depends on your shell, but typically there's no locking, just an `open()` with `O_APPEND` in the flags. – Toby Speight Apr 05 '18 at 15:12

2 Answers2

0

fcntl() file locks are bound to a process, not a thread. So locking a file descriptor which is attached to something only available to that process seems useless. Not only is there no actual file to lock (e.g. the mechanism would have to differ somehow), the process which locks its own stderr is competing with no one else for that lock.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
0

As per the comment by @nos, this may be dependent on the operating system and the type of file that file descriptor 2 is connected to. E.g., the above call will not work if standard error is piped to another program, like so:

~]$ mkfifo pipe
~]$ cat pipe
~]$ foobar 2>> pipe

However, if standard error is redirected to a regular file (as in the above example), then advisory file working does appear to work, at least on Arch Linux.

magnus
  • 4,031
  • 7
  • 26
  • 48