Mail Archives: djgpp-workers/2001/06/04/00:41:25
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 -