On Sun, Mar 1, 2020 at 3:06 AM Ian Lance Taylor <i...@golang.org> wrote:
>
> > But if you opened newfd yourself, or if it is 0/1/2 and you never
> > closed os.Std*, then you *can* dup2 safely, regardless of other
> > packages.
>
> Those are examples where you are in charge of the FD namespace
> (assuming you know that no other code is doing to touch descriptors
> 0/1/2).

I think we've understood each other on this point. We were just
interpreting the expression "being in charge of the FD namespace"
differently.
I actually meant "being in control of the timing of every single FD
creation in the program" and I wrote it in answer to Rader (who was
talking about "unused" FDs) to point out that you cannot be sure that
one is unused unless you have that kind of control.

> So you are calling dup2(N, 2)?

Yes.

> And dup2 is not documented to return EINTR

Yes, it is. In the same man page you quoted [1].
|  EINTR  The dup2() or dup3() call was interrupted by a signal; see
|         signal(7).

> and the Linux kernel code shown above does not have any path that
> returns EINTR.

That's a relief, but I would be more comfortable if the man page was accurate.

> dup2 is documented to atomically close newfd and duplicate oldfd
> onto it.  That means that either newfd is untouched, or oldfd is
> duplicated onto it.

If that is true, there is indeed no problem in retrying on EINTR, but
(as I explained two times already) someone disagrees with your
premise, notably the python standard library implementation [2].

>From PEP 475 [3]:
| os.close, close() methods and os.dup2() are a special case: they will
| ignore EINTR instead of retrying. The reason is complex but involves
| behaviour under Linux and the fact that the file descriptor may really
| be closed even if EINTR is returned.

"the file descriptor may really be closed even if EINTR is returned",
hence the alleged race if dup2 is retried.

libuv is of the same opinion [4].

That's why I was asking for more evidence about the exact meaning of
"performed atomically". It could just mean that no one can "steal"
newfd between close and duplication, even though your stronger
interpretation makes sense and seems to reflect the actual kernel
code.

Maybe the python folks are wrongly assuming that errors from the
implicit close are reported by dup2 (the man clearly says that they
are not).

[1] http://man7.org/linux/man-pages/man2/dup2.2.html
[2] 
https://github.com/python/cpython/blob/6e02691f300c9918ac5806dafa1f2ecef451d733/Modules/posixmodule.c#L8730
[3] https://www.python.org/dev/peps/pep-0475/
[4] https://github.com/libuv/libuv/issues/462

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEvMKD8a7hOLg2BM6_7LsB%2BaPZOjvDa_QU44FtJNWn23-bwQrA%40mail.gmail.com.

Reply via email to