From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Sun, 11 Mar 2001 00:22:41 -0500 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: zero fill EOF gap patch Message-ID: <3AAAC551.12083.441287@localhost> X-mailer: Pegasus Mail for Win32 (v3.12c) Reply-To: djgpp-workers AT delorie DOT com Hello again, This is my first draft of a patch that zero fills the space between EOF and the current file pointer when the current file pointer > EOF. I left out the patch for llseek since it's just like the one for lseek. *** fd_props.h.orig Tue Mar 6 13:43:54 2001 --- fd_props.h Sat Mar 10 18:05:44 2001 *************** extern "C" { *** 15,20 **** --- 15,24 ---- /* Delete file when the last descriptor referencing it is closed. */ #define FILE_DESC_TEMPORARY 0x01 + /* Tell write and _write to test for file offset greater than EOF. If so, + they will fill the gap with zeroes. */ + #define FILE_DESC_FILL_TEST 0x02 + typedef struct fd_properties fd_properties; struct fd_properties *************** static __inline__ int __has_fd_propertie *** 37,42 **** --- 41,56 ---- return __fd_properties && __fd_properties[_fd]; } + static __inline__ void __set_fd_flags(int _fd, unsigned long _flags) + { + __fd_properties[_fd]->flags |= _flags; + } + + static __inline__ void __clear_fd_flags(int _fd, unsigned long _flags) + { + __fd_properties[_fd]->flags &= ~_flags; + } + #endif /* !_POSIX_SOURCE */ #endif /* !__STRICT_ANSI__ */ #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */ *** lseek.c.orig Sun Jun 28 13:29:36 1998 --- lseek.c Fri Mar 9 17:40:06 2001 *************** *** 1,3 **** --- 1,4 ---- + /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include *************** *** 7,12 **** --- 8,14 ---- #include #include #include + #include off_t lseek(int handle, off_t offset, int whence) *************** lseek(int handle, off_t offset, int when *** 31,35 **** --- 33,48 ---- errno = __doserr_to_errno(r.x.ax); return -1; } + + if (__has_fd_properties(handle)) + { + /* When seeking forward, set the EOF fill test flag. + When seeking to the start of file, clear the fill test flag. */ + if (offset > 0) + __set_fd_flags(handle, FILE_DESC_FILL_TEST); + else if (whence == SEEK_SET || whence == SEEK_END) + __clear_fd_flags(handle, FILE_DESC_FILL_TEST); + } + return (r.x.dx << 16) + r.x.ax; } *** _write.c.orig Fri Mar 2 11:41:54 2001 --- _write.c Sat Mar 10 18:13:36 2001 *************** *** 10,15 **** --- 10,18 ---- #include #include + #include + + int _write_fill_seek_area(int fd); int _write(int handle, const void* buffer, size_t count) *************** _write(int handle, const void* buffer, s *** 27,32 **** --- 30,42 ---- return rv; } + if (__has_fd_properties(handle) + && (__fd_properties[handle]->flags & FILE_DESC_FILL_TEST)) + { + if (_write_fill_seek_area(handle) < 0) + return -1; + } + tbsize = _go32_info_block.size_of_transfer_buffer; nput = 0; do { *************** _write(int handle, const void* buffer, s *** 58,60 **** --- 68,144 ---- return nput; } + + int + _write_fill_seek_area(int fd) + { + offset_t eof_off, cur_off, fill_count; + unsigned long tbsize, buf_size; + unsigned long i, write_size, out_count; + char *buffer; + __dpmi_regs r; + + __clear_fd_flags(fd, FILE_DESC_FILL_TEST); + + if (isatty(fd)) + return -1; + + eof_off = lfilelength (fd); + if (eof_off < 0) + return -1; + + cur_off = llseek (fd, 0, SEEK_CUR); + if (cur_off < 0) + return -1; + + if (cur_off <= eof_off) + return 0; + + /* Also quit when unable to seek to EOF. */ + if (llseek (fd, eof_off, SEEK_SET) == -1) + return -1; + + /* Clear once again because the llseek call above will + set the fill test flag. */ + __clear_fd_flags(fd, FILE_DESC_FILL_TEST); + + /* Fill the space. */ + tbsize = _go32_info_block.size_of_transfer_buffer; + fill_count = cur_off - eof_off; + + buf_size = (fill_count > tbsize) ? tbsize : fill_count; + + i = 0; + _farsetsel(_dos_ds); + while (i < buf_size) + { + _farnspokel(__tb + i, 0); + i += 4; + } + + out_count = 0; + do + { + r.x.ax = 0x4000; + r.x.bx = fd; + write_size = (fill_count > buf_size) ? buf_size : fill_count; + r.x.cx = write_size; + r.x.dx = __tb & 15; + r.x.ds = __tb / 16; + __dpmi_int (0x21, &r); + if (r.x.flags & 1) + { + errno =__doserr_to_errno (r.x.ax); + return -1; + } + fill_count -= r.x.ax; + out_count += r.x.ax; + } while (fill_count && (write_size == r.x.ax)); + + if (fill_count && out_count == 0) + { + errno = ENOSPC; + return -1; + } + } +