coreutils/backport-cat-fix-plain-cat-bug.patch
2025-03-18 09:30:58 +08:00

82 lines
2.9 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 7386c291be8e2de115f2e161886e872429edadd7 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 14 Feb 2025 13:10:02 -0800
Subject: =?UTF-8?q?cat:=20fix=20plain=20=E2=80=98cat=E2=80=99=20bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 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, dont report an error if the seek position is at or after EOF,
even if O_APPEND is set.
---
src/cat.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
(limited to 'src/cat.c')
diff --git a/src/cat.c b/src/cat.c
index 274f844..c022103 100644
--- a/src/cat.c
+++ b/src/cat.c
@@ -646,9 +646,15 @@
idx_t outsize = io_blksize (stat_buf);
/* Device, I-node number and lazily-acquired flags of the output. */
- dev_t out_dev = stat_buf.st_dev;
- ino_t out_ino = stat_buf.st_ino;
+ dev_t out_dev;
+ ino_t out_ino;
int out_flags = -2;
+ bool have_out_dev = ! (S_TYPEISSHM (&stat_buf) || S_TYPEISTMO (&stat_buf));
+ if (have_out_dev)
+ {
+ out_dev = stat_buf.st_dev;
+ out_ino = stat_buf.st_ino;
+ }
/* True if the output is a regular file. */
bool out_isreg = S_ISREG (stat_buf.st_mode) != 0;
@@ -706,22 +712,25 @@
output device. It's better to catch this error earlier
rather than later. */
- if (stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino)
+ if (! (S_ISFIFO (stat_buf.st_mode) || S_ISSOCK (stat_buf.st_mode)
+ || S_TYPEISSHM (&stat_buf) || S_TYPEISTMO (&stat_buf))
+ && 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)
- exhausting = in_pos < lseek (STDOUT_FILENO, 0, SEEK_CUR);
- }
- if (exhausting)
+ off_t in_pos = lseek (input_desc, 0, SEEK_CUR);
+ if (0 <= in_pos)
{
- 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;
+ }
}
}