Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why override write() when you can just use pipes?

http://distfiles.exherbo.org/distfiles/hilite-1.5.c



One problem is stdio buffering. By default the C stdio functions will flush buffers after every line for file descriptors that are connected to terminals, but only every now and then for file descriptors connected to disk files or pipes. So if a program outputs messages on both stdout and stderr (like a compiler), then after filtering one of the streams through a pipe, the messages are not interleaved properly.


One way is to wrap the program with a parent process that can handle the colourising. Here's a version I've been using for 6 years or so;

http://people.apache.org/~colm/utils/sexec.c

it uses regular select semantics and a trivial state machine to pick the active fd, and has an XML mode - which is convenient for colourising in XHTML (if you want to record an automated process say).


Here is an example illustrating what I mean:

    #include <stdio.h>
    int main() {
       while (1) {
           fprintf(stdout, "Hi.\n");
           fprintf(stderr, "Hello.\n");
       }
       return 0;
    }
If you run this program directly from the shell, every odd line says Hi and every even line says Hello. But if you run it through sexec (on a Linux machine at least), you get a large block of lines saying Hi, followed by a large block saying Hello, etc. Whether this is a problem or not of course depends on the use case. But to avoid it you need something more sophisticated than just pipes, e.g. the LD_PRELOAD hack in the original post.


Now I get you. I'm tempted to write a small pty allocator which does enough to allow isatty() return true.


Or you could just disable buffering, for instance with the unbuffer tool that comes with Expect:

    ./mytest | tee out.txt # blocks of Hello. and Hi.
    unbuffer ./mytest | tee out.txt # expected result


Without looking at it's source, what 'unbuffer' does is likely allocate a PTY for the things under it. That's how the rest of Expect works after all ;)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: