1

I have been looking at terminfo and it has delays, e.g. $<5>, in the capability strings. I was trying to see through running tput under strace how is the delay implemented, i.e., whether it is implemented by, say, nanosleep or by inserting NUL or other characters. This is the command I have tried to run and trace:

TERM=ansi77 strace -o log.txt tput dl1

I chose dl1 on ansi77 because it is defined as dl1=\E[M$<5*/>. However, all I see in the trace is write of 3 bytes:

write(1, "\33[M", 3)                    = 3
  1. So, my question is, how the delay actually implemented? Padding characters or simple process/thread sleep?
  2. Can I observe it in terminal emulator or do I need real hardware terminal to see it?
  3. Is there any flaw in trying to reproduce it with tput?
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
wilx
  • 17,697
  • 6
  • 59
  • 114
  • The unasked question is the elephant in the room: do modern implementations even bother? –  Oct 27 '15 at 20:01
  • @WumpusQ.Wumbley: Well, what if you connect real terminal using serial line? It should respect the delays at least in that case. – wilx Oct 27 '15 at 23:55

2 Answers2

2

Where delays are implemented, it's done by transmitting pad characters, traditionally NUL characters. The pad character can be changed by a termdata/terminfo setting of the variable pad or pc.

Pad characters are necessary because the program cannot know when the previously-sent characters have actually been written for it to start a CPU delay. Even if the kernel is done with them after an output flush the characters might still be buffered in the output device UART.

The number of required pad characters is calculated from the baud rate - so it depends on that information being available and accurate.

The tputs routine in the library implements padding (see man 3 tputs). I suspect that the command-line tool does too, since it's basically just a wrapper.

cliffordheath
  • 2,536
  • 15
  • 16
2

Agreeing with @cliffordheath that padding is done by adding padding characters, reference to the available documentation can help.

Hardware terminals did not cease to exist, they are still supported by ncurses. Without padding, these old terminals would not work properly (dropping or mangling your output). The vt100 entry uses padding, that for xterm does not.

The terminfo name for the padding character is pad; pc is a termcap name (see terminfo(5)):

   pad_char                  pad    pc   padding char
                                         (instead of null)

The terminfo manual page has a lengthy paragraph (in Types of Capabilities) dealing with padding. There are two types of padding supported in terminfo format (advisory and mandatory), distinguished by their format. termcap supports only the latter (using different syntax of course), and unlike terminfo all of the delays happen at one time (making escape sequences for "flash" generally not work).

The command-line tput program does more than act as a wrapper for the function tputs, but it uses that when outputting strings. The command-line program provides for outputting boolean, numeric and of course string capabilities.

The library call tputs has a parameter for the number of affected lines which is taken into account (like baud rate) in computing delays.

In OP's question

dl1=\E[M$<5*/>

specifies a delay proportional to the number of lines affected (marked by the "*" character). The number of lines affected for the command-line tput utility is 1. It calls putp to do this. However, that in turn calls delay_output, and that calls baudrate. The last function is initialized only when the terminal is initialized. The command-line tput does not initialize the terminal, so delays will not work for that. You should see (given the right speed) delays using the library itself.

ncurses also provides time delays with napms (milliseconds), which is different from padding.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • This seems to be a random collection of facts about padding that fails to answer the actual question: if `tput` is supposed to support padding, why don't we see it actually writing any padding bytes in the `strace`? –  Oct 28 '15 at 14:53
  • If you don't see any nulls, that's because the optimizer determined that none were needed or would affect the result. – Thomas Dickey Oct 29 '15 at 00:13
  • Does `tack` not initialize the terminal? I started investigating this because I was getting `flash` failures in `tack`. The really odd thing is, `tput` seems to sleep, but before writing the whole sequence rather than in the middle of it. – Random832 Sep 24 '16 at 19:26
  • Also just as a point of curiosity, is "number of lines affected" for something like a line insert/delete/scroll the number of lines deleted, number of lines moved (less if you scroll by more lines), or number of lines changed (distance between cursor and the bottom of the screen, more or less)? – Random832 Sep 24 '16 at 19:28
  • Think of it as the number of lines to be repainted. – Thomas Dickey Sep 24 '16 at 23:49