mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +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
|
@ -8,8 +8,10 @@
|
|||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/struct/statfs.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/nt/enum/statfs.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/st.h"
|
||||
|
||||
|
@ -44,41 +46,106 @@ dontinline void ShowIt(const char *path) {
|
|||
"maximum length of filenames");
|
||||
|
||||
printf("f_flags = %#x", sf.f_flags);
|
||||
if (ST_RDONLY && (sf.f_flags & ST_RDONLY)) {
|
||||
printf(" ST_RDONLY");
|
||||
}
|
||||
if (ST_NOSUID && (sf.f_flags & ST_NOSUID)) {
|
||||
printf(" ST_NOSUID");
|
||||
}
|
||||
if (ST_NODEV && (sf.f_flags & ST_NODEV)) {
|
||||
printf(" ST_NODEV");
|
||||
}
|
||||
if (ST_NOEXEC && (sf.f_flags & ST_NOEXEC)) {
|
||||
printf(" ST_NOEXEC");
|
||||
}
|
||||
if (ST_SYNCHRONOUS && (sf.f_flags & ST_SYNCHRONOUS)) {
|
||||
printf(" ST_SYNCHRONOUS");
|
||||
}
|
||||
if (ST_MANDLOCK && (sf.f_flags & ST_MANDLOCK)) {
|
||||
printf(" ST_MANDLOCK");
|
||||
}
|
||||
if (ST_WRITE && (sf.f_flags & ST_WRITE)) {
|
||||
printf(" ST_WRITE");
|
||||
}
|
||||
if (ST_APPEND && (sf.f_flags & ST_APPEND)) {
|
||||
printf(" ST_APPEND");
|
||||
}
|
||||
if (ST_IMMUTABLE && (sf.f_flags & ST_IMMUTABLE)) {
|
||||
printf(" ST_IMMUTABLE");
|
||||
}
|
||||
if (ST_NOATIME && (sf.f_flags & ST_NOATIME)) {
|
||||
printf(" ST_NOATIME");
|
||||
}
|
||||
if (ST_NODIRATIME && (sf.f_flags & ST_NODIRATIME)) {
|
||||
printf(" ST_NODIRATIME");
|
||||
}
|
||||
if (ST_RELATIME && (sf.f_flags & ST_RELATIME)) {
|
||||
printf(" ST_RELATIME");
|
||||
|
||||
if (!IsWindows()) {
|
||||
if (ST_RDONLY && (sf.f_flags & ST_RDONLY)) {
|
||||
printf(" ST_RDONLY");
|
||||
}
|
||||
if (ST_NOSUID && (sf.f_flags & ST_NOSUID)) {
|
||||
printf(" ST_NOSUID");
|
||||
}
|
||||
if (ST_NODEV && (sf.f_flags & ST_NODEV)) {
|
||||
printf(" ST_NODEV");
|
||||
}
|
||||
if (ST_NOEXEC && (sf.f_flags & ST_NOEXEC)) {
|
||||
printf(" ST_NOEXEC");
|
||||
}
|
||||
if (ST_SYNCHRONOUS && (sf.f_flags & ST_SYNCHRONOUS)) {
|
||||
printf(" ST_SYNCHRONOUS");
|
||||
}
|
||||
if (ST_MANDLOCK && (sf.f_flags & ST_MANDLOCK)) {
|
||||
printf(" ST_MANDLOCK");
|
||||
}
|
||||
if (ST_WRITE && (sf.f_flags & ST_WRITE)) {
|
||||
printf(" ST_WRITE");
|
||||
}
|
||||
if (ST_APPEND && (sf.f_flags & ST_APPEND)) {
|
||||
printf(" ST_APPEND");
|
||||
}
|
||||
if (ST_IMMUTABLE && (sf.f_flags & ST_IMMUTABLE)) {
|
||||
printf(" ST_IMMUTABLE");
|
||||
}
|
||||
if (ST_NOATIME && (sf.f_flags & ST_NOATIME)) {
|
||||
printf(" ST_NOATIME");
|
||||
}
|
||||
if (ST_NODIRATIME && (sf.f_flags & ST_NODIRATIME)) {
|
||||
printf(" ST_NODIRATIME");
|
||||
}
|
||||
if (ST_RELATIME && (sf.f_flags & ST_RELATIME)) {
|
||||
printf(" ST_RELATIME");
|
||||
}
|
||||
|
||||
} else {
|
||||
if (sf.f_flags & kNtFileCasePreservedNames) {
|
||||
printf(" CasePreservedNames");
|
||||
}
|
||||
if (sf.f_flags & kNtFileCaseSensitiveSearch) {
|
||||
printf(" CaseSensitiveSearch");
|
||||
}
|
||||
if (sf.f_flags & kNtFileFileCompression) {
|
||||
printf(" FileCompression");
|
||||
}
|
||||
if (sf.f_flags & kNtFileNamedStreams) {
|
||||
printf(" NamedStreams");
|
||||
}
|
||||
if (sf.f_flags & kNtFilePersistentAcls) {
|
||||
printf(" PersistentAcls");
|
||||
}
|
||||
if (sf.f_flags & kNtFileReadOnlyVolume) {
|
||||
printf(" ReadOnlyVolume");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSequentialWriteOnce) {
|
||||
printf(" SequentialWriteOnce");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsEncryption) {
|
||||
printf(" SupportsEncryption");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsExtendedAttributes) {
|
||||
printf(" SupportsExtendedAttributes");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsHardLinks) {
|
||||
printf(" SupportsHardLinks");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsObjectIds) {
|
||||
printf(" SupportsObjectIds");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsOpenByFileId) {
|
||||
printf(" SupportsOpenByFileId");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsReparsePoints) {
|
||||
printf(" SupportsReparsePoints");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsSparseFiles) {
|
||||
printf(" SupportsSparseFiles");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsTransactions) {
|
||||
printf(" SupportsTransactions");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsUsnJournal) {
|
||||
printf(" SupportsUsnJournal");
|
||||
}
|
||||
if (sf.f_flags & kNtFileUnicodeOnDisk) {
|
||||
printf(" UnicodeOnDisk");
|
||||
}
|
||||
if (sf.f_flags & kNtFileVolumeIsCompressed) {
|
||||
printf(" VolumeIsCompressed");
|
||||
}
|
||||
if (sf.f_flags & kNtFileVolumeQuotas) {
|
||||
printf(" VolumeQuotas");
|
||||
}
|
||||
if (sf.f_flags & kNtFileSupportsBlockRefcounting) {
|
||||
printf(" SupportsBlockRefcounting");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
|
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)
|
||||
|
|
29
libc/nt/enum/statfs.h
Normal file
29
libc/nt/enum/statfs.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_STATFS_H_
|
||||
#define COSMOPOLITAN_LIBC_NT_ENUM_STATFS_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define kNtFileCasePreservedNames 0x00000002
|
||||
#define kNtFileCaseSensitiveSearch 0x00000001
|
||||
#define kNtFileFileCompression 0x00000010
|
||||
#define kNtFileNamedStreams 0x00040000
|
||||
#define kNtFilePersistentAcls 0x00000008
|
||||
#define kNtFileReadOnlyVolume 0x00080000 /* ST_RDONLY */
|
||||
#define kNtFileSequentialWriteOnce 0x00100000
|
||||
#define kNtFileSupportsEncryption 0x00020000
|
||||
#define kNtFileSupportsExtendedAttributes 0x00800000
|
||||
#define kNtFileSupportsHardLinks 0x00400000
|
||||
#define kNtFileSupportsObjectIds 0x00010000
|
||||
#define kNtFileSupportsOpenByFileId 0x01000000
|
||||
#define kNtFileSupportsReparsePoints 0x00000080
|
||||
#define kNtFileSupportsSparseFiles 0x00000040
|
||||
#define kNtFileSupportsTransactions 0x00200000
|
||||
#define kNtFileSupportsUsnJournal 0x02000000
|
||||
#define kNtFileUnicodeOnDisk 0x00000004
|
||||
#define kNtFileVolumeIsCompressed 0x00008000
|
||||
#define kNtFileVolumeQuotas 0x00000020
|
||||
#define kNtFileSupportsBlockRefcounting 0x08000000
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_STATFS_H_ */
|
|
@ -219,6 +219,15 @@ bool32 GetVolumePathName(const char16_t *lpszFileName,
|
|||
char16_t *lpszVolumePathName,
|
||||
uint32_t cchBufferLength);
|
||||
|
||||
bool32 GetVolumeInformationByHandle(int64_t hFile,
|
||||
char16_t *opt_out_lpVolumeNameBuffer,
|
||||
uint32_t nVolumeNameSize,
|
||||
uint32_t *opt_out_lpVolumeSerialNumber,
|
||||
uint32_t *opt_out_lpMaximumComponentLength,
|
||||
uint32_t *opt_out_lpFileSystemFlags,
|
||||
char16_t *opt_out_lpFileSystemNameBuffer,
|
||||
uint32_t nFileSystemNameSize);
|
||||
|
||||
#if ShouldUseMsabiAttribute()
|
||||
#include "libc/nt/thunk/files.inc"
|
||||
#endif /* ShouldUseMsabiAttribute() */
|
||||
|
|
|
@ -1,2 +1,12 @@
|
|||
.include "o/libc/nt/codegen.inc"
|
||||
.imp kernel32,__imp_GetVolumeInformationByHandleW,GetVolumeInformationByHandleW,0
|
||||
|
||||
.text.windows
|
||||
GetVolumeInformationByHandle:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
mov __imp_GetVolumeInformationByHandleW(%rip),%rax
|
||||
jmp __sysv2nt8
|
||||
.endfn GetVolumeInformationByHandle,globl
|
||||
.previous
|
||||
|
|
|
@ -580,7 +580,7 @@ imp 'GetVDMCurrentDirectories' GetVDMCurrentDirectories kernel32 798
|
|||
imp 'GetVersion' GetVersion kernel32 0
|
||||
imp 'GetVersionEx' GetVersionExW kernel32 0 1
|
||||
imp 'GetVolumeInformation' GetVolumeInformationW kernel32 0
|
||||
imp 'GetVolumeInformationByHandle' GetVolumeInformationByHandleW kernel32 0
|
||||
imp 'GetVolumeInformationByHandle' GetVolumeInformationByHandleW kernel32 0 8
|
||||
imp 'GetVolumeNameForVolumeMountPoint' GetVolumeNameForVolumeMountPointW kernel32 0
|
||||
imp 'GetVolumePathName' GetVolumePathNameW kernel32 0 3
|
||||
imp 'GetVolumePathNamesForVolumeName' GetVolumePathNamesForVolumeNameW kernel32 0
|
||||
|
|
16
libc/nt/struct/filefsfullsizeinformation.h
Normal file
16
libc/nt/struct/filefsfullsizeinformation.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_FILEFSFULLSIZEINFORMATION_H_
|
||||
#define COSMOPOLITAN_LIBC_NT_STRUCT_FILEFSFULLSIZEINFORMATION_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct NtFileFsFullSizeInformation {
|
||||
int64_t TotalAllocationUnits;
|
||||
int64_t CallerAvailableAllocationUnits;
|
||||
int64_t ActualAvailableAllocationUnits;
|
||||
uint32_t SectorsPerAllocationUnit;
|
||||
uint32_t BytesPerSector;
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_FILEFSFULLSIZEINFORMATION_H_ */
|
|
@ -297,7 +297,6 @@ DIR *opendir(const char *name) {
|
|||
} else {
|
||||
res = opendir_nt(name);
|
||||
}
|
||||
STRACE("opendir(%#s) → %p% m", name, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -317,7 +316,6 @@ DIR *fdopendir(int fd) {
|
|||
} else {
|
||||
dir = fdopendir_nt(fd);
|
||||
}
|
||||
STRACE("fdopendir(%d) → %p% m", fd, dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
@ -443,7 +441,6 @@ int closedir(DIR *dir) {
|
|||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
STRACE("closedir(%p) → %d% m", dir, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -454,7 +451,6 @@ long telldir(DIR *dir) {
|
|||
long rc;
|
||||
_lockdir(dir);
|
||||
rc = dir->tell;
|
||||
STRACE("telldir(%p) → %ld", dir, rc);
|
||||
_unlockdir(dir);
|
||||
return rc;
|
||||
}
|
||||
|
@ -472,7 +468,6 @@ int dirfd(DIR *dir) {
|
|||
} else {
|
||||
rc = dir->fd;
|
||||
}
|
||||
STRACE("dirfd(%p) → %d% m", dir, rc);
|
||||
_unlockdir(dir);
|
||||
return rc;
|
||||
}
|
||||
|
@ -499,7 +494,6 @@ void rewinddir(DIR *dir) {
|
|||
dir->isdone = true;
|
||||
}
|
||||
}
|
||||
STRACE("rewinddir(%p)", dir);
|
||||
_unlockdir(dir);
|
||||
}
|
||||
|
||||
|
@ -521,6 +515,5 @@ void seekdir(DIR *dir, long off) {
|
|||
dir->buf_pos = dir->buf_end = 0;
|
||||
}
|
||||
dir->tell = i;
|
||||
STRACE("seekdir(%p, %ld) → %ld", dir, off, i);
|
||||
_unlockdir(dir);
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_fstatfs,0x09f04022c215a08a,globl,hidden
|
||||
.scall sys_fstatfs,0x09e04022c215a08a,globl,hidden
|
||||
|
|
|
@ -1155,7 +1155,7 @@ syscon ms MS_INVALIDATE 2 2 2 4 2 0
|
|||
# statfs() flags
|
||||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon statfs ST_RDONLY 1 1 1 1 1 0 # MNT_RDONLY on BSD
|
||||
syscon statfs ST_RDONLY 1 1 1 1 1 0x00080000 # MNT_RDONLY on BSD, kNtFileReadOnlyVolume on NT
|
||||
syscon statfs ST_NOSUID 2 8 8 8 8 0 # MNT_NOSUID on BSD
|
||||
syscon statfs ST_NODEV 4 16 0 16 16 0 # MNT_NODEV on BSD
|
||||
syscon statfs ST_NOEXEC 8 4 4 4 4 0 # MNT_NOEXEC on BSD
|
||||
|
|
|
@ -169,7 +169,7 @@ scall mknodat 0x1cc14022fffff103 globl # FreeBSD 12+
|
|||
scall sys_mkfifo 0x0840840842084fff globl hidden
|
||||
scall mkfifoat 0x1cb13f1f1fffffff globl
|
||||
scall sys_statfs 0x09d03f22b2159089 globl hidden
|
||||
scall sys_fstatfs 0x09f04022c215a08a globl hidden
|
||||
scall sys_fstatfs 0x09e04022c215a08a globl hidden
|
||||
scall sys_getpriority 0x064064064206408c globl hidden
|
||||
scall sys_setpriority 0x060060060206008d globl hidden # modern nice()
|
||||
scall mlock 0x0cb0cb0cb20cb095 globl
|
||||
|
|
47
test/libc/calls/statfs_test.c
Normal file
47
test/libc/calls/statfs_test.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- 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/struct/statfs.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
char testlib_enable_tmp_setup_teardown;
|
||||
struct statfs f;
|
||||
|
||||
TEST(statfs, testFile) {
|
||||
EXPECT_SYS(0, 0, touch("foo", 0644));
|
||||
EXPECT_SYS(0, 0, statfs("foo", &f));
|
||||
}
|
||||
|
||||
TEST(statfs, testDirectory) {
|
||||
EXPECT_SYS(0, 0, statfs(".", &f));
|
||||
}
|
||||
|
||||
TEST(statfs, testFdDirectory) {
|
||||
EXPECT_SYS(0, 3, open(".", O_RDONLY | O_DIRECTORY));
|
||||
EXPECT_SYS(0, 0, fstatfs(3, &f));
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
}
|
||||
|
||||
TEST(statfs, testFdFile) {
|
||||
EXPECT_SYS(0, 0, touch("foo", 0644));
|
||||
EXPECT_SYS(0, 3, open("foo", O_RDONLY));
|
||||
EXPECT_SYS(0, 0, fstatfs(3, &f));
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
}
|
Loading…
Add table
Reference in a new issue