mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 17:28:30 +00:00
Polyfill statfs() and fstatfs() on Windows
This commit is contained in:
parent
f7ee9d7d99
commit
c2211c9e63
16 changed files with 370 additions and 50 deletions
86
libc/calls/fstatfs-nt.c
Normal file
86
libc/calls/fstatfs-nt.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/statfs.h"
|
||||
#include "libc/calls/struct/statfs.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/fsinformationclass.h"
|
||||
#include "libc/nt/enum/status.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/ntdll.h"
|
||||
#include "libc/nt/struct/byhandlefileinformation.h"
|
||||
#include "libc/nt/struct/filefsfullsizeinformation.h"
|
||||
#include "libc/nt/struct/iostatusblock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tpenc.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_fstatfs_nt(int64_t handle, struct statfs *f) {
|
||||
uint64_t w;
|
||||
NtStatus st;
|
||||
uint32_t type;
|
||||
uint32_t h, i, j;
|
||||
struct NtIoStatusBlock io;
|
||||
struct NtFileFsFullSizeInformation fs;
|
||||
char16_t VolumeNameBuffer[261];
|
||||
uint32_t VolumeSerialNumber;
|
||||
uint32_t MaximumComponentLength;
|
||||
uint32_t FileSystemFlags;
|
||||
char16_t FileSystemNameBuffer[261];
|
||||
if (!GetVolumeInformationByHandle(
|
||||
handle, VolumeNameBuffer, ARRAYLEN(VolumeNameBuffer),
|
||||
&VolumeSerialNumber, &MaximumComponentLength, &FileSystemFlags,
|
||||
FileSystemNameBuffer, ARRAYLEN(FileSystemNameBuffer))) {
|
||||
return __winerr();
|
||||
}
|
||||
st = NtQueryVolumeInformationFile(handle, &io, &fs, sizeof(fs),
|
||||
kNtFileFsFullSizeInformation);
|
||||
if (!NtSuccess(st)) {
|
||||
if (st == kNtStatusDllNotFound) return enosys();
|
||||
return eio();
|
||||
}
|
||||
for (h = j = i = 0; FileSystemNameBuffer[i]; i++) {
|
||||
w = tpenc(FileSystemNameBuffer[i]);
|
||||
do {
|
||||
if (j + 1 < sizeof(f->f_fstypename)) {
|
||||
h = ((unsigned)(w & 255) + h) * 0x9e3779b1u;
|
||||
f->f_fstypename[j++] = w;
|
||||
}
|
||||
} while ((w >>= 8));
|
||||
}
|
||||
f->f_fstypename[j] = 0;
|
||||
f->f_type = h;
|
||||
f->f_fsid = VolumeSerialNumber;
|
||||
f->f_flags = FileSystemFlags;
|
||||
f->f_bsize = fs.BytesPerSector;
|
||||
f->f_bsize *= fs.SectorsPerAllocationUnit;
|
||||
f->f_frsize = f->f_bsize;
|
||||
f->f_blocks = fs.TotalAllocationUnits;
|
||||
f->f_bfree = fs.ActualAvailableAllocationUnits;
|
||||
f->f_bavail = fs.CallerAvailableAllocationUnits;
|
||||
f->f_files = INT64_MAX;
|
||||
f->f_ffree = INT64_MAX;
|
||||
f->f_namelen = 255;
|
||||
f->f_owner = 0;
|
||||
return 0;
|
||||
}
|
|
@ -17,10 +17,13 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/statfs-meta.internal.h"
|
||||
#include "libc/calls/struct/statfs.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns information about filesystem.
|
||||
|
@ -29,8 +32,14 @@ int fstatfs(int fd, struct statfs *sf) {
|
|||
int rc;
|
||||
union statfs_meta m;
|
||||
CheckLargeStackAllocation(&m, sizeof(m));
|
||||
if ((rc = sys_fstatfs(fd, &m)) != -1) {
|
||||
statfs2cosmo(sf, &m);
|
||||
if (!IsWindows()) {
|
||||
if ((rc = sys_fstatfs(fd, &m)) != -1) {
|
||||
statfs2cosmo(sf, &m);
|
||||
}
|
||||
} else if (__isfdopen(fd)) {
|
||||
rc = sys_fstatfs_nt(g_fds.p[fd].handle, sf);
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
STRACE("fstatfs(%d, [%s]) → %d% m", fd, DescribeStatfs(rc, sf));
|
||||
return rc;
|
||||
|
|
44
libc/calls/statfs-nt.c
Normal file
44
libc/calls/statfs-nt.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/statfs.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/filesharemode.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
|
||||
textwindows int sys_statfs_nt(const char *path, struct statfs *sf) {
|
||||
int rc;
|
||||
int64_t h;
|
||||
char16_t path16[PATH_MAX];
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
h = __fix_enotdir(
|
||||
CreateFile(path16, kNtFileGenericRead,
|
||||
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete,
|
||||
&kNtIsInheritable, kNtOpenExisting,
|
||||
kNtFileAttributeNormal | kNtFileFlagBackupSemantics, 0),
|
||||
path16);
|
||||
if (h == -1) return -1;
|
||||
rc = sys_fstatfs_nt(h, sf);
|
||||
CloseHandle(h);
|
||||
return rc;
|
||||
}
|
|
@ -17,10 +17,14 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/statfs-meta.internal.h"
|
||||
#include "libc/calls/struct/statfs.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
* Returns information about filesystem.
|
||||
|
@ -29,8 +33,12 @@ int statfs(const char *path, struct statfs *sf) {
|
|||
int rc;
|
||||
union statfs_meta m;
|
||||
CheckLargeStackAllocation(&m, sizeof(m));
|
||||
if ((rc = sys_statfs(path, &m)) != -1) {
|
||||
statfs2cosmo(sf, &m);
|
||||
if (!IsWindows()) {
|
||||
if ((rc = sys_statfs(path, &m)) != -1) {
|
||||
statfs2cosmo(sf, &m);
|
||||
}
|
||||
} else {
|
||||
rc = sys_statfs_nt(path, sf);
|
||||
}
|
||||
STRACE("statfs(%#s, [%s]) → %d% m", path, DescribeStatfs(rc, sf));
|
||||
return rc;
|
||||
|
|
|
@ -8,6 +8,8 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
int sys_statfs(const char *, union statfs_meta *);
|
||||
int sys_fstatfs(int, union statfs_meta *);
|
||||
int sys_fstatfs_nt(int64_t, struct statfs *);
|
||||
int sys_statfs_nt(const char *, struct statfs *);
|
||||
|
||||
const char *DescribeStatfs(char[300], int, const struct statfs *);
|
||||
#define DescribeStatfs(rc, sf) DescribeStatfs(alloca(300), rc, sf)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue