On 12/13/25 1:51 AM, Grisha Levit wrote:
On Fri, Dec 12, 2025, 19:20 Robert Elz <[email protected] <mailto:[email protected]>> wrote:

 > I'm guessing that the difference between using awk, and most other
 > processes that might be used (echo, sed, even cat probably) inside the
 > cmdsub, is that awk (gawk) might be doing
 >
 >         freopen(filename, "r", stdin);
 >
 > or something similar, which it is perfectly entitled to do (ie: doing that
 > is certainly not, of itself, a bug).

What gawk had was essentially a call like:

     fcntl(2, F_SETFL, fcntl(2, F_GETFL) | O_APPEND);

And coreutils cat changes the test it uses to determine whether or not an
output file is an input file depending on whether O_APPEND is set in the
output file's flags.

So let's posit that fd 1 and fd 2 are the same at startup (dup2 (1, 2) or
equivalent somewhere). Then gawk changing fd 2 to add O_APPEND to the
file flags will change fd 1's flags. Further posit that fd 0 is the same
device but opened by a different call to open(2), so it will test as having
the same device and inode, but with a different entry in the file table and
a different flag set.

This appears to change how cat tests whether fd 0 and fd 1 are the same
file (this is from coreutils-git):

      if (! (S_ISFIFO (stat_buf.st_mode) || S_ISSOCK (stat_buf.st_mode)
             || S_TYPEISSHM (&stat_buf) || S_TYPEISTMO (&stat_buf))
          && have_out_dev
          && SAME_INODE (stat_buf, out_id))
        {
          off_t in_pos = lseek (input_desc, 0, SEEK_CUR);
          if (0 <= in_pos)
            {
              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;
                }
            }
        }

and the difference between fd 0/SEEK_CUR and fd 1/SEEK_END is enough.

I don't have a better explanation and I've already spent way too much
time on this.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    [email protected]    http://tiswww.cwru.edu/~chet/

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to