From Derek Robert Price > The problem is that in a standard configuration: > > --stderr-> -------------stderr------------> > / \ / / \ > CVS Server ssh CVS client tty > \ / \ / \ / > --stdout-> --stdout-> --stdout-> > > Note that since CVS didn't access the stderr of its child process, ssh, > the child process gets a clone of the parent process' stderr descriptor > and ssh and the CVS client end up sharing the tty's standard error. > > Now, when the user redirects stderr to stdout, say, to redirect the > output to a file (e.g. CVS_RSH=ssh cvs diff >tmp.diff 2>&1), you get the > following configuration:
This may sound silly, but as a temporary workaround, can't you: CVS_RSH=ssh cvs diff >tmp.diff 2>tmp.diff that ought to open the file twice as separate file descriptors. The downside is that I/O is now unsynchronized, and lines may be inserted in the middle of other lines, but nothing should get lost at least. switching to line buffering should eliminate most of that problem. this assumes, of course, that is what you're trying to do. There are other possibilities that you can't control, I know, and doesn't solve the real problem. > --stderr-> -------------stderr------------- > / \ / / \ > CVS Server ssh CVS client >tty/file/whatever > \ / \ / \ / > --stdout-> --stdout-> --stdout-- > > Since CVS was using the same file descriptor for stderr and stdout, ssh > is writing to CVS's stdout descriptor as its stderr. When ssh sets its > stderr to non-block, the same happens to CVS's stdout. Since CVS isn't > prepared for this, data gets lost (written to a non-blocking descriptor > without watching for EAGAIN). > > So, anyway, cat wouldn't need to do line buffering. What has been > proposed is that a script stick cat in between ssh's stderr and cvs's > stderr. I assume by redirecting ssh's stderr to cat's stdin and then > cat's stdout back to CVS's stderr, but I'm going to leave stdin out of > the following picture for convenience: > > --stderr-> --stderr----->cat-------stderr-- > / \ / / \ > CVS Server ssh CVS client >tty/file/whatever > \ / \ / \ / > --stdout-> --stdout-> --stdout-- > > Now, when ssh sets its stderr to O_NONBLOCK, only cat's stdin will be > affected. cat's buffering ability will be irrelevant since ssh is the > only PROCESS that needs to be aware of the non-blocking i/o and resend > data and it is already doing that. yup. perhaps re-opening/re-assigning stderr before forking off ssh? hm, no, you still have the fd cloning problem you could fork off a client and do the 'cat' thing yourself, but exec'ing cat would have the same result. you could setup a pipe and use the parent process to do the read/write separation, but that's no different. Hm, it's too bad that the shared internal file info also shares the block/nonblock setting, but I suppose that's unavoidable. You cannot both have and not have a buffer block on a given filedescriptor. thanks for taking the time to detail the issues; I can't seem to find the first part of the thread; did it come from another mailing list? or am I just being blind? - Kevin _______________________________________________ Bug-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-cvs