On Mon, Sep 14, 2015 at 10:17 AM, Jeff King <peff@xxxxxxxx> wrote: > On Mon, Sep 14, 2015 at 09:46:58AM -0700, Stefan Beller wrote: > >> I tried implementing a buffering solution for both stdout and stderr, >> but that doesn't really workout well if you consider interleaved output >> on the pipes as we cannot accurately replay that later on. To do that >> we would need to store the timing information of the channels, at least >> the relative order of it like: >> >> (stdout, First comes text to stdout), >> (stderr, interrupted by text in stderr) >> (stdout, but stdout doesn't bother, blasting more text) >> (stderr, continues to interrupt) >> >> obtaining the information is inherently racy, as all we can do is >> polling/reading from both stdout/err as fast as possible but without >> proper synchronization mechanisms we cannot be sure. > > I don't think you need exact timing information. This is no different > than running the commands themselves, with stdout and stderr writing to > a pty that your terminal emulator will then read() from. If the program > produces intermingled stdout/stderr that clogs up the terminal, that is > its problem. > > The only difference is that we're going to save it and later replay it > all very quickly. So I think it would be sufficient just to retain the > original order. > >> I will add documentation explaining why the async output case >> will only deal with one channel. I chose stderr as that's already >> available and needed in this use case. > > I suspect you could just set child->stdout_to_stderr in this case, and > then you get your ordering for free. But probably in the general case > people would want to run inspection commands that produce a useful > stdout. > > To handle multiple channels, I think you could just do a linked list of > buffers rather than a single strbuf. Like: I will have no problem coding such a thing in a user program, but how do you obtain this non racily from the child using the posix API? The poll/select command may return more than one fd ready, so then you don't know the ordering in which you would need to replay it. This may introduce subtle bugs? So I'd rather come up with a solution buffering 2 channels once we need it, keeping the stdout_to_stderr as a requirement for now. > > struct io_chunk { > int channel; > char *buf; > size_t len; > struct io_chunk *next; > }; > > and just keep appending chunks to the list (and to dump them, just walk > the list, writing each to the appropriate channel descriptor). > > -Peff -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html