diff --git a/nshlib/nsh_console.c b/nshlib/nsh_console.c index ebcbe6fb260..0e42842220e 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 878c1d18e51..7044d8d54a9 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;