From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Thu, 25 Jan 2001 23:47:28 -0500 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: lfilelen patch Message-ID: <3A70BB10.7477.23FC70@localhost> X-mailer: Pegasus Mail for Win32 (v3.12c) Reply-To: djgpp-workers AT delorie DOT com Hi guys, This is essentially Peter Farley's patch for lfilelength but modifed to use 0x71a6 when available. The documentation of lfilelength is from filelength but modified to note the wider return type. Since lfilelength will be used by the enhanced fcntl, it will require an entry in stubs.h. *** /dev/null Thu Jan 25 23:35:14 2001 --- src/libc/posix/sys/stat/lfilelen.c Thu Jan 25 20:23:30 2001 *************** *** 0 **** --- 1,89 ---- + /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ + /* This is file LFILELEN.C */ + /* + * Copyright (c) 1994 Eli Zaretskii + * + * This software may be used freely so long as this copyright notice is + * left intact. There is no warranty on this software. + * + */ + + #include + #include + #include + #include + #include + #include + #include + + long long __lfilelength (int); + + long long + __lfilelength(int fhandle) + { + __dpmi_regs regs; + unsigned short fpos_high, fpos_low; + long long retval; + + /* DOS 7 provides a way to get the file size directly. + Prefer it when available. */ + if (_USE_LFN) + { + 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) + { + /* Offset 0x24 contains the low 32-bits of the file size. + Offset 0x20 contains the high 32-bits. */ + long retval_l = _farpeekl (_dos_ds, __tb + 0x24); + long retval_h = _farpeekl (_dos_ds, __tb + 0x20); + + retval = retval_l + retval_h * (1LL << 32); + return retval; + } + } + + /* Remember the current file position, so we can return there + later. */ + regs.x.ax = 0x4201; /* set pointer from current position */ + regs.x.bx = fhandle; + regs.x.cx = regs.x.dx = 0; /* move 0 bytes (i.e., stay put) */ + __dpmi_int(0x21, ®s); + if (regs.x.flags & 1) + { + errno = __doserr_to_errno(regs.x.ax); + return -1L; + } + fpos_high = regs.x.dx; /* save current position */ + fpos_low = regs.x.ax; + + regs.x.cx = regs.x.dx = 0; + regs.x.ax = 0x4202; /* set pointer 0 bytes from the end of file */ + __dpmi_int(0x21, ®s); + if (regs.x.flags & 1) + { + errno = __doserr_to_errno(regs.x.ax); + return -1L; + } + + /* The absolute byte offset returned in DX:AX is the file size. */ + retval = ( (long long)regs.x.dx << 16 ) + regs.x.ax; + + /* Leave things as we have found them. */ + regs.x.ax = 0x4200; /* set pointer from the beginning of file */ + regs.x.cx = fpos_high; + regs.x.dx = fpos_low; + __dpmi_int(0x21, ®s); + if (regs.x.flags & 1) + { + errno = __doserr_to_errno(regs.x.ax); + return -1L; + } + + return retval; + } *** /dev/null Thu Jan 25 23:35:17 2001 --- src/libc/posix/sys/stat/lfilelen.txh Thu Jan 25 23:35:12 2001 *************** *** 0 **** --- 1,35 ---- + @node lfilelength, io + @subheading Syntax + + @example + #include + + long long lfilelength(int fhandle); + @end example + + @subheading Description + + This function returns the size, in bytes, of a file whose handle is + specified in the argument @var{fhandle}. To get the handle of a file + opened by @ref{fopen} or @ref{freopen}, you can use @ref{fileno} macro. + + @subheading Return Value + + The size of the file in bytes, or (if any error occured) -1L and + @var{errno} set to a value describing the cause of the failure. + + The return value is of type long long which allows file sizes of + 2^63-2 bytes to be returned. Note that FAT16 limits files to near + 2^31 bytes and FAT32 limits files to 2^32-2 bytes. + + @subheading Portability + + @portability !ansi, !posix + + @subheading Example + + @example + printf("Size of file to which STDIN is redirected is %ld\n", + lfilelength(0)); + @end example +