summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2023-03-07 01:12:12 +0000
committerPádraig Brady <P@draigBrady.com>2023-03-07 01:14:00 +0000
commit35ac97e0d601d5a20bf986bad052f0f94a504561 (patch)
tree24b7033884d2cbd36a20fa5ce0427fdacb840a39
parenta4778006c8f2b669afcc45456acf0d21f228208d (diff)
downloadcoreutils-35ac97e0d601d5a20bf986bad052f0f94a504561.tar.gz
tee: fix a crash with unwriteable files
This was introduced recently with commit v9.1-166-g6b12e62d9 * src/tee.c (tee_files): Check the return from fopen() before passing to fileno() etc. * tests/misc/tee.sh: Add a test case.
-rw-r--r--src/tee.c8
-rwxr-xr-xtests/misc/tee.sh5
2 files changed, 10 insertions, 3 deletions
diff --git a/src/tee.c b/src/tee.c
index 4fc6722d4..8da68230a 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -259,11 +259,11 @@ tee_files (int nfiles, char **files, bool pipe_check)
for (i = 1; i <= nfiles; i++)
{
/* Do not treat "-" specially - as mandated by POSIX. */
- descriptors[i] = fopen (files[i], mode_string);
- if (pipe_check)
- out_pollable[i] = iopoll_output_ok (fileno (descriptors[i]));
+ descriptors[i] = fopen (files[i], mode_string);
if (descriptors[i] == NULL)
{
+ if (pipe_check)
+ out_pollable[i] = false;
error (output_error == output_error_exit
|| output_error == output_error_exit_nopipe,
errno, "%s", quotef (files[i]));
@@ -271,6 +271,8 @@ tee_files (int nfiles, char **files, bool pipe_check)
}
else
{
+ if (pipe_check)
+ out_pollable[i] = iopoll_output_ok (fileno (descriptors[i]));
setvbuf (descriptors[i], NULL, _IONBF, 0);
n_outputs++;
}
diff --git a/tests/misc/tee.sh b/tests/misc/tee.sh
index 30d64a9d2..63e7524c0 100755
--- a/tests/misc/tee.sh
+++ b/tests/misc/tee.sh
@@ -74,6 +74,11 @@ retry_delay_ tee_exited .1 7 | # 12.7s (Must be > following timeout)
test $(wc -l < err) = 0 || { cat err; fail=1; }
test -f tee.exited || fail=1
+# Test with unwriteable files
+touch file.ro || framework_failure_
+chmod a-w file.ro || framework_failure_
+returns_ 1 tee -p </dev/null file.ro || fail=1
+
# Ensure tee honors --output-error modes
mkfifo_or_skip_ fifo
read_fifo() { timeout 10 dd count=1 if=fifo of=/dev/null status=none & }