* fhandler.cc(fhandler_base::open): Open with READ_CONTROL only in
case of query_open flag set to query_read_control. Add case for new query_read_attributes flag. (fhandler_base::fstatvfs): New method. * fhandler.h (enum query_state): Add query_read_attributes flag. (class fhandler_base): Declare new virtual fstatvfs method. (class fhandler_socket): Ditto. (class fhandler_pipe): Ditto. (class fhandler_fifo): Ditto. (class fhandler_disk_file): Ditto. (class fhandler_virtual): Ditto. * fhandler_disk_file.cc (fhandler_base::fstat_fs): Open with query_read_attributes instead of query_read_control. (fhandler_disk_file::fstatvfs): New method. (fhandler_disk_file::facl): Open with query_read_attributes instead of query_read_control. * fhandler_fifo.cc (fhandler_fifo::fstatvfs): New method. * fhandler_socket.cc (fhandler_socket::fstatvfs): New method. (fhandler_socket::fchmod): Return with EBADF in the default case. (fhandler_socket::fchown): Ditto. (fhandler_socket::facl): Ditto. * fhandler_virtual.cc (fhandler_virtual::fstatvfs): Ditto. * ntdll.h (struct _FILE_FS_ATTRIBUTE_INFORMATION): Define. (struct _FILE_FS_FULL_SIZE_INFORMATION): Define. * pipe.cc (fhandler_pipe::fstatvfs): New method. * syscalls.cc (fstatvfs): Just call the fhandler's fstatvfs. (statvfs): Ditto. (fstatfs): Call fstatvfs. (statfs): Drop EFAULT handling.
This commit is contained in:
parent
7706962caf
commit
3323df7e0e
|
@ -1,3 +1,35 @@
|
||||||
|
2007-02-27 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.cc(fhandler_base::open): Open with READ_CONTROL only in
|
||||||
|
case of query_open flag set to query_read_control. Add case for
|
||||||
|
new query_read_attributes flag.
|
||||||
|
(fhandler_base::fstatvfs): New method.
|
||||||
|
* fhandler.h (enum query_state): Add query_read_attributes flag.
|
||||||
|
(class fhandler_base): Declare new virtual fstatvfs method.
|
||||||
|
(class fhandler_socket): Ditto.
|
||||||
|
(class fhandler_pipe): Ditto.
|
||||||
|
(class fhandler_fifo): Ditto.
|
||||||
|
(class fhandler_disk_file): Ditto.
|
||||||
|
(class fhandler_virtual): Ditto.
|
||||||
|
* fhandler_disk_file.cc (fhandler_base::fstat_fs): Open with
|
||||||
|
query_read_attributes instead of query_read_control.
|
||||||
|
(fhandler_disk_file::fstatvfs): New method.
|
||||||
|
(fhandler_disk_file::facl): Open with query_read_attributes instead of
|
||||||
|
query_read_control.
|
||||||
|
* fhandler_fifo.cc (fhandler_fifo::fstatvfs): New method.
|
||||||
|
* fhandler_socket.cc (fhandler_socket::fstatvfs): New method.
|
||||||
|
(fhandler_socket::fchmod): Return with EBADF in the default case.
|
||||||
|
(fhandler_socket::fchown): Ditto.
|
||||||
|
(fhandler_socket::facl): Ditto.
|
||||||
|
* fhandler_virtual.cc (fhandler_virtual::fstatvfs): Ditto.
|
||||||
|
* ntdll.h (struct _FILE_FS_ATTRIBUTE_INFORMATION): Define.
|
||||||
|
(struct _FILE_FS_FULL_SIZE_INFORMATION): Define.
|
||||||
|
* pipe.cc (fhandler_pipe::fstatvfs): New method.
|
||||||
|
* syscalls.cc (fstatvfs): Just call the fhandler's fstatvfs.
|
||||||
|
(statvfs): Ditto.
|
||||||
|
(fstatfs): Call fstatvfs.
|
||||||
|
(statfs): Drop EFAULT handling.
|
||||||
|
|
||||||
2007-02-26 Corinna Vinschen <corinna@vinschen.de>
|
2007-02-26 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler.cc (fhandler_base::fstat): Set all file times to arbitrary
|
* fhandler.cc (fhandler_base::fstat): Set all file times to arbitrary
|
||||||
|
|
|
@ -15,6 +15,7 @@ details. */
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/acl.h>
|
#include <sys/acl.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "perprocess.h"
|
#include "perprocess.h"
|
||||||
|
@ -486,6 +487,10 @@ fhandler_base::open (int flags, mode_t mode)
|
||||||
switch (query_open ())
|
switch (query_open ())
|
||||||
{
|
{
|
||||||
case query_read_control:
|
case query_read_control:
|
||||||
|
access = READ_CONTROL;
|
||||||
|
create_options = FILE_OPEN_FOR_BACKUP_INTENT;
|
||||||
|
break;
|
||||||
|
case query_read_attributes:
|
||||||
access = READ_CONTROL | FILE_READ_ATTRIBUTES;
|
access = READ_CONTROL | FILE_READ_ATTRIBUTES;
|
||||||
create_options = FILE_OPEN_FOR_BACKUP_INTENT;
|
create_options = FILE_OPEN_FOR_BACKUP_INTENT;
|
||||||
break;
|
break;
|
||||||
|
@ -1144,6 +1149,16 @@ fhandler_base::fstat (struct __stat64 *buf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
fhandler_base::fstatvfs (struct statvfs *sfs)
|
||||||
|
{
|
||||||
|
/* If we hit this base implementation, it's some device in /dev.
|
||||||
|
Just call statvfs on /dev for simplicity. */
|
||||||
|
path_conv pc ("/dev");
|
||||||
|
fhandler_disk_file fh (pc);
|
||||||
|
return fh.fstatvfs (sfs);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
|
fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,9 +82,10 @@ enum bg_check_types
|
||||||
enum query_state {
|
enum query_state {
|
||||||
no_query = 0,
|
no_query = 0,
|
||||||
query_read_control = 1,
|
query_read_control = 1,
|
||||||
query_stat_control = 2,
|
query_read_attributes = 2,
|
||||||
query_write_control = 3,
|
query_stat_control = 3,
|
||||||
query_write_attributes = 4
|
query_write_control = 4,
|
||||||
|
query_write_attributes = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_base
|
class fhandler_base
|
||||||
|
@ -276,6 +277,7 @@ class fhandler_base
|
||||||
__attribute__ ((regparm (3)));
|
__attribute__ ((regparm (3)));
|
||||||
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
virtual int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
int utimes_fs (const struct timeval *) __attribute__ ((regparm (2)));
|
int utimes_fs (const struct timeval *) __attribute__ ((regparm (2)));
|
||||||
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||||
|
@ -506,6 +508,7 @@ class fhandler_socket: public fhandler_base
|
||||||
char *get_sun_path () {return sun_path;}
|
char *get_sun_path () {return sun_path;}
|
||||||
|
|
||||||
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||||
int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
|
int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
|
||||||
|
@ -540,6 +543,7 @@ public:
|
||||||
}
|
}
|
||||||
int dup (fhandler_base *child);
|
int dup (fhandler_base *child);
|
||||||
int ioctl (unsigned int cmd, void *);
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
|
int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
|
||||||
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
|
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
|
||||||
void fixup_in_child ();
|
void fixup_in_child ();
|
||||||
|
@ -572,6 +576,7 @@ public:
|
||||||
void set_output_handle (HANDLE h) { output_handle = h; }
|
void set_output_handle (HANDLE h) { output_handle = h; }
|
||||||
void set_use ();
|
void set_use ();
|
||||||
int dup (fhandler_base *child);
|
int dup (fhandler_base *child);
|
||||||
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
bool is_slow () {return true;}
|
bool is_slow () {return true;}
|
||||||
void close_one_end ();
|
void close_one_end ();
|
||||||
};
|
};
|
||||||
|
@ -692,6 +697,7 @@ class fhandler_disk_file: public fhandler_base
|
||||||
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
|
int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
|
||||||
int __stdcall link (const char *) __attribute__ ((regparm (2)));
|
int __stdcall link (const char *) __attribute__ ((regparm (2)));
|
||||||
int __stdcall utimes (const struct timeval *) __attribute__ ((regparm (2)));
|
int __stdcall utimes (const struct timeval *) __attribute__ ((regparm (2)));
|
||||||
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
|
|
||||||
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
|
HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, _off64_t off);
|
||||||
int munmap (HANDLE h, caddr_t addr, size_t len);
|
int munmap (HANDLE h, caddr_t addr, size_t len);
|
||||||
|
@ -1228,6 +1234,7 @@ class fhandler_virtual : public fhandler_base
|
||||||
int open (int flags, mode_t mode = 0);
|
int open (int flags, mode_t mode = 0);
|
||||||
int close ();
|
int close ();
|
||||||
int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat (struct stat *buf) __attribute__ ((regparm (2)));
|
||||||
|
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
|
||||||
int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
|
int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
|
||||||
|
|
|
@ -14,6 +14,7 @@ details. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
#include <sys/acl.h>
|
#include <sys/acl.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "perprocess.h"
|
#include "perprocess.h"
|
||||||
|
@ -340,7 +341,7 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
||||||
/* If we couldn't open the file, try a query open with no permissions.
|
/* If we couldn't open the file, try a query open with no permissions.
|
||||||
This allows us to determine *some* things about the file, at least. */
|
This allows us to determine *some* things about the file, at least. */
|
||||||
pc.set_exec (0);
|
pc.set_exec (0);
|
||||||
query_open (query_read_control);
|
query_open (query_read_attributes);
|
||||||
oret = open_fs (open_flags, 0);
|
oret = open_fs (open_flags, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,6 +531,111 @@ fhandler_disk_file::fstat (struct __stat64 *buf)
|
||||||
return fstat_fs (buf);
|
return fstat_fs (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
||||||
|
{
|
||||||
|
int ret = -1, oret = 0;
|
||||||
|
NTSTATUS status;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
const size_t fvi_size = sizeof (FILE_FS_VOLUME_INFORMATION)
|
||||||
|
+ 256 * sizeof (WCHAR);
|
||||||
|
PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION)
|
||||||
|
alloca (fvi_size);
|
||||||
|
const size_t fai_size = sizeof (FILE_FS_ATTRIBUTE_INFORMATION)
|
||||||
|
+ 256 * sizeof (WCHAR);
|
||||||
|
PFILE_FS_ATTRIBUTE_INFORMATION pfai = (PFILE_FS_ATTRIBUTE_INFORMATION)
|
||||||
|
alloca (fai_size);
|
||||||
|
FILE_FS_FULL_SIZE_INFORMATION full_fsi;
|
||||||
|
FILE_FS_SIZE_INFORMATION fsi;
|
||||||
|
|
||||||
|
if (!get_io_handle ())
|
||||||
|
{
|
||||||
|
query_open (query_read_control);
|
||||||
|
oret = open_fs (O_RDONLY | O_BINARY, 0);
|
||||||
|
if (!oret)
|
||||||
|
{
|
||||||
|
/* Can't open file. Try again with rootdir. */
|
||||||
|
char root[CYG_MAX_PATH];
|
||||||
|
if (!rootdir (get_win32_name (), root))
|
||||||
|
goto out;
|
||||||
|
pc.check (root, PC_SYM_NOFOLLOW);
|
||||||
|
oret = open_fs (O_RDONLY | O_BINARY, 0);
|
||||||
|
if (!oret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get basic volume information. */
|
||||||
|
status = NtQueryVolumeInformationFile (get_handle (), &io, pfvi, fvi_size,
|
||||||
|
FileFsVolumeInformation);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
__seterrno_from_nt_status (status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
status = NtQueryVolumeInformationFile (get_handle (), &io, pfai, fai_size,
|
||||||
|
FileFsAttributeInformation);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
__seterrno_from_nt_status (status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
sfs->f_files = ULONG_MAX;
|
||||||
|
sfs->f_ffree = ULONG_MAX;
|
||||||
|
sfs->f_favail = ULONG_MAX;
|
||||||
|
sfs->f_fsid = pfvi->VolumeSerialNumber;
|
||||||
|
sfs->f_flag = pfai->FileSystemAttributes;
|
||||||
|
sfs->f_namemax = pfai->MaximumComponentNameLength;
|
||||||
|
/* Get allocation related information. Try to get "full" information
|
||||||
|
first, which is only available since W2K. If that fails, try to
|
||||||
|
retrieve normal allocation information. */
|
||||||
|
status = NtQueryVolumeInformationFile (get_handle (), &io, &full_fsi,
|
||||||
|
sizeof full_fsi,
|
||||||
|
FileFsFullSizeInformation);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
sfs->f_bsize = full_fsi.BytesPerSector * full_fsi.SectorsPerAllocationUnit;
|
||||||
|
sfs->f_frsize = sfs->f_bsize;
|
||||||
|
sfs->f_blocks = full_fsi.TotalAllocationUnits.LowPart;
|
||||||
|
sfs->f_bfree = full_fsi.ActualAvailableAllocationUnits.LowPart;
|
||||||
|
sfs->f_bavail = full_fsi.CallerAvailableAllocationUnits.LowPart;
|
||||||
|
if (sfs->f_bfree > sfs->f_bavail)
|
||||||
|
{
|
||||||
|
/* Quotas active. We can't trust TotalAllocationUnits. */
|
||||||
|
NTFS_VOLUME_DATA_BUFFER nvdb;
|
||||||
|
DWORD bytes;
|
||||||
|
|
||||||
|
if (!DeviceIoControl (get_handle (), FSCTL_GET_NTFS_VOLUME_DATA, NULL,
|
||||||
|
0, &nvdb, sizeof nvdb, &bytes, NULL))
|
||||||
|
debug_printf ("DeviceIoControl (%s) failed, %E", get_name ());
|
||||||
|
else
|
||||||
|
sfs->f_blocks = nvdb.TotalClusters.QuadPart;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = NtQueryVolumeInformationFile (get_handle (), &io, &fsi,
|
||||||
|
sizeof fsi, FileFsSizeInformation);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
__seterrno_from_nt_status (status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
sfs->f_bsize = fsi.BytesPerSector * fsi.SectorsPerAllocationUnit;
|
||||||
|
sfs->f_frsize = sfs->f_bsize;
|
||||||
|
sfs->f_blocks = fsi.TotalAllocationUnits.LowPart;
|
||||||
|
sfs->f_bfree = fsi.AvailableAllocationUnits.LowPart;
|
||||||
|
sfs->f_bavail = sfs->f_bfree;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
if (oret)
|
||||||
|
close_fs ();
|
||||||
|
syscall_printf ("%d = fstatvfs (%s, %p)", ret, get_name (), sfs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_disk_file::fchmod (mode_t mode)
|
fhandler_disk_file::fchmod (mode_t mode)
|
||||||
{
|
{
|
||||||
|
@ -653,7 +759,7 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
||||||
{
|
{
|
||||||
if (!get_io_handle ())
|
if (!get_io_handle ())
|
||||||
{
|
{
|
||||||
query_open (query_read_control);
|
query_open (query_read_attributes);
|
||||||
if (!(oret = open (O_BINARY, 0)))
|
if (!(oret = open (O_BINARY, 0)))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -687,7 +793,7 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
||||||
{
|
{
|
||||||
if (!get_io_handle ())
|
if (!get_io_handle ())
|
||||||
{
|
{
|
||||||
query_open (cmd == SETACL ? query_write_control : query_read_control);
|
query_open (cmd == SETACL ? query_write_control : query_read_attributes);
|
||||||
if (!(oret = open (O_BINARY, 0)))
|
if (!(oret = open (O_BINARY, 0)))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
|
/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
|
||||||
|
|
||||||
Copyright 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
|
Copyright 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "perprocess.h"
|
#include "perprocess.h"
|
||||||
|
@ -238,3 +239,18 @@ fhandler_fifo::dup (fhandler_base *child)
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
fhandler_fifo::fstatvfs (struct statvfs *sfs)
|
||||||
|
{
|
||||||
|
/* Call statvfs on parent dir. */
|
||||||
|
char *c, dir[CYG_MAX_PATH];
|
||||||
|
strcpy (dir, get_name ());
|
||||||
|
if ((c = strrchr (dir, '/')))
|
||||||
|
{
|
||||||
|
*c = '\0';
|
||||||
|
return statvfs (dir, sfs);
|
||||||
|
}
|
||||||
|
set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "wininfo.h"
|
#include "wininfo.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/acl.h>
|
#include <sys/acl.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "cygwin/in6.h"
|
#include "cygwin/in6.h"
|
||||||
|
|
||||||
|
@ -666,6 +667,19 @@ fhandler_socket::fstat (struct __stat64 *buf)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
fhandler_socket::fstatvfs (struct statvfs *sfs)
|
||||||
|
{
|
||||||
|
if (get_device () == FH_UNIX)
|
||||||
|
{
|
||||||
|
fhandler_disk_file fh (pc);
|
||||||
|
fh.get_device () = FH_FS;
|
||||||
|
return fh.fstatvfs (sfs);
|
||||||
|
}
|
||||||
|
set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket::fchmod (mode_t mode)
|
fhandler_socket::fchmod (mode_t mode)
|
||||||
{
|
{
|
||||||
|
@ -677,7 +691,8 @@ fhandler_socket::fchmod (mode_t mode)
|
||||||
SetFileAttributes (pc, GetFileAttributes (pc) | FILE_ATTRIBUTE_SYSTEM);
|
SetFileAttributes (pc, GetFileAttributes (pc) | FILE_ATTRIBUTE_SYSTEM);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -688,7 +703,8 @@ fhandler_socket::fchown (__uid32_t uid, __gid32_t gid)
|
||||||
fhandler_disk_file fh (pc);
|
fhandler_disk_file fh (pc);
|
||||||
return fh.fchown (uid, gid);
|
return fh.fchown (uid, gid);
|
||||||
}
|
}
|
||||||
return 0;
|
set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -699,7 +715,8 @@ fhandler_socket::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
||||||
fhandler_disk_file fh (pc);
|
fhandler_disk_file fh (pc);
|
||||||
return fh.facl (cmd, nentries, aclbufp);
|
return fh.facl (cmd, nentries, aclbufp);
|
||||||
}
|
}
|
||||||
return fhandler_base::facl (cmd, nentries, aclbufp);
|
set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* fhandler_virtual.cc: base fhandler class for virtual filesystems
|
/* fhandler_virtual.cc: base fhandler class for virtual filesystems
|
||||||
|
|
||||||
Copyright 2002, 2003, 2004, 2005 Red Hat, Inc.
|
Copyright 2002, 2003, 2004, 2005, 2007 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ details. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
#include <sys/acl.h>
|
#include <sys/acl.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
@ -261,3 +262,14 @@ fhandler_virtual::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
fhandler_virtual::fstatvfs (struct statvfs *sfs)
|
||||||
|
{
|
||||||
|
/* Virtual file system. Just return an empty buffer with a few values
|
||||||
|
set to something useful. Just as on Linux. */
|
||||||
|
memset (sfs, 0, sizeof (*sfs));
|
||||||
|
sfs->f_bsize = sfs->f_frsize = 4096;
|
||||||
|
sfs->f_namemax = NAME_MAX;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -590,6 +590,14 @@ typedef struct _FILE_COMPRESSION_INFORMATION
|
||||||
UCHAR ClusterSizeShift;
|
UCHAR ClusterSizeShift;
|
||||||
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;
|
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG FileSystemAttributes;
|
||||||
|
ULONG MaximumComponentNameLength;
|
||||||
|
ULONG FileSystemNameLength;
|
||||||
|
WCHAR FileSystemName[1];
|
||||||
|
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
|
||||||
|
|
||||||
typedef struct _FILE_FS_VOLUME_INFORMATION
|
typedef struct _FILE_FS_VOLUME_INFORMATION
|
||||||
{
|
{
|
||||||
LARGE_INTEGER VolumeCreationTime;
|
LARGE_INTEGER VolumeCreationTime;
|
||||||
|
@ -607,6 +615,15 @@ typedef struct _FILE_FS_SIZE_INFORMATION
|
||||||
ULONG BytesPerSector;
|
ULONG BytesPerSector;
|
||||||
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
|
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_FS_FULL_SIZE_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER TotalAllocationUnits;
|
||||||
|
LARGE_INTEGER CallerAvailableAllocationUnits;
|
||||||
|
LARGE_INTEGER ActualAvailableAllocationUnits;
|
||||||
|
ULONG SectorsPerAllocationUnit;
|
||||||
|
ULONG BytesPerSector;
|
||||||
|
} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
|
||||||
|
|
||||||
typedef enum _FSINFOCLASS {
|
typedef enum _FSINFOCLASS {
|
||||||
FileFsVolumeInformation = 1,
|
FileFsVolumeInformation = 1,
|
||||||
FileFsLabelInformation,
|
FileFsLabelInformation,
|
||||||
|
|
|
@ -451,6 +451,13 @@ fhandler_pipe::ioctl (unsigned int cmd, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __stdcall
|
||||||
|
fhandler_pipe::fstatvfs (struct statvfs *sfs)
|
||||||
|
{
|
||||||
|
set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#define DEFAULT_PIPEBUFSIZE (16 * PIPE_BUF)
|
#define DEFAULT_PIPEBUFSIZE (16 * PIPE_BUF)
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
|
|
|
@ -1841,113 +1841,56 @@ get_osfhandle (int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
statvfs (const char *fname, struct statvfs *sfs)
|
fstatvfs (int fd, struct statvfs *sfs)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
|
||||||
char root[CYG_MAX_PATH];
|
|
||||||
|
|
||||||
myfault efault;
|
myfault efault;
|
||||||
if (efault.faulted (EFAULT))
|
if (efault.faulted (EFAULT))
|
||||||
return -1;
|
return -1;
|
||||||
if (!*fname)
|
|
||||||
{
|
|
||||||
set_errno (ENOENT);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
syscall_printf ("statfs %s", fname);
|
|
||||||
|
|
||||||
if (!sfs)
|
|
||||||
{
|
|
||||||
set_errno (EFAULT);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_conv full_path (fname, PC_SYM_FOLLOW);
|
|
||||||
if (!full_path.rootdir (root))
|
|
||||||
{
|
|
||||||
set_errno (ENOTDIR);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULARGE_INTEGER availb, freeb, totalb;
|
|
||||||
DWORD spc, bps, availc, freec, totalc, vsn, maxlen, flags;
|
|
||||||
BOOL status, statusex;
|
|
||||||
|
|
||||||
/* GetDiskFreeSpaceEx must be called before GetDiskFreeSpace on
|
|
||||||
WinME, to avoid the MS KB 314417 bug */
|
|
||||||
statusex = GetDiskFreeSpaceEx (root, &availb, &totalb, &freeb);
|
|
||||||
status = GetDiskFreeSpace (root, &spc, &bps, &freec, &totalc);
|
|
||||||
if (status)
|
|
||||||
{
|
|
||||||
if (statusex)
|
|
||||||
{
|
|
||||||
availc = availb.QuadPart / (spc*bps);
|
|
||||||
totalc = totalb.QuadPart / (spc*bps);
|
|
||||||
freec = freeb.QuadPart / (spc*bps);
|
|
||||||
if (freec > availc)
|
|
||||||
{
|
|
||||||
/* Quotas active. We can't trust totalc. */
|
|
||||||
HANDLE hdl = CreateFile (full_path, READ_CONTROL,
|
|
||||||
FILE_SHARE_VALID_FLAGS, &sec_none_nih,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
|
||||||
if (hdl == INVALID_HANDLE_VALUE)
|
|
||||||
debug_printf ("CreateFile (%s) failed, %E", (char *) full_path);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NTFS_VOLUME_DATA_BUFFER nvdb;
|
|
||||||
DWORD bytes;
|
|
||||||
if (!DeviceIoControl (hdl, FSCTL_GET_NTFS_VOLUME_DATA, NULL,
|
|
||||||
0, &nvdb, sizeof nvdb, &bytes, NULL))
|
|
||||||
debug_printf ("DeviceIoControl (%s) failed, %E", (char *) full_path);
|
|
||||||
else
|
|
||||||
totalc = nvdb.TotalClusters.QuadPart;
|
|
||||||
CloseHandle (hdl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
availc = freec;
|
|
||||||
if (GetVolumeInformation (root, NULL, 0, &vsn, &maxlen, &flags, NULL, 0))
|
|
||||||
{
|
|
||||||
sfs->f_bsize = spc*bps;
|
|
||||||
sfs->f_frsize = spc*bps;
|
|
||||||
sfs->f_blocks = totalc;
|
|
||||||
sfs->f_bfree = freec;
|
|
||||||
sfs->f_bavail = availc;
|
|
||||||
sfs->f_files = ULONG_MAX;
|
|
||||||
sfs->f_ffree = ULONG_MAX;
|
|
||||||
sfs->f_favail = ULONG_MAX;
|
|
||||||
sfs->f_fsid = vsn;
|
|
||||||
sfs->f_flag = flags;
|
|
||||||
sfs->f_namemax = maxlen;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret)
|
|
||||||
__seterrno ();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int
|
|
||||||
fstatvfs (int fd, struct statvfs *sfs)
|
|
||||||
{
|
|
||||||
cygheap_fdget cfd (fd);
|
cygheap_fdget cfd (fd);
|
||||||
if (cfd < 0)
|
if (cfd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return statvfs (cfd->get_name (), sfs);
|
return cfd->fstatvfs (sfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
statfs (const char *fname, struct statfs *sfs)
|
statvfs (const char *name, struct statvfs *sfs)
|
||||||
{
|
{
|
||||||
|
int res = -1;
|
||||||
|
fhandler_base *fh = NULL;
|
||||||
|
|
||||||
myfault efault;
|
myfault efault;
|
||||||
if (efault.faulted (EFAULT))
|
if (efault.faulted (EFAULT))
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
|
if (!(fh = build_fh_name (name, NULL, PC_SYM_FOLLOW, stat_suffixes)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (fh->error ())
|
||||||
|
{
|
||||||
|
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||||
|
set_errno (fh->error ());
|
||||||
|
}
|
||||||
|
else if (fh->exists ())
|
||||||
|
{
|
||||||
|
debug_printf ("(%s, %p), file_attributes %d", name, sfs, (DWORD) *fh);
|
||||||
|
res = fh->fstatvfs (sfs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
set_errno (ENOENT);
|
||||||
|
|
||||||
|
delete fh;
|
||||||
|
error:
|
||||||
|
MALLOC_CHECK;
|
||||||
|
syscall_printf ("%d = (%s, %p)", res, name, sfs);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int
|
||||||
|
fstatfs (int fd, struct statfs *sfs)
|
||||||
|
{
|
||||||
struct statvfs vfs;
|
struct statvfs vfs;
|
||||||
int ret = statvfs (fname, &vfs);
|
int ret = fstatvfs (fd, &vfs);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
sfs->f_type = vfs.f_flag;
|
sfs->f_type = vfs.f_flag;
|
||||||
|
@ -1964,12 +1907,23 @@ statfs (const char *fname, struct statfs *sfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
fstatfs (int fd, struct statfs *sfs)
|
statfs (const char *fname, struct statfs *sfs)
|
||||||
{
|
{
|
||||||
cygheap_fdget cfd (fd);
|
struct statvfs vfs;
|
||||||
if (cfd < 0)
|
int ret = statvfs (fname, &vfs);
|
||||||
return -1;
|
if (!ret)
|
||||||
return statfs (cfd->get_name (), sfs);
|
{
|
||||||
|
sfs->f_type = vfs.f_flag;
|
||||||
|
sfs->f_bsize = vfs.f_bsize;
|
||||||
|
sfs->f_blocks = vfs.f_blocks;
|
||||||
|
sfs->f_bavail = vfs.f_bavail;
|
||||||
|
sfs->f_bfree = vfs.f_bfree;
|
||||||
|
sfs->f_files = -1;
|
||||||
|
sfs->f_ffree = -1;
|
||||||
|
sfs->f_fsid = vfs.f_fsid;
|
||||||
|
sfs->f_namelen = vfs.f_namemax;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setpgid: POSIX 4.3.3.1 */
|
/* setpgid: POSIX 4.3.3.1 */
|
||||||
|
|
Loading…
Reference in New Issue