From: Martin Str|mberg Message-Id: <200103311757.TAA23410@mother.ludd.luth.se> Subject: Bug00323, final? (LONG) To: djgpp-workers AT delorie DOT com (DJGPP-WORKERS) Date: Sat, 31 Mar 2001 19:57:43 +0200 (MEST) X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com How about this? Right, MartinS Index: include/libc/fd_props.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/libc/fd_props.h,v retrieving revision 1.3 diff -p -u -r1.3 fd_props.h --- fd_props.h 2001/03/25 18:14:15 1.3 +++ fd_props.h 2001/03/31 17:42:15 @@ -25,6 +25,9 @@ extern "C" { /* Set when the descriptor is used for pipe emulation. */ #define FILE_DESC_PIPE 0x08 +/* Set when the descriptor is opened for append only. */ +#define FILE_DESC_APPEND 0x10 + typedef struct fd_properties fd_properties; struct fd_properties Index: src/libc/ansi/stdio/fflush.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/fflush.c,v retrieving revision 1.5 diff -p -u -r1.5 fflush.c --- fflush.c 1999/06/03 17:27:33 1.5 +++ fflush.c 2001/03/31 17:42:17 @@ -30,6 +30,17 @@ fflush(FILE *f) return 0; } + if (f->_flag & _IOAPPEND) + { + int save_errno = errno; /* We don't want llseek()'s setting + errno to remain. */ + if( llseek(fileno(f), 0, SEEK_END) == -1 ) + { + errno = save_errno; + return -1; + } + } + f->_flag &= ~_IOUNGETC; if ((f->_flag&(_IONBF|_IOWRT))==_IOWRT && (base = f->_base) != NULL Index: src/libc/ansi/stdio/flsbuf.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/flsbuf.c,v retrieving revision 1.4 diff -p -u -r1.4 flsbuf.c --- flsbuf.c 1999/06/03 17:27:33 1.4 +++ flsbuf.c 2001/03/31 17:42:17 @@ -1,3 +1,4 @@ +/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ @@ -6,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -90,7 +92,19 @@ _flsbuf(int c, FILE *f) if ((f->_flag & _IOTERM) == 0 || __libc_write_termios_hook == NULL || __libc_write_termios_hook(fileno(f), base, rn, &n) == 0) + { + if (f->_flag & _IOAPPEND) + { + int save_errno = errno; /* We don't want llseek()'s setting + errno to remain. */ + if( llseek(fileno(f), 0, SEEK_END) == -1 ) + { + errno = save_errno; + return EOF; + } + } n = _write(fileno(f), base, rn); + } if (n <= 0) { f->_flag |= _IOERR; 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 2001/03/31 17:42:18 @@ -1,3 +1,4 @@ +/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include @@ -29,7 +30,7 @@ fopen(const char *file, const char *mode switch (*mode) { case 'a': - oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY); + oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY) | O_APPEND; break; case 'r': oflags = rw ? O_RDWR : O_RDONLY; @@ -55,9 +56,6 @@ fopen(const char *file, const char *mode if (fd < 0) return NULL; - if (*mode == 'a') - lseek(fd, 0, SEEK_END); - f->_cnt = 0; f->_file = fd; f->_bufsiz = 0; @@ -67,6 +65,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/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 2001/03/31 17:42:18 @@ -1,3 +1,4 @@ +/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include @@ -23,7 +24,7 @@ freopen(const char *file, const char *mo switch (*mode) { case 'a': - oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY); + oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY) | O_APPEND; break; case 'r': oflags = rw ? O_RDWR : O_RDONLY; @@ -49,9 +50,6 @@ freopen(const char *file, const char *mo if (fd < 0) return NULL; - if (*mode == 'a') - lseek(fd, 0, SEEK_END); - f->_cnt = 0; f->_file = fd; f->_bufsiz = 0; @@ -61,6 +59,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/dos/io/fd_props.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/fd_props.c,v retrieving revision 1.2 diff -p -u -r1.2 fd_props.c --- fd_props.c 2001/03/13 19:39:12 1.2 +++ fd_props.c 2001/03/31 17:42:24 @@ -41,6 +41,8 @@ open_fd(fd_properties *cur_fd, int open_ cur_fd->flags = 0; if (cur_fd->filename && (open_flags & O_TEMPORARY)) cur_fd->flags |= FILE_DESC_TEMPORARY; + if (cur_fd->filename && (open_flags & O_APPEND)) + cur_fd->flags |= FILE_DESC_APPEND; } /* Perform file descriptor specific finalization. */ Index: src/libc/posix/fcntl/fcntl.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/fcntl/fcntl.c,v retrieving revision 1.5 diff -p -u -r1.5 fcntl.c --- fcntl.c 2001/02/01 19:19:24 1.5 +++ fcntl.c 2001/03/31 17:42:27 @@ -408,7 +408,8 @@ fcntl(int fd, int cmd, ...) case F_GETFL: { - return 0; + return 0; /* FIXME: should use the data in the SFT, and the + FILE_DESC_APPEND flag in __fd_properties */ } Index: src/libc/posix/fcntl/open.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/fcntl/open.c,v retrieving revision 1.8 diff -p -u -r1.8 open.c --- open.c 2001/03/07 05:39:05 1.8 +++ open.c 2001/03/31 17:42:28 @@ -1,3 +1,4 @@ +/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ @@ -27,6 +28,7 @@ int open(const char* filename, int oflag, ...) { int fd, dmode, bintext, dont_have_share; + /* int append_mode = (oflag & O_APPEND);*/ char real_name[FILENAME_MAX + 1]; int should_create = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL); @@ -151,8 +153,8 @@ open(const char* filename, int oflag, .. setmode(fd, bintext); __set_fd_properties(fd, real_name, oflag); - if(oflag & O_APPEND) - lseek(fd, 0, SEEK_END); + /* if (append_mode) + __file_handle_modes[fd] |= O_APPEND;*/ return fd; } Index: src/libc/posix/stdio/fdopen.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/stdio/fdopen.c,v retrieving revision 1.1 diff -p -u -r1.1 fdopen.c --- fdopen.c 1995/07/25 07:19:42 1.1 +++ fdopen.c 2001/03/31 17:42:28 @@ -24,7 +24,7 @@ fdopen(int fildes, const char *mode) switch (*mode) { case 'a': - oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY); + oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY) | O_APPEND; break; case 'r': oflags = rw ? O_RDWR : O_RDONLY; @@ -47,7 +47,9 @@ fdopen(int fildes, const char *mode) oflags |= (_fmode & (O_TEXT|O_BINARY)); if (*mode == 'a') - lseek(fildes, 0, SEEK_END); + { + f->_flag |= _IOAPPEND; + } f->_cnt = 0; f->_file = fildes; Index: src/libc/posix/unistd/write.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/write.c,v retrieving revision 1.5 diff -p -u -r1.5 write.c --- write.c 2001/03/25 00:55:09 1.5 +++ write.c 2001/03/31 17:42:29 @@ -38,6 +38,16 @@ write(int handle, const void* buffer, si if (count == 0) return 0; /* POSIX.1 requires this */ + if ( __has_fd_properties(handle) + && ( __fd_properties[handle]->flags & FILE_DESC_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 2001/03/31 17:42:31 @@ -2,27 +2,42 @@ #include #include +#define FILE_NAME "append.dat" + int main(void) { FILE *f; + int status = 0; /* Return value. */ 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"); + status++; + } + + 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"); + status++; } - return 0; + return status; } Index: tests/libc/ansi/stdio/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/ansi/stdio/makefile,v retrieving revision 1.4 diff -p -u -r1.4 makefile --- makefile 1999/04/18 15:14:35 1.4 +++ makefile 2001/03/31 17:42:31 @@ -2,6 +2,7 @@ TOP=../.. SRC += append.c SRC += bintext.c +SRC += fflush.c SRC += filbuf.c SRC += file.c SRC += fprintf.c Index: tests/libc/posix/unistd/append.c =================================================================== RCS file: append.c diff -N append.c --- /dev/null Tue May 5 16:32:27 1998 +++ append.c Sat Mar 31 12:42:33 2001 @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +#define FILE_NAME "append.dat" +char str[] = "hello, there\n"; + +int +main(void) +{ + char in = 0; + int fd; + int status = 0; /* Return value. */ + struct stat s; + size_t len; + + fd = open( FILE_NAME, O_WRONLY|O_CREAT|O_TRUNC ); + write( fd, str, strlen(str) ); + close( fd ); + stat( FILE_NAME, &s ); + len = s.st_size; + + fd = open( FILE_NAME, O_APPEND|O_WRONLY); + write( fd, str, strlen(str) ); + close( fd ); + stat( FILE_NAME, &s ); + if (s.st_size != len * 2) + { + printf("wrong size 1!\n"); + status++; + } + + fd = open( FILE_NAME, O_APPEND|O_RDWR ); + lseek( fd, 1, SEEK_SET ); + read( fd, &in, 1 ); + if( in != str[1] ) + { + printf( "Wrong character found: '%c', expected '%c'!\n", in, str[1] ); + status++; + } + write( fd, str, strlen(str) ); + close( fd ); + stat( FILE_NAME, &s ); + if( s.st_size != len * 3 ) + { + printf("wrong size 2!\n"); + status++; + } + + return status; +} Index: tests/libc/posix/unistd/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/posix/unistd/makefile,v retrieving revision 1.2 diff -p -u -r1.2 makefile --- makefile 1996/07/24 21:24:46 1.2 +++ makefile 2001/03/31 17:42:33 @@ -1,6 +1,7 @@ TOP=../.. SRC += access.c +SRC += append.c SRC += chdr.c SRC += gcwd.c SRC += getpid.c