Mail Archives: djgpp-workers/2001/03/11/00:47:01
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 <libc/stubs.h>
***************
*** 7,12 ****
--- 8,14 ----
#include <dpmi.h>
#include <sys/fsext.h>
#include <libc/dosio.h>
+ #include <libc/fd_props.h>
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 <sys/fsext.h>
#include <libc/dosio.h>
+ #include <libc/fd_props.h>
+
+ 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;
+ }
+ }
+
- Raw text -