From: Martin Str|mberg Message-Id: <200010132314.BAA29969@father.ludd.luth.se> Subject: Bug 000323 (LONG) To: djgpp-workers AT delorie DOT com (DJGPP-WORKERS) Date: Sat, 14 Oct 2000 01:14:15 +0200 (MET DST) X-Mailer: ELM [version 2.4ME+ PL54 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Ok, the good news is this: I've implemented the stuff for correcting this bug. BUT I have not the time to continue working on it for the moment so I'd like to make my work available to you if any of you have time for testing and hacking it. (If you haven't, it's not a problem as I'll come back to this later when I have time.) The bad news is: COMPLETELY untested! And I really mean this. I think it compiled but I might have changed something after that. I don't think I've compiled a program using a libc containing these changes. Right, MartinS Index: include/libc/dosio.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/libc/dosio.h,v retrieving revision 1.5 diff -p -u -r1.5 dosio.h --- dosio.h 1999/06/03 17:22:28 1.5 +++ dosio.h 2000/10/13 22:34:13 @@ -15,7 +15,7 @@ extern "C" { #ifndef _POSIX_SOURCE /* set to O_BINARY or O_TEXT */ -extern char *__file_handle_modes; +extern unsigned short *__file_handle_modes; extern void __file_handle_set(int fd, int mode); int __doserr_to_errno(int doserr); Index: include/libc/file.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/libc/file.h,v retrieving revision 1.8 diff -p -u -r1.8 file.h --- file.h 1999/06/27 16:27:44 1.8 +++ file.h 2000/10/13 22:34:14 @@ -93,6 +93,15 @@ static __inline__ int __putc(const int x else (p)->_flag |= _IONTERM; } + + if( (p)->_flag & _IOAPPEND ) + { + if( fseek((p), 0, SEEK_END) ) + { + return 0; + } + } + if(x=='\n' && __is_text_file(p)) __putc_raw('\r',p); return __putc_raw(x,p); Index: src/libc/ansi/stdio/fopen.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/fopen.c,v retrieving revision 1.1 diff -p -u -r1.1 fopen.c --- fopen.c 1995/08/23 07:49:24 1.1 +++ fopen.c 2000/10/13 22:34:17 @@ -51,12 +51,17 @@ fopen(const char *file, const char *mode else oflags |= (_fmode & (O_TEXT|O_BINARY)); + if( *mode == 'a' ) + { + oflags |= O_APPEND; + } + fd = open(file, oflags, 0666); if (fd < 0) return NULL; - if (*mode == 'a') - lseek(fd, 0, SEEK_END); + /* if (*mode == 'a') + lseek(fd, 0, SEEK_END); */ f->_cnt = 0; f->_file = fd; @@ -67,6 +72,11 @@ fopen(const char *file, const char *mode f->_flag = _IOREAD; else f->_flag = _IOWRT; + + if (*mode == 'a') + { + f->_flag |= _IOAPPEND; + } f->_base = f->_ptr = NULL; return f; Index: src/libc/ansi/stdio/fprintf.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/fprintf.c,v retrieving revision 1.1 diff -p -u -r1.1 fprintf.c --- fprintf.c 1994/12/26 20:34:46 1.1 +++ fprintf.c 2000/10/13 22:34:17 @@ -8,6 +8,14 @@ fprintf(register FILE *iop, const char * int len; char localbuf[BUFSIZ]; + if( iop->_flag & _IOAPPEND ) + { + if( fseek(iop, 0, SEEK_END) ) + { + return 0; + } + } + if (iop->_flag & _IONBF) { iop->_flag &= ~_IONBF; Index: src/libc/ansi/stdio/freopen.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/freopen.c,v retrieving revision 1.3 diff -p -u -r1.3 freopen.c --- freopen.c 1999/06/03 17:27:33 1.3 +++ freopen.c 2000/10/13 22:34:17 @@ -45,12 +45,17 @@ freopen(const char *file, const char *mo else oflags |= (_fmode & (O_TEXT|O_BINARY)); + if( *mode == 'a' ) + { + oflags |= O_APPEND; + } + fd = open(file, oflags, 0666); if (fd < 0) return NULL; - if (*mode == 'a') - lseek(fd, 0, SEEK_END); + /* if (*mode == 'a') + lseek(fd, 0, SEEK_END);*/ f->_cnt = 0; f->_file = fd; @@ -61,6 +66,11 @@ freopen(const char *file, const char *mo f->_flag = _IOREAD; else f->_flag = _IOWRT; + + if (*mode == 'a') + { + f->_flag |= _IOAPPEND; + } f->_base = f->_ptr = NULL; return f; Index: src/libc/ansi/stdio/fwrite.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/fwrite.c,v retrieving revision 1.5 diff -p -u -r1.5 fwrite.c --- fwrite.c 2000/06/28 08:20:55 1.5 +++ fwrite.c 2000/10/13 22:34:18 @@ -24,6 +24,14 @@ fwrite(const void *vptr, size_t size, si f->_flag |= _IONTERM; } + if( f->_flag & _IOAPPEND ) + { + if( fseek(f, 0, SEEK_END) ) + { + return 0; + } + } + s = size * count; if(!__is_text_file(f)) { Index: src/libc/dos/io/_creat.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/_creat.c,v retrieving revision 1.4 diff -p -u -r1.4 _creat.c --- _creat.c 2000/06/19 18:00:56 1.4 +++ _creat.c 2000/10/13 22:34:27 @@ -52,6 +52,6 @@ _creat(const char* filename, int attrib) errno = __doserr_to_errno(r.x.ax); return -1; } - __file_handle_set(r.x.ax, O_BINARY); + __file_handle_set(r.x.ax, O_BINARY | ( oflag & O_APPEND)); return r.x.ax; } Index: src/libc/dos/io/_creat_n.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/_creat_n.c,v retrieving revision 1.2 diff -p -u -r1.2 _creat_n.c --- _creat_n.c 2000/06/19 18:00:56 1.2 +++ _creat_n.c 2000/10/13 22:34:28 @@ -58,6 +58,6 @@ _creatnew(const char* filename, int attr errno = __doserr_to_errno(r.x.ax); return -1; } - __file_handle_set(r.x.ax, O_BINARY); + __file_handle_set(r.x.ax, O_BINARY | ( oflag & O_APPEND)); return r.x.ax; } Index: src/libc/dos/io/_open.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/_open.c,v retrieving revision 1.3 diff -p -u -r1.3 _open.c --- _open.c 2000/06/19 18:00:56 1.3 +++ _open.c 2000/10/13 22:34:29 @@ -54,6 +54,6 @@ _open(const char* filename, int oflag) errno = __doserr_to_errno(r.x.ax); return -1; } - __file_handle_set(r.x.ax, O_BINARY); + __file_handle_set(r.x.ax, O_BINARY | ( oflag & O_APPEND)); return r.x.ax; } Index: src/libc/dos/io/dosio.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/dosio.c,v retrieving revision 1.1 diff -p -u -r1.1 dosio.c --- dosio.c 1995/11/25 02:06:10 1.1 +++ dosio.c 2000/10/13 22:34:29 @@ -7,7 +7,7 @@ #include #include -static char init_file_handle_modes[20] = { +static unsigned short init_file_handle_modes[20] = { O_TEXT, O_TEXT, O_TEXT, @@ -18,7 +18,7 @@ static char init_file_handle_modes[20] = static int dosio_bss_count = -1; static size_t count=20; /* DOS default limit */ -char *__file_handle_modes = init_file_handle_modes; +unsigned short *__file_handle_modes = init_file_handle_modes; void __file_handle_set(int fd, int mode) Index: src/libc/posix/fcntl/open.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/fcntl/open.c,v retrieving revision 1.7 diff -p -u -r1.7 open.c --- open.c 2000/08/28 14:22:33 1.7 +++ open.c 2000/10/13 22:34:34 @@ -149,8 +149,8 @@ open(const char* filename, int oflag, .. /* this will do cooked/raw ioctl() on character devices */ setmode(fd, bintext); - if(oflag & O_APPEND) - lseek(fd, 0, SEEK_END); + /* if(oflag & O_APPEND) + lseek(fd, 0, SEEK_END);*/ return fd; } Index: src/libc/posix/unistd/write.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/write.c,v retrieving revision 1.3 diff -p -u -r1.3 write.c --- write.c 1997/08/31 17:49:14 1.3 +++ write.c 2000/10/13 22:34:36 @@ -37,6 +37,15 @@ write(int handle, const void* buffer, si if (count == 0) return 0; /* POSIX.1 requires this */ + if( __file_handle_modes[handle] & O_APPEND ) + { + if( llseek(handle, 0, SEEK_END) == -1 ) + { + /* llseek() sets errno. */ + return -1; + } + } + if(__file_handle_modes[handle] & O_BINARY) return _write(handle, buf, count); Index: tests/libc/ansi/stdio/append.c =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/ansi/stdio/append.c,v retrieving revision 1.1 diff -p -u -r1.1 append.c --- append.c 1995/08/27 20:55:10 1.1 +++ append.c 2000/10/13 22:34:52 @@ -2,6 +2,8 @@ #include #include +#define FILE_NAME "append.dat" + int main(void) { @@ -9,19 +11,29 @@ main(void) struct stat s; size_t len; - f = fopen("append.dat", "w"); + f = fopen(FILE_NAME, "w"); fprintf(f, "hello, there\n"); fclose(f); - stat("append.dat", &s); + stat(FILE_NAME, &s); len = s.st_size; - f = fopen("append.dat", "a"); + f = fopen(FILE_NAME, "a"); fprintf(f, "hello, there\n"); fclose(f); - stat("append.dat", &s); + stat(FILE_NAME, &s); if (s.st_size != len * 2) + { + printf("wrong size 1!\n"); + } + + f = fopen(FILE_NAME, "a+"); + fseek(f, 0, SEEK_SET); + fprintf(f, "hello, there\n"); + fclose(f); + stat(FILE_NAME, &s); + if (s.st_size != len * 3) { - printf("wrong size!\n"); + printf("wrong size 2!\n"); } return 0;