diff options
| author | Paul Eggert <eggert@cs.ucla.edu> | 2025-02-14 13:10:02 -0800 |
|---|---|---|
| committer | Paul Eggert <eggert@cs.ucla.edu> | 2025-02-14 13:13:08 -0800 |
| commit | 7386c291be8e2de115f2e161886e872429edadd7 (patch) | |
| tree | fcef6842cb4fcc997c9b119866d104e06676e137 | |
| parent | cat: omit unnecessary lseek (diff) | |
| download | coreutils-7386c291be8e2de115f2e161886e872429edadd7.tar.gz coreutils-7386c291be8e2de115f2e161886e872429edadd7.zip | |
cat: fix plain ‘cat’ bug
* src/cat.c (main): Do not fail with plain ‘cat’ where input and
output are both /dev/tty, if the output happens to have O_APPEND set.
Problem reported by lilydjwg <https://bugs.gnu.org/76255>.
Also, don’t report an error if the seek position is at or after EOF,
even if O_APPEND is set.
| -rw-r--r-- | NEWS | 6 | ||||
| -rw-r--r-- | src/cat.c | 26 |
2 files changed, 18 insertions, 14 deletions
@@ -4,7 +4,11 @@ GNU coreutils NEWS -*- outline -*- ** Bug fixes - `ls -Z dir` would crash. + 'cat' would fail with "input file is output file" if input and + output are the same terminal device and the output is append-only. + [bug introduced in coreutils-9.6] + + 'ls -Z dir' would crash. [bug introduced in coreutils-9.6] @@ -717,20 +717,20 @@ main (int argc, char **argv) && have_out_dev && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino) { - if (out_flags < -1) - out_flags = fcntl (STDOUT_FILENO, F_GETFL); - bool exhausting = 0 <= out_flags && out_flags & O_APPEND; - if (!exhausting) + off_t in_pos = lseek (input_desc, 0, SEEK_CUR); + if (0 <= in_pos) { - off_t in_pos = lseek (input_desc, 0, SEEK_CUR); - if (0 <= in_pos) - exhausting = in_pos < lseek (STDOUT_FILENO, 0, SEEK_CUR); - } - if (exhausting) - { - error (0, 0, _("%s: input file is output file"), quotef (infile)); - ok = false; - goto contin; + if (out_flags < -1) + out_flags = fcntl (STDOUT_FILENO, F_GETFL); + int whence = (0 <= out_flags && out_flags & O_APPEND + ? SEEK_END : SEEK_CUR); + if (in_pos < lseek (STDOUT_FILENO, 0, whence)) + { + error (0, 0, _("%s: input file is output file"), + quotef (infile)); + ok = false; + goto contin; + } } } |
