ssh client is setting O_NONBLOCK on a pipe shared with other processes

Doug Graham edougra at
Tue Sep 17 00:06:45 AEST 2019

> Case in point; EAGAIN can come if you give your fd to another process
> and continue using it yourself.

> Short counts; It is documented behavior that read() and write() may
> return short counts. It is not documented why, so you can not make
> any assumptions.

You might be right about short counts but if you're right about
EAGAIN, there are
bugs everywhere.  My first attempt at working around my "make: write error"
failure was to pipe make into cat or tee, eg: "make | tee make.log".  But that
caused both cat and tee to fail with EAGAIN.  So they have the same "bug" as
make.  Also note that make is just calling printf normally and then
just before exiting,
it calls ferror(stdout) to see if any error occurred when it
previously wrote to stdout.
ferror()  is returning true.  So now the bug has moved into the C library.

Also note that EAGAIN is not a transient error like EINTR that will
probably go away
on a retry.  Retrying the write in a tight loop would probably just
burn some extra cpu and
then fail anyway.  You'd have to call select() first, or put a delay
in the loop. Are you
suggesting that every program that writes to stdout should implement
such contortions?

Not to mention that if the error occurred in stdout or some other C
library routine, I don't
think the calling program has any way of telling how much output was
sent successfully
and how much should be retried.  I could write

  if (printf("hello world") < 0 && errno == EAGAIN)
      <what here?>

but can I safely assume that none of my string was written before the
error occurred?

More information about the openssh-unix-dev mailing list