Mail Archives: djgpp-workers/2001/01/24/15:16:21
Hi,
The RBIL says that 0x71A6 returns information about a file handle including the file
size in two dwords. This patch changes filelength() to use that service when available.
If the value is too large, errno is set to EOVERFLOW. This patch also adds EOVERFLOW as
described in the single Unix spec and the LFS support document. I left out changes to
syserr2.c and syserr3.c since those changes are trivial. Not knowing if EOVERFLOW is
POSIX or not, so I placed it the non-ANSI, non-POSIX section.
Is EOVERFLOW part of POSIX or just the Unix spec?
This is one prelude to my patch for zero filling seek created space.
Index: filelen.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/filelen.c,v
retrieving revision 1.1
diff -c -p -r1.1 filelen.c
*** filelen.c 1995/03/29 20:55:56 1.1
--- filelen.c 2001/01/24 19:49:31
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/* This is file FILELEN.C */
/*
***************
*** 11,16 ****
--- 12,20 ----
#include <errno.h>
#include <dpmi.h>
#include <libc/dosio.h>
+ #include <go32.h>
+ #include <sys/farptr.h>
+ #include <dos.h>
long __filelength(int);
*************** __filelength(int fhandle)
*** 21,26 ****
--- 25,59 ----
unsigned short fpos_high, fpos_low;
long retval;
+ /* DOS 7 provides a way to get the file size directly.
+ Prefer it when available. */
+ if (_osmajor >= 7 && _osmajor < 10)
+ {
+ regs.x.ax = 0x71A6;
+ regs.x.bx = fhandle;
+ regs.x.ds = __tb >> 4;
+ regs.x.dx = 0;
+ regs.x.flags |= 1;
+ __dpmi_int (0x21, ®s);
+
+ if ((regs.x.flags & 1) == 0)
+ {
+ long retval_h;
+
+ /* Offset 0x24 contains the low 32-bits of the file size.
+ Offset 0x20 contains the high 32-bits. */
+ retval = _farpeekl(_dos_ds, __tb + 0x24);
+ retval_h = _farpeekl(_dos_ds, __tb + 0x20);
+
+ if (retval_h)
+ {
+ errno = EOVERFLOW;
+ return -1L;
+ }
+ return retval;
+ }
+ }
+
/* Remember the current file position, so we can return there
later. */
regs.x.ax = 0x4201; /* set pointer from current position */
Index: errno.h
===================================================================
RCS file: /cvs/djgpp/djgpp/include/errno.h,v
retrieving revision 1.3
diff -c -p -r1.3 errno.h
*** errno.h 2000/08/14 08:48:27 1.3
--- errno.h 2001/01/24 19:54:44
*************** extern int errno;
*** 56,61 ****
--- 56,62 ----
#define ENMFILE 38
#define ELOOP 39
+ #define EOVERFLOW 40
extern char * sys_errlist[];
extern int sys_nerr;
Index: errno.txh
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/errno/errno.txh,v
retrieving revision 1.5
diff -c -p -r1.5 errno.txh
*** errno.txh 2000/08/14 08:49:15 1.5
--- errno.txh 2001/01/24 19:56:02
*************** ELOOP -- Too many levels of symbolic lin
*** 243,248 ****
--- 243,253 ----
file handling function in library. Usually means encountered link loop
(link1 -> link2, link2 -> link1).
+ @item 40
+
+ EOVERFLOW -- Value too large. @code{filelength} can assign this to @code{errno}
+ when a file's length is larger than @code{LONG_MAX}.
+
@end table
Index: syserr1.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/string/syserr1.c,v
retrieving revision 1.2
diff -c -p -r1.2 syserr1.c
*** syserr1.c 2000/08/28 18:48:20 1.2
--- syserr1.c 2001/01/24 19:57:10
***************
*** 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 "syserr1.h"
*************** char __syserr36[] = "No such process (ES
*** 41,43 ****
--- 42,45 ----
char __syserr37[] = "Improper link (EXDEV)";
char __syserr38[] = "No more files (ENMFILE)";
char __syserr39[] = "Too many levels of symbolic links (ELOOP)";
+ char __syserr40[] = "Value too large (EOVERFLOW)";
- Raw text -