Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It strikes me that you'd use up STDIN, STDOUT, and STDERR pretty fast that way.

One could make an unprincipled exception for them, of course. And SQLITE would still need the special-casing to prevent using low-numbered fds. But this would prevent other problems and is worth considering.



Didn't see your reply before commenting, but it gave me a thought: We really only need a "local" solution. If there were a way of requesting fd's that weren't required to be the lowest available ones (perhaps even 64-bit ones with a process unique uppper part), that'd probably be good enough here. Of course we're still sharing address space with buggy code, so maybe it's not worth it.


I’ll reply here since then both you and parent can see it and comment further.

In the case that you linked to in the sibling comment that you wrote in reply to me, the dup2 syscall is used.

So the question then that I have is, in the case of

  foo 2&>1
Does bash then:

a) First close fd 2, and then call dup(1), or does it

b) Call dup2(1, 2), or

c) Do something else entirely, or something more complex or convoluted?

In case the answer is b) then it seems to me, though I may be overlooking something, that we could allow calls like b) and inside of the dup2 syscall keep the id of the fd that we are using as newfd, since it is unambiguously requested that this is intended, while at the same never reusing fd id in the dup syscall.

In this comment I am referring to the dup and dup2 syscalls as defined in the Linux man pages:

dup() uses the lowest-numbered unused descriptor for the new descriptor.

dup2() makes newfd be the copy of oldfd, closing newfd first if necessary, but note the following: [...]

https://linux.die.net/man/2/dup2

With the modification that “lowest-numbered unused descriptor” would be unique as previously stated in the comment that the two of you are replying to.

More generally, the question is, does any wide-spread piece of code manually close an fd and then call the dup syscall, and expect the fd id to be exactly the same as the one they themselves closed, instead of using dup2?

And furthermore, likewise, does any widespread piece of code use the dup2 syscall to specify the newfd where actually it should not have cared about the id of the newfd and should have used dup instead and let the system decide?


I don't think it matters what bash actually does, the issue (as I see it) is that when a program calls write(N, ...) it sometimes wants to refer to the "stale" file descriptor N. Consider this contrived example:

    write(STDERR_FILENO,"test",4); // OK, write to normal stderr
    close(STDERR_FILENO);
    open(....); // Open some log file
    // later
    write(STDERR_FILENO,"x",1); // OK, write to log file
Even though fd 2 refers to different files I think the above is required to work for POSIX compliance.


That case is covered too as long as the program makes use of the dup2 syscall to make the switch instead of close followed by open. But it is probable that some pieces of code that are currently in widespread use do it by close and expecting a call to open to give them fd id for stderr like you say indeed I guess.

So the conclusion is that the answer to my original question is probably like you say, we can’t just do that.

But it would be interesting to find out how many wide-spread pieces of open source code do it that way, and for all code that does one could submit patches to change them to using the explicit dup2.


64 bit file descriptors doesn't work unless you create a whole swag of new system calls, because file descriptors are type `int` and most 64-bit POSIX implementations are I32LP64.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: