Date: Sun, 14 Sep 1997 20:08:50 +0300 (IDT) From: Eli Zaretskii To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: stat in 970831 Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk Some improvements for stat: diff -c src/libc/posix/sys/stat/stat.c~7 src/libc/posix/sys/stat/stat.c *** src/libc/posix/sys/stat/stat.c~7 Sun Aug 31 17:08:42 1997 --- src/libc/posix/sys/stat/stat.c Wed May 28 08:49:56 1997 *************** *** 112,117 **** --- 112,118 ---- #include #include #include + #include #include "xstat.h" *************** *** 384,389 **** --- 385,422 ---- return 0; } + int _ioctl_get_first_cluster(const char *); + + /* Get the number of the first cluster of PATHNAME using + the IOCTL call Int 21h/AX=440Dh/CX=0871h, if that call + is supported by the OS. Return the cluster number, or + a negative number if this service isn't supported. */ + + int + _ioctl_get_first_cluster(const char *pathname) + { + __dpmi_regs r; + + /* See if the IOCTL GetFirstCluster call is supported. */ + r.x.ax = 0x4411; /* query generic IOCTL capability by drive */ + r.h.bl = pathname[0] & 0x1f; /* drive number (1=A:) */ + r.x.cx = 0x871; + __dpmi_int(0x21, &r); + if ((r.x.flags & 1) == 0 && r.x.ax == 0) + { + r.x.ax = 0x440d; /* Generic IOCTL */ + r.x.cx = 0x0871; /* category code 08h, minor code 71h */ + r.x.bx = 1; /* pathname uses current OEM character set */ + r.x.ds = __tb >> 4; + r.x.dx = __tb & 0x0f; + _put_path(pathname); + __dpmi_int(0x21, &r); + if ((r.x.flags & 1) == 0) + return ( ((int)r.x.dx << 16) + r.x.ax ); + } + return -1; + } + static char blanks_8[] = " "; static int *************** *** 516,522 **** ( (unsigned short)ff_blk.ff_fdate << 16 ) + (unsigned short)ff_blk.ff_ftime; ! if ( (_djstat_flags & _STAT_INODE) == 0 ) { /* For networked drives, don't believe the starting cluster --- 549,557 ---- ( (unsigned short)ff_blk.ff_fdate << 16 ) + (unsigned short)ff_blk.ff_ftime; ! /* If the IOCTL GetFirstCluster call is available, try it first. */ ! if ( (_djstat_flags & _STAT_INODE) == 0 ! && (statbuf->st_ino = _ioctl_get_first_cluster(pathname)) <= 0) { /* For networked drives, don't believe the starting cluster *************** *** 533,540 **** is_remote_drive() fails is that some network redirector takes over IOCTL functions in an incompatible way, which means the drive is remote. QED. */ ! if (_is_remote_drive(drv_no) || ! (statbuf->st_ino = get_inode_from_sda(ff_blk.ff_name)) == 0) { _djstat_fail_bits |= _STFAIL_HASH; statbuf->st_ino = --- 568,576 ---- is_remote_drive() fails is that some network redirector takes over IOCTL functions in an incompatible way, which means the drive is remote. QED. */ ! if (statbuf->st_ino == 0 /* don't try SDA if IOCTL call succeeded */ ! || _is_remote_drive(drv_no) ! || (statbuf->st_ino = get_inode_from_sda(ff_blk.ff_name)) == 0) { _djstat_fail_bits |= _STFAIL_HASH; statbuf->st_ino = *************** *** 628,633 **** --- 664,670 ---- } else { + int e = errno; /* errno value from original FindFirst on PATHNAME */ int i = 0; int j = strlen (pathname) - 1; *************** *** 664,670 **** } else { ! /* FindFirst might set errno to ENMFILE; correct that. */ if (errno == ENMFILE) errno = ENOENT; return -1; --- 701,709 ---- } else { ! /* FindFirst on volume labels might set errno to ENMFILE or even ! to something more strange like EINVAl; correct that. */ ! errno = e; /* restore errno from the original FindFirst */ if (errno == ENMFILE) errno = ENOENT; return -1;