diff --git a/examples/statfs.c b/examples/statfs.c index b66f1074f..b22950961 100644 --- a/examples/statfs.c +++ b/examples/statfs.c @@ -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"); diff --git a/libc/calls/fstatfs-nt.c b/libc/calls/fstatfs-nt.c new file mode 100644 index 000000000..d4b7d1152 --- /dev/null +++ b/libc/calls/fstatfs-nt.c @@ -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; +} diff --git a/libc/calls/fstatfs.c b/libc/calls/fstatfs.c index 659e58c91..ca053c808 100644 --- a/libc/calls/fstatfs.c +++ b/libc/calls/fstatfs.c @@ -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; diff --git a/libc/calls/statfs-nt.c b/libc/calls/statfs-nt.c new file mode 100644 index 000000000..4b656416d --- /dev/null +++ b/libc/calls/statfs-nt.c @@ -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; +} diff --git a/libc/calls/statfs.c b/libc/calls/statfs.c index 4fb6d49f0..e54324bdd 100644 --- a/libc/calls/statfs.c +++ b/libc/calls/statfs.c @@ -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; diff --git a/libc/calls/struct/statfs.internal.h b/libc/calls/struct/statfs.internal.h index b410324d7..e0d5f2e52 100644 --- a/libc/calls/struct/statfs.internal.h +++ b/libc/calls/struct/statfs.internal.h @@ -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) diff --git a/libc/nt/enum/statfs.h b/libc/nt/enum/statfs.h new file mode 100644 index 000000000..d626037b3 --- /dev/null +++ b/libc/nt/enum/statfs.h @@ -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_ */ diff --git a/libc/nt/files.h b/libc/nt/files.h index 97c95a83f..b61db4569 100644 --- a/libc/nt/files.h +++ b/libc/nt/files.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() */ diff --git a/libc/nt/kernel32/GetVolumeInformationByHandleW.s b/libc/nt/kernel32/GetVolumeInformationByHandleW.s index 7bf6a4744..6ba5ca693 100644 --- a/libc/nt/kernel32/GetVolumeInformationByHandleW.s +++ b/libc/nt/kernel32/GetVolumeInformationByHandleW.s @@ -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 diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 2d79e629d..29a438991 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -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 diff --git a/libc/nt/struct/filefsfullsizeinformation.h b/libc/nt/struct/filefsfullsizeinformation.h new file mode 100644 index 000000000..dfb7c0840 --- /dev/null +++ b/libc/nt/struct/filefsfullsizeinformation.h @@ -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_ */ diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index 7e62a735e..4b7aeb7e7 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -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); } diff --git a/libc/sysv/calls/sys_fstatfs.s b/libc/sysv/calls/sys_fstatfs.s index 6fc7b458e..1cc25d2c3 100644 --- a/libc/sysv/calls/sys_fstatfs.s +++ b/libc/sysv/calls/sys_fstatfs.s @@ -1,2 +1,2 @@ .include "o/libc/sysv/macros.internal.inc" -.scall sys_fstatfs,0x09f04022c215a08a,globl,hidden +.scall sys_fstatfs,0x09e04022c215a08a,globl,hidden diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index a9ad2ab4d..47c578cb2 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -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 diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index a4b08f99c..f17c0c224 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -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 diff --git a/test/libc/calls/statfs_test.c b/test/libc/calls/statfs_test.c new file mode 100644 index 000000000..1f9c6ca24 --- /dev/null +++ b/test/libc/calls/statfs_test.c @@ -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)); +}