This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new ed063a098 nshlib: fix infinite loop on broken stdout in nsh_catfile
ed063a098 is described below
commit ed063a0981f97949c1294745eb5602bfa8170d36
Author: wangjianyu3 <[email protected]>
AuthorDate: Tue May 19 16:42:47 2026 +0800
nshlib: fix infinite loop on broken stdout in nsh_catfile
When stdout is broken (e.g. PTY master closed), nsh_catfile could spin
forever: write() fails, error logging generates syslog output to
/dev/log, next read() picks it up, write() fails again, ad infinitum.
Two fixes:
- nsh_console: drop the _err() in nsh_consolewrite entirely. The risk
is errno-agnostic (EPIPE / EIO / ENOSPC / ...): any failure logged
here can be re-injected by the syslog backend when OUTFD is bound to
/dev/log. Callers already see the failure via the negative return
value and errno, so on-failure logging at this layer is redundant.
- nsh_fsutils: jump straight from the inner write-failure path to a
single errout: cleanup label instead of using a two-level break +
flag check, so a failed write cannot fall through to another read().
Assisted-by: GitHubCopilot:claude-4.7-opus
Signed-off-by: wangjianyu3 <[email protected]>
---
nshlib/nsh_console.c | 23 ++++++++++++-----------
nshlib/nsh_fsutils.c | 9 ++++++++-
2 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/nshlib/nsh_console.c b/nshlib/nsh_console.c
index ebcbe6fb2..0e4284222 100644
--- a/nshlib/nsh_console.c
+++ b/nshlib/nsh_console.c
@@ -131,18 +131,19 @@ static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s
*vtbl,
FAR const void *buffer, size_t nbytes)
{
FAR struct console_stdio_s *pstate = (FAR struct console_stdio_s *)vtbl;
- ssize_t ret;
-
- /* Write the data to the output stream */
- ret = write(OUTFD(pstate), buffer, nbytes);
- if (ret < 0)
- {
- _err("ERROR: [%d] Failed to send buffer: %d\n",
- OUTFD(pstate), errno);
- }
-
- return ret;
+ /* Write the data to the output stream.
+ *
+ * Errors are reported to the caller via the negative return value and
+ * errno; do NOT _err() here. OUTFD may itself be wired to the syslog
+ * backend (e.g. nsh_catfile dumping /dev/log on dmesg), in which case
+ * logging on write failure would produce new bytes, get picked up by
+ * the next read(), and lock the shell into an infinite loop at the
+ * highest priority — independent of which errno (EPIPE/EIO/ENOSPC/...)
+ * the underlying device returns.
+ */
+
+ return write(OUTFD(pstate), buffer, nbytes);
}
/****************************************************************************
diff --git a/nshlib/nsh_fsutils.c b/nshlib/nsh_fsutils.c
index 878c1d18e..7044d8d54 100644
--- a/nshlib/nsh_fsutils.c
+++ b/nshlib/nsh_fsutils.c
@@ -228,8 +228,14 @@ int nsh_catfile(FAR struct nsh_vtbl_s *vtbl, FAR const
char *cmd,
NSH_ERRNO_OF(errcode));
}
+ /* Jump straight to cleanup. On a broken stdout (e.g.
+ * closed PTY master) we must not keep reading: the
+ * outer loop would otherwise drain /dev/log forever
+ * when cat is dumping it on dmesg.
+ */
+
ret = ERROR;
- break;
+ goto errout;
}
else
{
@@ -255,6 +261,7 @@ int nsh_catfile(FAR struct nsh_vtbl_s *vtbl, FAR const char
*cmd,
/* Close the input file and return the result */
+errout:
close(fd);
free(buffer);
return ret;