From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Wed, 24 Jan 2001 15:16:09 -0500 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: filelength and errno patch Message-ID: <3A6EF1B9.6453.3E8C83@localhost> X-mailer: Pegasus Mail for Win32 (v3.12c) Reply-To: djgpp-workers AT delorie DOT com 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 #include #include + #include + #include + #include 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)";