Search code examples
makefileterminalblockinggnu-screenpty

How to control GNU screen's blocking behaviour


Why does GNU screen, when set to Copy Mode, sometimes block the inner process(es), yet other times it does not?

For example, the following bash one-liner is not blocked by Copy Mode:

while ((1)) ; do echo $i; i=$((i+1)); sleep 0.1; done

If you run this, then invoke Copy Mode (CTRL+A ESCAPE), wait a few seconds, then leave the mode (ESCAPE), the output will jump because it continues to run "behind" the Copy display.

But if you take a C Makefile and do the same, you'll see that in some cases the compilation within freezes, and does not continue behind the scenes. Only when you leave Copy Mode does it continue.

Yet not for all Makefiles:

.PSEUDO: count
count:
    number=1 ; while (true) ; do \
        echo $$number ; \
        number=$$((number + 1)) ; \
        sleep 0.1 ; \
    done

Can anyone shed some light on this? Is it related to flow control within screen, or maybe the obuflimit? I've played around with a number of these settings but it's really not clear to me what is going on and how to influence it. Obviously screen cannot save the output forever, as that would take unlimited memory, but what is the size of the buffer and is there any way to change this so that an invocation of make with significant output can run to completion behind the Copy Mode display?


Solution

  • The limit is not in screen. Every tty/pty has an input buffer and output buffer. When the input (or output) buffer is full, processes reading from (or writing to) it will be blocked or some data will be lost.

    Not sure if the buffer size can be changed but you can work it around this way:

    touch make.log
    tail -f make.log &
    make >> make.log 2>&1
    # when `make' is done, kill the `tail', e.g. with bash:
    kill %%
    

    then when you enter screen's Copy mode it can only possibly block the tail process and make will keep running.