mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
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 <wangjianyu3@xiaomi.com>
This commit is contained in:
parent
72bedd5c5d
commit
ed063a0981
2 changed files with 19 additions and 11 deletions
|
|
@ -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 */
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
ret = write(OUTFD(pstate), buffer, nbytes);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("ERROR: [%d] Failed to send buffer: %d\n",
|
||||
OUTFD(pstate), errno);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return write(OUTFD(pstate), buffer, nbytes);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue