delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/06/04/00:41:25

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Mon, 4 Jun 2001 00:40:59 -0400
MIME-Version: 1.0
Subject: file append problem
Message-ID: <3B1AD91B.15461.664B37@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

Hi,
I believe I found a problem that remains with appending to files. I 
discovered the problem trying to figure out why a file generated from a 
script was jumbled. I've created a short script that demonstrates the 
problem. I've also written a short program that emulates how the script is 
executed. In both cases, the output is:

abc
abc
67890

and the expected output is:
abc
1234567890
abc

redir_test.sh:
#! /bin/sh

exec 7 >& ./test.txt
echo "abc" >& 7
echo "1234567890" >> ./test.txt
echo "abc" >& 7

redir_test.c:

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>

/* Simulate the script:
   exec 7 >& ./test.txt
   echo "abc" >& 7
   echo "1234567890" >> ./test.txt
   echo "abc" >& 7
*/

int main()
{
  int fd1, fd2, fd3;

  fd1 = dup(1);

  /* exec 7>& ./test.txt */
  fd2 = open("test.txt", O_WRONLY | O_APPEND | O_TRUNC | O_CREAT, S_IWUSR);

  if (fd2 < 0)
    return 1;

  dup2(fd2, 1);

  /* echo "abc" >& 7 */
  printf("abc");
  putchar('\n');
  fflush (stdout);

  dup2(fd1, 1);

  /* echo "1234567890" >> ./test.txt */
  fd3 = open("test.txt", O_WRONLY | O_APPEND, S_IWUSR);

  if (fd3 < 0)
    return 1;

  dup2(fd3, 1);

  printf("1234567890");
  putchar('\n');
  fflush (stdout);

  dup2(fd1, 1);

  /* echo "abc" >& 7 */
  dup2(fd2, 1);

  printf("abc");
  putchar('\n');
  fflush (stdout);

  dup2(fd1, 1);

  /* close up shop */
  close (fd3);
  close (fd2);
  close (fd1);

  return 0;
}

The problem seems to be that fileno(stdout) gets its append flag set, but 
stdout doesn't. Because _flsbuf never checks its underlying fd to see if its 
append flag is set, it doesn't know it should perform a 'llseek(1, 0, 
SEEK_END)' before calling _write.

I see two solutions:
1) Have _flsbuf (and other places where _IOAPPEND is checked) check whether 
the underlying fd has its append flag set before calling _write.
2) Add logic to _write to check whether a file descriptor's append flag is 
set and take action.

I'll think about which one I like better tommor... later.

Mark

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019