On 2/19/25 12:47, Karl Berry wrote:
However ... when I ran make check with the changes installed, the tap-merge-stdout-stderr test failed. Did it succeed for you? Before I delved into it, thought I'd check back.
Doh! There's a race condition and no portable (POSIX) way to fix it, I think. The proposed change spawns an asynchronous subshell (a pipeline stage) to read stderr, prefix each line, and write the results to stdout. That subshell is a separate process/thread that races with the direct writes to stdout.
The only race-free* fix is to use a select or poll loop to read from both stderr and stdout simultaneously from a single thread. Unfortunately, there is no portable way (that I know of) to use those system interfaces from a shell script. Perl, Python, etc. can do it, but those add a new dependency. It's not practical to ship a C file and compile that when the user runs the tests (right?).
I can reduce the severity of the out-of-order writes by (a) not piping stderr through the prefixing function when the prefix is the empty string, and (b) avoiding stdout buffering when stderr is prefixed. These changes might provide good enough results for most users. Users that require stronger guarantees can wrap their test program in a custom helper utility rather than rely on Automake's TAP driver to do the prefixing and merging.
Thoughts and suggestions would be appreciated. -Richard*Even a select/poll loop wouldn't be completely race-free: if the test process writes to both stdout and stderr while a previous write is still being processed then the next loop iteration won't know whether the stdout or the stderr write happened first.
OpenPGP_signature.asc
Description: OpenPGP digital signature