New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
redirecting >&4 sends data to iothread_service_completion() #3303
Comments
See Having said all that what did you expect to happen? Normally if you redirect to an invalid file descriptor you'll get an error:
The redirection code should probably be modified to explicitly test for the use of file descriptors used internally and emit the same error since doing such a redirection is nonsensical. We should also remove the |
An error. It seemed worrying that I could get that function to eat my 99/100s and seemingly mess with fish internally - although I can't get anything terrible to happen. Redirecting fd 3 will similarly send characters to the tty while disrupting completion behavior.
Also, 4 different errors for each of: Maybe if these were simply given higher fd numbers nobody would be as likely to encounter them accidentally. |
For anyone inclined to fix this I suggest adding a new class that tracks file descriptors used privately by fish. It should have methods such as "make_fd_private", "make_fd_public", and "is_private". Those method names are merely suggestions so you are welcome to use other names. The behavior of each method should be obvious from the suggested name. The class would be instantiated using the singleton pattern; i.e., a single global instance of the class. Functions like Also, any existing code, such as the
Such scripts almost always use low numbered file descriptors. That pattern isn't currently legal in fish but should be. As part of fixing this issue we should make it easier to support that idiom. So there should also be a function added that takes a file descriptor returned by something like the |
We do this in
Rather than a lot of machinery to track file descriptors (which would duplicate a lot of the CLOEXEC logic) I would rather we always just fork for processes that have redirections of file descriptors larger than 2. We already do some of this for output (look for
we'll run the builtin, get the buffered output, fork a new process, and write it to fd 4. This might error, since fd 4 won't be open in the child - but it might succeed if we have a stdin redirection in a pipe, i.e.:
might plausibly work. |
Doesn't the fact that command requires a lengthy comment in the source of the eval function to discuss the internal, private, details of fish's implementation worry you? To me it says we do not want to codify that pattern. Quite the contrary. That behavior is far too subtle for a "friendly" shell.
That seems rather expensive. Which isn't a big deal today since we only support fd redirection in that manner in a |
I've got a thousand yard stare after reading through If forking gets us closer to the kind of usage @krader1961 mentioned above which fish is worse off for lacking lacking IMO ( |
Completely agree - this is clearly a sh holdover. AFAICT the only legitimate use for redirections above 2 is to "save and restore" an existing file descriptor, or sometimes swap them, and this is always extremely confusing and obscure. Everyone would be better off if there were an alternative readable way to accomplish this, and then I think we could disallow redirections above 2 altogether (which would be a nice simplification in fish). However until we have that, we have to keep our existing uses ( |
Surely there are reasons to want more channels of output. I do this in C: void main(int argc, char* argv[]) {
dprintf(1, "Regular output");
dprintf(15, "This is debug output that won't print anything unless you 15>&1 me\n");
dprintf(16, "This is more deeper debuggy\n");
} With obvious goals and pleasant results. Maybe it's a bad pattern? |
Fascinating, that's the first I've ever heard of someone doing that. |
Really though - it actually feels easier in C there than a shell. One thing is the lack of syntax - but what's the technical reason why a fd can't be immediately valid for use? It's probably obvious, but I'd rather my shell let me: function output
echo foo >&3
echo bar
end
instead of:
I'm sure there's some good reason - doesn't work in any shell I've tried. But it's easy if it's another process. int main(int argc, char* argv[])
{
dprintf(10, "foo");
dprintf(1, "bar");
}
|
Err, spoke too soon. causes an error in bash & zsh when not an external script, but works in ksh93u+ 2012-08-01:
|
Redirecting fds greater than two is actually quite useful. In other shells you can do things like
Now obviously that's a silly example that doesn't really need fd 3. A more realistic example would involve using a named pipe, where you don't want it being opened and closed multiple times because that would confuse the process reading from the pipe. Or a more complicated situation, possibly involving a loop, where you want to write a lot to a destination without paying the overhead of opening and closing it with each I/O. Of course, at the moment fish doesn't support using |
This pattern is used quite frequently — try searching for Sorry to necro the thread — I was hoping to do some fd magic in fish and wound up here via #3948. |
Okay, this no longer happens. |
Those file descriptors are still open, though, so sending data to them could corrupt internal state:
|
It looks like this does still happen - you can write to arbitrary fds within fish. We should prevent this. |
Should be fixed by 11a373f? @ridiculousfish |
Looks like. |
Yeah should be fixed! |
This commit is reverted in the upcoming 3.2.1, so I am reopening the issue. |
Should this happen?
if not interactive, does what other fds do:
The text was updated successfully, but these errors were encountered: