[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lost process output in pipe between Emacs and CVS

From: Ian Lance Taylor
Subject: Re: Lost process output in pipe between Emacs and CVS
Date: 08 Jul 2002 11:15:40 -0700
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

"Stefan Monnier" <monnier+gnu/emacs/pretest@rum.cs.yale.edu> writes:

> Another notable thing is that this whole problem disappears if I
> change PCL-CVS to use a pty rather than a pipe for the process' output.
> (I noticed it because the problem doesn't appear with VC which is
> not careful to use a pipe).
> Now my direct `read' calls from GDB make me believe that maybe the
> problem is not in Emacs, but in CVS instead (I use cvs-1.11.1p1
> from the Redhat distribution, with a mix of Redhat-7.2
> and Redhat-7.3 GNU/Linux system).
> But the fact that `cvs diff src/minibuf.c |(sleep 120; wc)' works
> correctly make me think that maybe it is a bug in Emacs.
> Could anybody help me out with insight/hints/patches/chocolates ?

I see the problem.  It only happens when you do the equivalent of
    cvs COMMAND 2>&1
and you are using ssh.

When CVS execs ssh, it sets up pipes for file descriptors 0 and 1, but
not for file descriptor 2.  Thus ssh inherits file descriptor 2 from
CVS.  If you have done 2>&1, this is the same as file descriptor 1.

ssh puts file descriptors 0, 1, 2 into non-blocking mode.  Since ssh
and CVS are using the same file descriptor for descriptor 2, this has
the effect of putting CVS's file descriptor 2 into non-blocking mode.
Since we're talking about the case of 2>&1, this has the effect of
putting CVS's file descriptor 1 into non-blocking mode.

If you have enough data, the CVS client fills up the output buffer on
stdout (file descriptor 1).  The CVS client does not expect this file
descriptor to be in non-blocking mode.  The call to fwrite or fflush
fails with EAGAIN, but CVS does not check for an error.  Instead, the
data is silently lost.

I don't know what the general fix is.  It makes sense for CVS to leave
file descriptor 2 untouched when executing the CVS_RSH program, so
that any errors from that program will appear on stderr.

Now that I understand what is happening, I can easily fix the
particular problem I'm seeing by setting CVS_RSH to a shell script
which does this:
    ssh $* 2>/dev/null
This disconnects the file descriptor 2 which ssh sees from the one
which CVS is using, and everything works fine.

Of course, the CVS client should be changed to check for errors when
doing output to stdout and stderr.  This would be simple changes to
handle_m and handle_e in src/client.c.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]