diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0218404c4..95f949315 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,6 +1,15 @@ +2003-05-25 Pierre Humblet + + * autoload.cc (GetDiskFreeSpaceEx): Add. + * syscalls.cc (statfs): Call full_path.root_dir() instead of + rootdir(full_path). Use GetDiskFreeSpaceEx when available and + report space available in addition to free space. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): + Do not call FindFirstFile for disk root directories. + 2003-05-24 Joe Buehler - * fhandler_process.cc (format_process_stat): use PagefileUsage + * fhandler_process.cc (format_process_stat): Use PagefileUsage instead of VirtualSize. (get_mem_values): Ditto. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 24527f590..71e7f9ead 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -502,6 +502,7 @@ LoadDLLfuncEx (CreateHardLinkA, 12, kernel32, 1) LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1) LoadDLLfuncEx2 (GetCompressedFileSizeA, 8, kernel32, 1, 0xffffffff) LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1) +LoadDLLfuncEx (GetDiskFreeSpaceEx, 16, kernel32, 1) LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1) LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1) LoadDLLfunc (IsProcessorFeaturePresent, 4, kernel32); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index bd235b35d..98d1531f4 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -109,39 +109,26 @@ fhandler_disk_file::fstat_by_name (struct __stat64 *buf, path_conv *pc) set_errno (ENOENT); res = -1; } + else if (pc->isdir () && strlen (*pc) <= strlen (pc->root_dir ())) + { + FILETIME ft = {}; + res = fstat_helper (buf, pc, ft, ft, ft, 0, 0); + } + else if ((handle = FindFirstFile (*pc, &local)) == INVALID_HANDLE_VALUE) + { + debug_printf ("FindFirstFile failed for '%s', %E", (char *) *pc); + __seterrno (); + res = -1; + } else { - char drivebuf[5]; - char *name; - if ((*pc)[3] != '\0' || !isalpha ((*pc)[0]) || (*pc)[1] != ':' || (*pc)[2] != '\\') - name = *pc; - else - { - /* FIXME: Does this work on empty disks? */ - drivebuf[0] = (*pc)[0]; - drivebuf[1] = (*pc)[1]; - drivebuf[2] = (*pc)[2]; - drivebuf[3] = '*'; - drivebuf[4] = '\0'; - name = drivebuf; - } - - if ((handle = FindFirstFile (name, &local)) == INVALID_HANDLE_VALUE) - { - debug_printf ("FindFirstFile failed for '%s', %E", name); - __seterrno (); - res = -1; - } - else - { - FindClose (handle); - res = fstat_helper (buf, pc, - local.ftCreationTime, - local.ftLastAccessTime, - local.ftLastWriteTime, - local.nFileSizeHigh, - local.nFileSizeLow); - } + FindClose (handle); + res = fstat_helper (buf, pc, + local.ftCreationTime, + local.ftLastAccessTime, + local.ftLastWriteTime, + local.nFileSizeHigh, + local.nFileSizeLow); } return res; } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 625e05957..3c3be8664 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1871,11 +1871,12 @@ statfs (const char *fname, struct statfs *sfs) } path_conv full_path (fname, PC_SYM_FOLLOW | PC_FULL); - char *root = rootdir (full_path); + + const char *root = full_path.root_dir(); syscall_printf ("statfs %s", root); - DWORD spc, bps, freec, totalc; + DWORD spc, bps, availc, freec, totalc; if (!GetDiskFreeSpace (root, &spc, &bps, &freec, &totalc)) { @@ -1883,6 +1884,17 @@ statfs (const char *fname, struct statfs *sfs) return -1; } + ULARGE_INTEGER availb, freeb, totalb; + + if (GetDiskFreeSpaceEx (root, &availb, &totalb, &freeb)) + { + availc = availb.QuadPart / (spc*bps); + totalc = totalb.QuadPart / (spc*bps); + freec = freeb.QuadPart / (spc*bps); + } + else + availc = freec; + DWORD vsn, maxlen, flags; if (!GetVolumeInformation (root, NULL, 0, &vsn, &maxlen, &flags, NULL, 0)) @@ -1893,7 +1905,8 @@ statfs (const char *fname, struct statfs *sfs) sfs->f_type = flags; sfs->f_bsize = spc*bps; sfs->f_blocks = totalc; - sfs->f_bfree = sfs->f_bavail = freec; + sfs->f_bavail = availc; + sfs->f_bfree = freec; sfs->f_files = -1; sfs->f_ffree = -1; sfs->f_fsid = vsn;