Skip to content

mainUtils: match readline behavior when ABC_USE_READLINE is undefined#514

Merged
alanminko merged 1 commit into
berkeley-abc:masterfrom
maliberty:fix-non-readline-prompt-pipe
Jun 5, 2026
Merged

mainUtils: match readline behavior when ABC_USE_READLINE is undefined#514
alanminko merged 1 commit into
berkeley-abc:masterfrom
maliberty:fix-non-readline-prompt-pipe

Conversation

@maliberty
Copy link
Copy Markdown
Contributor

The non-readline branch of Abc_UtilsGetUsersInput has three behavioral gaps
versus the readline branch that break callers driving abc as a coprocess
over a pipe — notably yosys's passes/techmap/abc.cc, which spawns abc -s
with piped stdin/stdout and uses read_until_abc_done to wait for
abc NN> <command> lines:

  1. Missing flush on the prompt. The prompt is written with fprintf()
    and never flushed. On a pipe stdout is fully buffered, so the prompt
    never reaches the reader. The reader waits for the prompt, abc waits
    in fgets(), deadlock.

  2. No echo of input. readline() emits each character to its output
    stream; yosys's protocol depends on seeing abc NN> source ...\n in
    the output to advance state. Without an echo it waits forever.

  3. EOF ignored. When stdin closes, fgets() returns NULL but the
    function returns a stale Prompt buffer, causing a tight loop on pipe
    close. The readline branch exit(0)s on NULL.

This patch fixes all three. The echo is gated on !isatty(fileno(stdin))
because on a tty the kernel already echoes during cooked input, and a
double echo would be visible to interactive users.

Reproduction

Without the patch, with an ABC_USE_READLINE=0 build:

$ printf 'version\nquit\n' | ./abc -s
UC Berkeley, ABC 1.01 ...
abc 01> UC Berkeley, ABC 1.01 ...

The prompt appears (only because the pipe drained on exit, not on
flush) and the input is never echoed. yosys, which expects to see
`abc 01> source <script>` in the stream, hangs in `read()`.

With the patch, the same invocation produces:

$ printf 'version\nquit\n' | ./abc -s
UC Berkeley, ABC 1.01 ...
abc 01> version
UC Berkeley, ABC 1.01 ...
abc 02> quit

which matches the output stream readline produces on the same input, and
unblocks yosys's coprocess driver.

The non-readline branch of Abc_UtilsGetUsersInput has three behavioral
gaps versus the readline branch that break callers driving abc as a
coprocess over a pipe (e.g. yosys's passes/techmap/abc.cc, which spawns
"abc -s" with piped stdin/stdout and uses read_until_abc_done to wait
for "abc NN> <command>" lines):

  1. The prompt is written with fprintf() and never flushed. On a pipe
     stdout is fully buffered, so the prompt never reaches the reader.
     The reader waits for the prompt, abc waits in fgets(), deadlock.

  2. There is no echo of the line read from stdin. readline() emits
     each character to its output stream; yosys's protocol depends on
     seeing "abc NN> source ...\n" in the output to advance state.
     Without an echo it waits forever.

  3. EOF on stdin is silently ignored: fgets() returns NULL but the
     function returns a stale Prompt buffer, causing a tight loop on
     pipe close. The readline branch exit(0)s on NULL.

Fix all three. Echo only when stdin is not a tty -- on a tty the kernel
already echoes typed characters during cooked input, so double-echo
would be visible to interactive users.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
@alanminko alanminko merged commit cd33ba5 into berkeley-abc:master Jun 5, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants