From: Martin Str|mberg Message-Id: <200101302125.WAA29699@father.ludd.luth.se> Subject: Bug000323 To: djgpp-workers AT delorie DOT com (DJGPP-WORKERS) Date: Tue, 30 Jan 2001 22:25:49 +0100 (MET) 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 I consider this done. Comments? 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 2001/01/30 21:18:15 @@ -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 */ @@ -15,7 +16,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: src/libc/ansi/stdio/doprnt.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/doprnt.c,v retrieving revision 1.8 diff -p -u -r1.8 doprnt.c --- doprnt.c 1999/07/04 14:18:04 1.8 +++ doprnt.c 2001/01/30 21:18: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) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ @@ -109,6 +110,14 @@ _doprnt(const char *fmt0, va_list argp, } if ((fp->_flag & _IOWRT) == 0) return (EOF); + + if (fp->_flag & _IOAPPEND) + { + if ( llseek(fileno(fp), 0, SEEK_END) == -1 ) + { + return (EOF); + } + } fmt = fmt0; digs = "0123456789abcdef"; 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/01/30 21:18:19 @@ -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,26 @@ _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) - n = _write(fileno(f), base, rn); + { + 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; + n = 0; + } + else + { + n = _write(fileno(f), base, rn); + } + } + else + { + 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/01/30 21:18:19 @@ -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; @@ -56,7 +57,9 @@ fopen(const char *file, const char *mode return NULL; if (*mode == 'a') - lseek(fd, 0, SEEK_END); + { + f->_flag |= _IOAPPEND; + } f->_cnt = 0; f->_file = fd; 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/01/30 21:18:19 @@ -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; @@ -50,7 +51,9 @@ freopen(const char *file, const char *mo return NULL; if (*mode == 'a') - lseek(fd, 0, SEEK_END); + { + f->_flag |= _IOAPPEND; + } f->_cnt = 0; f->_file = fd; 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 2001/01/30 21:18:26 @@ -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 @@ -7,7 +8,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 +19,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) @@ -43,7 +44,7 @@ __file_handle_set(int fd, int mode) int oldcount = count; count = 255; - __file_handle_modes = (char *)malloc(count * sizeof(*__file_handle_modes)); + __file_handle_modes = malloc(count * sizeof(*__file_handle_modes)); memcpy(__file_handle_modes, init_file_handle_modes, sizeof(init_file_handle_modes)); memset(__file_handle_modes + oldcount, 0, (count-oldcount)*sizeof(__file_handle_modes[0])); Index: src/libc/posix/fcntl/fcntl.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/fcntl/fcntl.c,v retrieving revision 1.4 diff -p -u -r1.4 fcntl.c --- fcntl.c 1999/06/03 17:27:37 1.4 +++ fcntl.c 2001/01/30 21:18:27 @@ -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 */ @@ -82,7 +83,8 @@ fcntl(int fd, int cmd, ...) return -1; } case F_GETFL: - return 0; /* FIXME: should use the data in the SFT */ + return 0; /* FIXME: should use the data in the SFT, and the + O_APPEND flag in __file_handle_modes[] */ case F_SETFL: errno = ENOSYS; return -1; 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 2001/01/30 21:18: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 */ @@ -149,8 +150,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) + __file_handle_modes[fd] |= O_APPEND; 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 2001/01/30 21:18:29 @@ -1,3 +1,4 @@ +/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1997 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 */ @@ -36,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 2001/01/30 21:18:31 @@ -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; 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/01/30 21:18:32 @@ -1,6 +1,7 @@ TOP=../.. SRC += access.c +SRC += append.c SRC += chdr.c SRC += gcwd.c SRC += getpid.c