Skip to content

cdba: read stdin even when it is not a tty - #98

Open
lumag wants to merge 1 commit into
linux-msm:masterfrom
lumag:cdba-nontty-stdin
Open

cdba: read stdin even when it is not a tty#98
lumag wants to merge 1 commit into
linux-msm:masterfrom
lumag:cdba-nontty-stdin

Conversation

@lumag

@lumag lumag commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Automating cdba is currently impossible without allocating a pty for it, and
the failure gives no hint as to why: the board boots, console output arrives,
and every keystroke written to a fifo or a pipe on stdin is dropped in
silence. It reads as a board that ignores input, so the time goes into
suspecting the target rather than the tool.

The intent to support this case is already in the tree — 7c12435 added
the ENOTTY tolerance so cdba could be launched from cron — but the select loop
reuses the "we changed the termios and must restore it" pointer as its "should
we watch stdin" flag, which quietly withdraws it again.

Wiring cdba into CI, test harnesses and agent-driven workflows is the
motivation; needing a pty to send a single line to a board is a sharp edge
that each such user has to rediscover.

Verified against a DB820c over a plain fifo with stdout redirected to a file
and no pty involved.

Driving cdba from a script -- a fifo or a pipe on stdin -- silently does
nothing.  The board boots, the console output arrives as usual, but every
keystroke written to stdin is discarded without an error or a warning, so
it looks like the board is ignoring input rather than like cdba never
sending it.

tty_unbuffer() returns NULL when stdin is not a tty, which commit
7c12435 ("cdba: Gracefully handle stdin not being a tty") introduced
precisely so that cdba stays usable when launched from cron and friends.
The select loop, however, uses that same pointer to decide whether to
watch stdin at all:

	if (orig_tios) {
		FD_SET(STDIN_FILENO, &rfds);
		nfds = MAX(nfds, STDIN_FILENO);
	}

so a non-tty stdin is never added to the read set and never read.  The
pointer answers "did we change the termios, and must we restore it", which
is not the same question as "can we read stdin", and conflating the two
undoes the graceful handling it was meant to preserve.

Track the two separately: always watch stdin, and stop watching it once it
reports EOF or an error.  The latter matters because a closed pipe stays
readable forever, and without unregistering it select() would spin.

Tested against a DB820c through a plain fifo with stdout redirected to a
file and no pty anywhere: the login and the commands that follow now reach
the console.

Fixes: 1e92a38 ("cdba: Make exit code reflect exit cause")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
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.

1 participant