labath wrote:
> who has the handle would be able to use them
They are, but unless they know about them, the FD is just going to sit there,
forever.
I love to educate people about FDs, so here's a crash course. Suppose you want
to communicate with a child process. Here's one way to do this:
```
pipe(fds);
fcntl(fds[0], F_SETFD, O_CLOEXEC);
if (fork() == 0)
execl("program", to_string(fds[1]).c_str());
else
close(fds[1]);
```
This works in that the other process gets one (and only one) end of the pipe
and is made aware of its number (via the cmdline arg). The problem is you run
the same code on two threads simultaneously. If the threads run in lockstep,
they will first create two pipes and then fork two subprocesses. Each of those
processes will get both pipes even though it's expecting only one.
A solution to that is to ensure the flag is cleared only inside the child
process:
```
pipe2(fds, O_CLOEXEC);
if (fork() == 0) {
fcntl(fds[1], F_SETFD, 0);
execl("program", to_string(fds[1]).c_str());
} else
close(fds[1]);
```
This way, even if both child processes end up with the extraneous pipe, the
pipe will be automatically closed due to O_CLOEXEC. Only the one which we
expect will have its flag cleared. This patch lets us to that (while accounting
for all of the layers that this information needs to step through).
(Note that this still means that the FD will exist in the child process until
the execve call. This is usually not a problem, since that's only a brief
moment, but in some situations it can be, and it's why we have the ETXTBUSY
workaround in the launching code (because android's ADB had this issue).
Unfortunately, fixing this is a lot trickier. The only way I'm aware of
involves using a "fork server" -- forking a new process at the beginning of
main (while you're still hopefully single threaded and don't have any extra
FDs) and then using this process to fork any new children (communicating with
it over a domain socket, and using the socket to pass any FDs that you want to
pass).
https://github.com/llvm/llvm-project/pull/126935
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits