Why dup()?

David Newall openssh at davidnewall.com
Fri Oct 20 16:58:52 AEDT 2017


I've been using ssh without it duping stdout and stderr, and had no 
problems.  I think this change should be made to the master source.

WHAT IS THE PROBLEM WITH SSH RIGHT NOW?
It duplicates FILENO_STDOUT and FILENO_STDERR, thus there are two 
descriptors for each of these files.  When the remote program closes its 
stdout or stderr, the remote sshd sends the appropriate message to the 
local ssh, which responds by closing the corresponding (duplicate) 
descriptor, but it ignores the original descriptor, thus that file 
remains open.  The result of this is that a program reading from ssh's 
stdout (or stderr) has no way of knowing that the remote program has 
closed the file.

WHY IS THAT BAD?
For interactive purposes, I suppose it isn't a problem.  It's true that 
the remote program can send no further ouput (or error output), but 
everything proceeds in an otherwise reasonable way.  Where it is a 
problem is if you want to use ssh in a script.  It's significant when a 
remote program closes stdout.  It means something.  It means that no 
more output will be produced, the next program in the pipeline will 
receive no more input, and should take action for end-of-file.  At 
present, the next program in the pipeline cannot take action for 
end-of-file until ssh exits.  The ssh program will not exit until the 
remote program exits, but, in a scripted situation, it may well be 
waiting for end-of-file on its input, and thus we have a deadlock: the 
remote program has closed output and is waiting for input to close; the 
local program that is next in the pipeline is waiting for its input to 
close, which will never occur, and thus has no way to signal that it has 
finished its job.  The program providing input has no way of knowing 
that the remote program has closed output and thus has no way of knowing 
that it should close its input.

WHAT IMPACT IS THERE FROM NOT DUPLICATING THESE DESCRIPTORS?
As far as I can tell, only that ssh's accurately mirrors the remote 
program's output.  That already happens for all data written to output.  
Closing ssh's output (all descriptors) merely completes the picture.  
Ssh does not, of itself, use stdout; it has no reason to keep stdout 
open.  As far as I can tell, the change I am proposing has no 
deleterious effect.

WHAT IS THE EXACT CHANGE?

This patch allows a program reading ssh's output to see an EOF from
the remote session.  Good for scripting.

Author: David NewallPatch-Name: scriptable-ssh.patch --- diff -u a/ssh.c b/ssh.c --- a/ssh.c 
+++ b/ssh.c @@ -1837,11 +1837,11 @@ } else { in = dup(STDIN_FILENO); } - 
out = dup(STDOUT_FILENO); - err = dup(STDERR_FILENO); + out = 
STDOUT_FILENO; + err = STDERR_FILENO; - if (in < 0 || out < 0 || err < 
0) - fatal("dup() in/out/err failed"); + if (in < 0) + fatal("dup() in 
failed"); /* enable nonblocking unless tty */ if (!isatty(in))

WHAT CAN I DO TO HELP STEWARD THIS CHANGE INTO THE MASTER SOURCE?
What do I need to do?

David


More information about the openssh-unix-dev mailing list