Polyfill statfs() and fstatfs() on BSD distros

This commit is contained in:
Justine Tunney 2022-08-17 13:41:21 -07:00
parent e3fe127ccd
commit f7ee9d7d99
42 changed files with 968 additions and 287 deletions

View file

@ -8,219 +8,89 @@
*/
#endif
#include "libc/calls/struct/statfs.h"
#include "libc/fmt/conv.h"
#include "libc/log/check.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/st.h"
const char *DescribeStatfsType(int64_t x) {
switch (x) {
case 0xadf5:
return "ADFS_SUPER_MAGIC";
case 0xadff:
return "AFFS_SUPER_MAGIC";
case 0x0187:
return "AUTOFS_SUPER_MAGIC";
case 0x1373:
return "DEVFS_SUPER_MAGIC";
case 0x1cd1:
return "DEVPTS_SUPER_MAGIC";
case 0xf15f:
return "ECRYPTFS_SUPER_MAGIC";
case 0x137d:
return "EXT_SUPER_MAGIC";
case 0xef51:
return "EXT2_OLD_SUPER_MAGIC";
case 0xef53:
return "EXT2/3/4_SUPER_MAGIC";
case 0x4244:
return "HFS_SUPER_MAGIC";
case 0x9660:
return "ISOFS_SUPER_MAGIC";
case 0x72b6:
return "JFFS2_SUPER_MAGIC";
case 0x137f:
return "MINIX_SUPER_MAGIC";
case 0x138f:
return "MINIX_SUPER_MAGIC2";
case 0x2468:
return "MINIX2_SUPER_MAGIC";
case 0x2478:
return "MINIX2_SUPER_MAGIC2";
case 0x4d5a:
return "MINIX3_SUPER_MAGIC";
case 0x4d44:
return "MSDOS_SUPER_MAGIC";
case 0x564c:
return "NCP_SUPER_MAGIC";
case 0x6969:
return "NFS_SUPER_MAGIC";
case 0x3434:
return "NILFS_SUPER_MAGIC";
case 0x9fa1:
return "OPENPROM_SUPER_MAGIC";
case 0x9fa0:
return "PROC_SUPER_MAGIC";
case 0x002f:
return "QNX4_SUPER_MAGIC";
case 0x7275:
return "ROMFS_MAGIC";
case 0x517b:
return "SMB_SUPER_MAGIC";
case 0x9fa2:
return "USBDEVICE_SUPER_MAGIC";
case 0x27e0eb:
return "CGROUP_SUPER_MAGIC";
case 0xbad1dea:
return "FUTEXFS_SUPER_MAGIC";
case 0x5346414f:
return "AFS_SUPER_MAGIC";
case 0x09041934:
return "ANON_INODE_FS_MAGIC";
case 0x62646576:
return "BDEVFS_MAGIC";
case 0x42465331:
return "BEFS_SUPER_MAGIC";
case 0x1badface:
return "BFS_MAGIC";
case 0x42494e4d:
return "BINFMTFS_MAGIC";
case 0xcafe4a11:
return "BPF_FS_MAGIC";
case 0x9123683e:
return "BTRFS_SUPER_MAGIC";
case 0x73727279:
return "BTRFS_TEST_MAGIC";
case 0x63677270:
return "CGROUP2_SUPER_MAGIC";
case 0xff534d42:
return "CIFS_MAGIC_NUMBER";
case 0x73757245:
return "CODA_SUPER_MAGIC";
case 0x012ff7b7:
return "COH_SUPER_MAGIC";
case 0x28cd3d45:
return "CRAMFS_MAGIC";
case 0x64626720:
return "DEBUGFS_MAGIC";
case 0xde5e81e4:
return "EFIVARFS_MAGIC";
case 0x00414a53:
return "EFS_SUPER_MAGIC";
case 0xf2f52010:
return "F2FS_SUPER_MAGIC";
case 0x65735546:
return "FUSE_SUPER_MAGIC";
case 0x00c0ffee:
return "HOSTFS_SUPER_MAGIC";
case 0xf995e849:
return "HPFS_SUPER_MAGIC";
case 0x958458f6:
return "HUGETLBFS_MAGIC";
case 0x3153464a:
return "JFS_SUPER_MAGIC";
case 0x19800202:
return "MQUEUE_MAGIC";
case 0x11307854:
return "MTD_INODE_FS_MAGIC";
case 0x6e736673:
return "NSFS_MAGIC";
case 0x5346544e:
return "NTFS_SB_MAGIC";
case 0x7461636f:
return "OCFS2_SUPER_MAGIC";
case 0x794c7630:
return "OVERLAYFS_SUPER_MAGIC";
case 0x50495045:
return "PIPEFS_MAGIC";
case 0x6165676c:
return "PSTOREFS_MAGIC";
case 0x68191122:
return "QNX6_SUPER_MAGIC";
case 0x858458f6:
return "RAMFS_MAGIC";
case 0x52654973:
return "REISERFS_SUPER_MAGIC";
case 0x73636673:
return "SECURITYFS_MAGIC";
case 0xf97cff8c:
return "SELINUX_MAGIC";
case 0x43415d53:
return "SMACK_MAGIC";
case 0x534f434b:
return "SOCKFS_MAGIC";
case 0x73717368:
return "SQUASHFS_MAGIC";
case 0x62656572:
return "SYSFS_MAGIC";
case 0x012ff7b6:
return "SYSV2_SUPER_MAGIC";
case 0x012ff7b5:
return "SYSV4_SUPER_MAGIC";
case 0x01021994:
return "TMPFS_MAGIC";
case 0x74726163:
return "TRACEFS_MAGIC";
case 0x15013346:
return "UDF_SUPER_MAGIC";
case 0x00011954:
return "UFS_MAGIC";
case 0x01021997:
return "V9FS_MAGIC";
case 0xa501fcf5:
return "VXFS_SUPER_MAGIC";
case 0xabba1974:
return "XENFS_SUPER_MAGIC";
case 0x012ff7b4:
return "XENIX_SUPER_MAGIC";
case 0x58465342:
return "XFS_SUPER_MAGIC";
case 0x012fd16d:
return "_XIAFS_SUPER_MAGIC";
default:
break;
}
return "UNKNOWN";
}
void ShowIt(const char *path) {
dontinline void ShowIt(const char *path) {
char ibuf[21];
struct statfs sf = {0};
CHECK_NE(-1, statfs(path, &sf));
printf("filesystem %s\n", path);
printf("f_type = %#x (%s)\n", sf.f_type, DescribeStatfsType(sf.f_type));
printf("f_bsize = %'zu (%s)\n", sf.f_bsize, "optimal transfer block size");
printf("f_blocks = %'zu (%s)\n", sf.f_blocks,
printf("f_type = %#x (%s)\n", sf.f_type, sf.f_fstypename);
sizefmt(ibuf, sf.f_bsize, 1024);
printf("f_bsize = %,zu (%sb %s)\n", sf.f_bsize, ibuf,
"optimal transfer block size");
sizefmt(ibuf, sf.f_frsize, 1024);
printf("f_frsize = %,zu (%sb %s)\n", sf.f_frsize, ibuf, "fragment size");
sizefmt(ibuf, sf.f_blocks * sf.f_bsize, 1024);
printf("f_blocks = %,zu (%sb %s)\n", sf.f_blocks, ibuf,
"total data blocks in filesystem");
printf("f_bfree = %'zu (%s)\n", sf.f_bfree, "free blocks in filesystem");
printf("f_bavail = %'zu (%s)\n", sf.f_bavail, "free blocks available to");
printf("f_files = %'zu (%s)\n", sf.f_files,
sizefmt(ibuf, sf.f_bfree * sf.f_bsize, 1024);
printf("f_bfree = %,zu (%sb %s)\n", sf.f_bfree, ibuf,
"free blocks in filesystem");
sizefmt(ibuf, sf.f_bavail * sf.f_bsize, 1024);
printf("f_bavail = %,zu (%sb %s)\n", sf.f_bavail, ibuf,
"free blocks available to use");
printf("f_files = %,zu (%s)\n", sf.f_files,
"total file nodes in filesystem");
printf("f_ffree = %'zu (%s)\n", sf.f_ffree,
printf("f_ffree = %,zu (%s)\n", sf.f_ffree,
"free file nodes in filesystem");
printf("f_fsid = %d:%d (%s)\n", (sf.f_fsid & 0xffff0000) >> 020,
(sf.f_fsid & 0x0000ffff) >> 000, "filesystem id");
printf("f_namelen = %'zu (%s)\n", sf.f_namelen,
printf("f_fsid = %#lx (%s)\n", sf.f_fsid, "filesystem id");
printf("f_owner = %#lx (%s)\n", sf.f_owner, "user that created mount");
printf("f_namelen = %,zu (%s)\n", sf.f_namelen,
"maximum length of filenames");
printf("f_frsize = %'zu (%s)\n", sf.f_frsize, "fragment size");
printf("f_flags = %#x", sf.f_flags);
if (sf.f_flags & 1) printf(" ST_RDONLY");
if (sf.f_flags & 2) printf(" ST_NOSUID");
if (sf.f_flags & 4) printf(" ST_NODEV");
if (sf.f_flags & 8) printf(" ST_NOEXEC");
if (sf.f_flags & 16) printf(" ST_SYNCHRONOUS");
if (sf.f_flags & 64) printf(" ST_MANDLOCK");
if (sf.f_flags & 128) printf(" ST_WRITE");
if (sf.f_flags & 256) printf(" ST_APPEND");
if (sf.f_flags & 512) printf(" ST_IMMUTABLE");
if (sf.f_flags & 1024) printf(" ST_NOATIME");
if (sf.f_flags & 2048) printf(" ST_NODIRATIME");
if (sf.f_flags & 4096) printf(" ST_RELATIME");
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");
}
printf("\n");
printf("\n");
}
int main(int argc, char *argv[]) {
if (!IsLinux()) return 1;
ShowIt("/");
if (argc <= 1) {
ShowIt("/");
} else {
for (int i = 1; i < argc; ++i) {
ShowIt(argv[i]);
}
}
}

View file

@ -8,6 +8,7 @@
*/
#endif
#include "libc/calls/struct/sysinfo.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/itoa.h"
#include "libc/log/check.h"
#include "libc/stdio/stdio.h"
@ -45,33 +46,33 @@ int main(int argc, char *argv[]) {
1. / 65536 * si.loads[1], //
1. / 65536 * si.loads[2]); //
FormatMemorySize(ibuf, si.totalram, 1024);
sizefmt(ibuf, si.totalram, 1024);
printf("%-16s %s\n", "totalram", ibuf);
FormatMemorySize(ibuf, si.freeram, 1024);
sizefmt(ibuf, si.freeram, 1024);
printf("%-16s %s\n", "freeram", ibuf);
FormatMemorySize(ibuf, si.sharedram, 1024);
sizefmt(ibuf, si.sharedram, 1024);
printf("%-16s %s\n", "sharedram", ibuf);
FormatMemorySize(ibuf, si.bufferram, 1024);
sizefmt(ibuf, si.bufferram, 1024);
printf("%-16s %s\n", "bufferram", ibuf);
FormatMemorySize(ibuf, si.totalswap, 1024);
sizefmt(ibuf, si.totalswap, 1024);
printf("%-16s %s\n", "totalswap", ibuf);
FormatMemorySize(ibuf, si.freeswap, 1024);
sizefmt(ibuf, si.freeswap, 1024);
printf("%-16s %s\n", "freeswap", ibuf);
printf("%-16s %lu\n", "processes", si.procs);
FormatMemorySize(ibuf, si.totalhigh, 1024);
sizefmt(ibuf, si.totalhigh, 1024);
printf("%-16s %s\n", "totalhigh", ibuf);
FormatMemorySize(ibuf, si.freehigh, 1024);
sizefmt(ibuf, si.freehigh, 1024);
printf("%-16s %s\n", "freehigh", ibuf);
FormatMemorySize(ibuf, si.mem_unit, 1024);
sizefmt(ibuf, si.mem_unit, 1024);
printf("%-16s %s\n", "mem_unit", ibuf);
//

View file

@ -118,6 +118,8 @@ o/$(MODE)/libc/calls/ntcontext2linux.o: private \
o/$(MODE)/libc/calls/execl.o \
o/$(MODE)/libc/calls/execle.o \
o/$(MODE)/libc/calls/execlp.o \
o/$(MODE)/libc/calls/statfs.o \
o/$(MODE)/libc/calls/fstatfs.o \
o/$(MODE)/libc/calls/execve-sysv.o \
o/$(MODE)/libc/calls/execve-nt.greg.o \
o/$(MODE)/libc/calls/mkntenvblock.o: private \

37
libc/calls/fstatfs.c Normal file
View file

@ -0,0 +1,37 @@
/*-*- 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/strace.internal.h"
#include "libc/calls/struct/statfs-meta.internal.h"
#include "libc/calls/struct/statfs.internal.h"
#include "libc/runtime/stack.h"
/**
* Returns information about filesystem.
*/
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);
}
STRACE("fstatfs(%d, [%s]) → %d% m", fd, DescribeStatfs(rc, sf));
return rc;
}

37
libc/calls/statfs.c Normal file
View file

@ -0,0 +1,37 @@
/*-*- 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/strace.internal.h"
#include "libc/calls/struct/statfs-meta.internal.h"
#include "libc/calls/struct/statfs.internal.h"
#include "libc/runtime/stack.h"
/**
* Returns information about filesystem.
*/
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);
}
STRACE("statfs(%#s, [%s]) → %d% m", path, DescribeStatfs(rc, sf));
return rc;
}

299
libc/calls/statfs2cosmo.c Normal file
View file

@ -0,0 +1,299 @@
/*-*- 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/struct/statfs-meta.internal.h"
#include "libc/dce.h"
#include "libc/str/str.h"
static const char *DescribeStatfsTypeLinux(int64_t x) {
switch (x) {
case 0xadf5:
return "adfs";
case 0xadff:
return "affs";
case 0x0187:
return "autofs";
case 0x1373:
return "devfs";
case 0x1cd1:
return "devpts";
case 0xf15f:
return "ecryptfs";
case 0x137d:
return "ext1";
case 0xef51:
return "ext2_old";
case 0xef53:
return "ext"; // ext2, ext3, ext4
case 0x4244:
return "hfs";
case 0x9660:
return "isofs";
case 0x72b6:
return "jffs2";
case 0x137f:
return "minix";
case 0x138f:
return "minix2";
case 0x2468:
return "minix2";
case 0x2478:
return "minix22";
case 0x4d5a:
return "minix3";
case 0x4d44:
return "msdos";
case 0x564c:
return "ncp";
case 0x6969:
return "nfs";
case 0x3434:
return "nilfs";
case 0x9fa1:
return "openprom";
case 0x9fa0:
return "proc";
case 0x002f:
return "qnx4";
case 0x7275:
return "romfs";
case 0x517b:
return "smb";
case 0x9fa2:
return "usbdevice";
case 0x27e0eb:
return "cgroup";
case 0xbad1dea:
return "futexfs";
case 0x5346414f:
return "afs";
case 0x09041934:
return "anon_inode_fs";
case 0x62646576:
return "bdevfs";
case 0x42465331:
return "befs";
case 0x1badface:
return "bfs";
case 0x42494e4d:
return "binfmtfs";
case 0xcafe4a11:
return "bpf_fs";
case 0x9123683e:
return "btrfs";
case 0x73727279:
return "btrfs_test";
case 0x63677270:
return "cgroup2";
case 0xff534d42:
return "cifs_number";
case 0x73757245:
return "coda";
case 0x012ff7b7:
return "coh";
case 0x28cd3d45:
return "cramfs";
case 0x64626720:
return "debugfs";
case 0xde5e81e4:
return "efivarfs";
case 0x00414a53:
return "efs";
case 0xf2f52010:
return "f2fs";
case 0x65735546:
return "fuse";
case 0x00c0ffee:
return "hostfs";
case 0xf995e849:
return "hpfs";
case 0x958458f6:
return "hugetlbfs";
case 0x3153464a:
return "jfs";
case 0x19800202:
return "mqueue";
case 0x11307854:
return "mtd_inode_fs";
case 0x6e736673:
return "nsfs";
case 0x5346544e:
return "ntfs_sb";
case 0x7461636f:
return "ocfs2";
case 0x794c7630:
return "overlayfs";
case 0x50495045:
return "pipefs";
case 0x6165676c:
return "pstorefs";
case 0x68191122:
return "qnx6";
case 0x858458f6:
return "ramfs";
case 0x52654973:
return "reiserfs";
case 0x73636673:
return "securityfs";
case 0xf97cff8c:
return "selinux";
case 0x43415d53:
return "smack";
case 0x534f434b:
return "sockfs";
case 0x73717368:
return "squashfs";
case 0x62656572:
return "sysfs";
case 0x012ff7b6:
return "sysv2";
case 0x012ff7b5:
return "sysv4";
case 0x01021994:
return "tmpfs";
case 0x74726163:
return "tracefs";
case 0x15013346:
return "udf";
case 0x00011954:
return "ufs";
case 0x01021997:
return "v9fs";
case 0xa501fcf5:
return "vxfs";
case 0xabba1974:
return "xenfs";
case 0x012ff7b4:
return "xenix";
case 0x58465342:
return "xfs";
case 0x012fd16d:
return "_xiafs";
default:
return "unknown";
}
}
void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
int64_t f_type;
int64_t f_bsize;
int64_t f_blocks;
int64_t f_bfree;
int64_t f_bavail;
int64_t f_files;
int64_t f_ffree;
int64_t f_fsid;
int64_t f_namelen;
int64_t f_frsize;
int64_t f_flags;
int32_t f_owner;
char f_fstypename[16];
if (IsLinux()) {
f_type = m->linux.f_type;
f_bsize = m->linux.f_bsize;
f_blocks = m->linux.f_blocks;
f_bfree = m->linux.f_bfree;
f_bavail = m->linux.f_bavail;
f_files = m->linux.f_files;
f_ffree = m->linux.f_ffree;
f_fsid = m->linux.f_fsid;
f_namelen = m->linux.f_namelen;
f_frsize = m->linux.f_frsize;
f_flags = m->linux.f_flags;
f_owner = 0;
strcpy(f_fstypename, DescribeStatfsTypeLinux(m->linux.f_type));
} else if (IsFreebsd()) {
f_type = m->freebsd.f_type;
f_bsize = m->freebsd.f_bsize;
f_blocks = m->freebsd.f_blocks;
f_bfree = m->freebsd.f_bfree;
f_bavail = m->freebsd.f_bavail;
f_files = m->freebsd.f_files;
f_ffree = m->freebsd.f_ffree;
f_fsid = m->freebsd.f_fsid;
f_namelen = m->freebsd.f_namemax;
f_frsize = m->freebsd.f_bsize;
f_flags = m->freebsd.f_flags;
f_owner = m->freebsd.f_owner;
strcpy(f_fstypename, m->freebsd.f_fstypename);
} else if (IsXnu()) {
f_type = m->xnu.f_type;
f_bsize = m->xnu.f_bsize;
f_blocks = m->xnu.f_blocks;
f_bfree = m->xnu.f_bfree;
f_bavail = m->xnu.f_bavail;
f_files = m->xnu.f_files;
f_ffree = m->xnu.f_ffree;
f_fsid = m->xnu.f_fsid;
f_namelen = 4096;
f_frsize = m->xnu.f_bsize;
f_flags = m->xnu.f_flags;
f_owner = m->xnu.f_owner;
strcpy(f_fstypename, m->xnu.f_fstypename);
} else if (IsOpenbsd()) {
f_type = f->f_type;
f_bsize = m->openbsd.f_bsize;
f_blocks = m->openbsd.f_blocks;
f_bfree = m->openbsd.f_bfree;
f_bavail = m->openbsd.f_bavail;
f_files = m->openbsd.f_files;
f_ffree = m->openbsd.f_ffree;
f_fsid = m->openbsd.f_fsid;
f_namelen = m->openbsd.f_namemax;
f_frsize = m->openbsd.f_bsize;
f_flags = m->openbsd.f_flags;
f_owner = m->openbsd.f_owner;
strcpy(f_fstypename, m->openbsd.f_fstypename);
} else if (IsNetbsd()) {
f_type = m->netbsd.f_type;
f_bsize = m->netbsd.f_bsize;
f_blocks = m->netbsd.f_blocks;
f_bfree = m->netbsd.f_bfree;
f_bavail = m->netbsd.f_bavail;
f_files = m->netbsd.f_files;
f_ffree = m->netbsd.f_ffree;
f_fsid = m->netbsd.f_fsid;
f_namelen = f->f_namelen;
f_frsize = m->netbsd.f_bsize;
f_flags = m->netbsd.f_flags;
f_owner = m->netbsd.f_owner;
strcpy(f_fstypename, m->netbsd.f_fstypename);
} else {
asm("hlt");
unreachable;
}
f->f_type = f_type;
f->f_bsize = f_bsize;
f->f_blocks = f_blocks;
f->f_bfree = f_bfree;
f->f_bavail = f_bavail;
f->f_files = f_files;
f->f_ffree = f_ffree;
f->f_fsid = f_fsid;
f->f_namelen = f_namelen;
f->f_frsize = f_frsize;
f->f_flags = f_flags;
strcpy(f->f_fstypename, f_fstypename);
}

View file

@ -0,0 +1,33 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_FREEBSD_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_FREEBSD_INTERNAL_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct statfs_freebsd {
uint32_t f_version; /* structure version number */
uint32_t f_type; /* type of filesystem */
uint64_t f_flags; /* copy of mount exported flags */
uint64_t f_bsize; /* filesystem fragment size */
uint64_t f_iosize; /* optimal transfer block size */
uint64_t f_blocks; /* total data blocks in filesystem */
uint64_t f_bfree; /* free blocks in filesystem */
int64_t f_bavail; /* free blocks avail to non-superuser */
uint64_t f_files; /* total file nodes in filesystem */
int64_t f_ffree; /* free nodes avail to non-superuser */
uint64_t f_syncwrites; /* count of sync writes since mount */
uint64_t f_asyncwrites; /* count of async writes since mount */
uint64_t f_syncreads; /* count of sync reads since mount */
uint64_t f_asyncreads; /* count of async reads since mount */
uint64_t f_spare[10]; /* unused spare */
uint32_t f_namemax; /* maximum filename length */
uint32_t f_owner; /* user that mounted the filesystem */
uint64_t f_fsid; /* filesystem id (endian 32 matters) */
char f_charspare[80]; /* spare string space */
char f_fstypename[16]; /* filesystem type name */
char f_mntfromname[1024]; /* mounted filesystem */
char f_mntonname[1024]; /* directory on which mounted */
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_FREEBSD_INTERNAL_H_ */

View file

@ -0,0 +1,23 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_LINUX_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_LINUX_INTERNAL_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct statfs_linux {
int64_t f_type; /* type of filesystem */
int64_t f_bsize; /* optimal transfer block size */
int64_t f_blocks; /* total data blocks in filesystem */
int64_t f_bfree; /* free blocks in filesystem */
int64_t f_bavail; /* free blocks available to */
int64_t f_files; /* total file nodes in filesystem */
int64_t f_ffree; /* free file nodes in filesystem */
int64_t f_fsid; /* filesystem id */
int64_t f_namelen; /* maximum length of filenames */
int64_t f_frsize; /* fragment size */
int64_t f_flags; /* mount flags of filesystem 2.6.36 */
int64_t f_spare[4];
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_LINUX_INTERNAL_H_ */

View file

@ -0,0 +1,24 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_META_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_META_INTERNAL_H_
#include "libc/calls/struct/statfs-freebsd.internal.h"
#include "libc/calls/struct/statfs-linux.internal.h"
#include "libc/calls/struct/statfs-netbsd.internal.h"
#include "libc/calls/struct/statfs-openbsd.internal.h"
#include "libc/calls/struct/statfs-xnu.internal.h"
#include "libc/calls/struct/statfs.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
union statfs_meta {
struct statfs_linux linux;
struct statfs_xnu xnu;
struct statfs_freebsd freebsd;
struct statfs_openbsd openbsd;
struct statfs_netbsd netbsd;
};
void statfs2cosmo(struct statfs *, const union statfs_meta *) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_META_INTERNAL_H_ */

View file

@ -0,0 +1,29 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_NETBSD_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_NETBSD_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct statfs_netbsd {
int16_t f_type; /* type of file system */
uint16_t f_oflags; /* deprecated copy of mount flags */
int64_t f_bsize; /* fundamental file system block size */
int64_t f_iosize; /* optimal transfer block size */
int64_t f_blocks; /* total data blocks in file system */
int64_t f_bfree; /* free blocks in fs */
int64_t f_bavail; /* free blocks avail to non-superuser */
int64_t f_files; /* total file nodes in file system */
int64_t f_ffree; /* free file nodes in fs */
uint64_t f_fsid; /* file system id (endian 32 matters) */
uint32_t f_owner; /* user that mounted the file system */
int64_t f_flags; /* copy of mount flags */
int64_t f_syncwrites; /* count of sync writes since mount */
int64_t f_asyncwrites; /* count of async writes since mount */
int64_t f_spare[1]; /* spare for later */
char f_fstypename[16]; /* fs type name */
char f_mntonname[90]; /* directory on which mounted */
char f_mntfromname[90]; /* mounted file system */
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_NETBSD_H_ */

View file

@ -0,0 +1,135 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_OPENBSD_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_OPENBSD_H_
#include "libc/sock/struct/sockaddr.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct xucred_openbsd {
uint32_t cr_uid; /* user id */
uint32_t cr_gid; /* group id */
int16_t cr_ngroups; /* number of groups */
uint32_t cr_groups[16]; /* groups */
};
struct export_args_openbsd {
int32_t ex_flags; /* export related flags */
uint32_t ex_root; /* mapping for root uid */
struct xucred_openbsd ex_anon; /* mapping for anonymous user */
struct sockaddr *ex_addr; /* net address to which exported */
int32_t ex_addrlen; /* and the net address length */
struct sockaddr *ex_mask; /* mask of valid bits in saddr */
int32_t ex_masklen; /* and the smask length */
};
struct ufs_args_openbsd {
char *fspec; /* block special device to mount */
struct export_args_openbsd export_info; /* network export information */
};
struct mfs_args_openbsd {
char *fspec; /* name to export for statfs */
struct export_args_openbsd export_info; /* if exported MFSes are supported */
char *base; /* base of file system in memory */
uint64_t size; /* size of file system */
};
struct iso_args_openbsd {
char *fspec; /* block special device to mount */
struct export_args_openbsd export_info; /* network export info */
int32_t flags; /* mounting flags, see below */
int32_t sess; /* start sector of session */
};
struct nfs_args_openbsd {
int32_t version; /* args structure version number */
struct sockaddr *addr; /* file server address */
int32_t addrlen; /* length of address */
int32_t sotype; /* Socket type */
int32_t proto; /* and Protocol */
unsigned char *fh; /* File handle to be mounted */
int32_t fhsize; /* Size, in bytes, of fh */
int32_t flags; /* flags */
int32_t wsize; /* write size in bytes */
int32_t rsize; /* read size in bytes */
int32_t readdirsize; /* readdir size in bytes */
int32_t timeo; /* initial timeout in .1 secs */
int32_t retrans; /* times to retry send */
int32_t maxgrouplist; /* Max. size of group list */
int32_t readahead; /* # of blocks to readahead */
int32_t leaseterm; /* Term (sec) of lease */
int32_t deadthresh; /* Retrans threshold */
char *hostname; /* server's name */
int32_t acregmin; /* Attr cache file recently modified */
int32_t acregmax; /* ac file not recently modified */
int32_t acdirmin; /* ac for dir recently modified */
int32_t acdirmax; /* ac for dir not recently modified */
};
struct msdosfs_args_openbsd {
char *fspec; /* blocks special holding the fs to mount */
struct export_args_openbsd export_info; /* network export information */
uint32_t uid; /* uid that owns msdosfs files */
uint32_t gid; /* gid that owns msdosfs files */
uint32_t mask; /* mask to be applied for msdosfs perms */
int32_t flags; /* see below */
};
struct ntfs_args_openbsd {
char *fspec; /* block special device to mount */
struct export_args_openbsd export_info; /* network export information */
uint32_t uid; /* uid that owns ntfs files */
uint32_t gid; /* gid that owns ntfs files */
uint32_t mode; /* mask to be applied for ntfs perms */
uint64_t flag; /* additional flags */
};
struct tmpfs_args_openbsd {
int32_t ta_version;
/* Size counters. */
uint64_t ta_nodes_max;
int64_t ta_size_max;
/* Root node attributes. */
uint32_t ta_root_uid;
uint32_t ta_root_gid;
uint32_t ta_root_mode;
};
union mount_info_openbsd {
struct ufs_args_openbsd ufs_args;
struct mfs_args_openbsd mfs_args;
struct nfs_args_openbsd nfs_args;
struct iso_args_openbsd iso_args;
struct msdosfs_args_openbsd msdosfs_args;
struct ntfs_args_openbsd ntfs_args;
struct tmpfs_args_openbsd tmpfs_args;
char __align[160]; /* 64-bit alignment and room to grow */
};
struct statfs_openbsd {
uint32_t f_flags; /* copy of mount flags */
uint32_t f_bsize; /* file system block size */
uint32_t f_iosize; /* optimal transfer block size */
uint64_t f_blocks; /* total data blocks in file system */
uint64_t f_bfree; /* free blocks in fs */
int64_t f_bavail; /* free blocks avail to non-superuser */
uint64_t f_files; /* total file nodes in file system */
uint64_t f_ffree; /* free file nodes in fs */
int64_t f_favail; /* free file nodes avail to non-root */
uint64_t f_syncwrites; /* count of sync writes since mount */
uint64_t f_syncreads; /* count of sync reads since mount */
uint64_t f_asyncwrites; /* count of async writes since mount */
uint64_t f_asyncreads; /* count of async reads since mount */
uint64_t f_fsid; /* file system id (endian 32 matters) */
uint32_t f_namemax; /* maximum filename length */
uint32_t f_owner; /* user that mounted the file system */
uint64_t f_ctime; /* last mount [-u] time */
char f_fstypename[16]; /* fs type name */
char f_mntonname[90]; /* directory on which mounted */
char f_mntfromname[90]; /* mounted file system */
char f_mntfromspec[90]; /* special for mount request */
union mount_info_openbsd mount_info; /* per-filesystem mount options */
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_OPENBSD_H_ */

View file

@ -0,0 +1,28 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_XNU_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_XNU_INTERNAL_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct statfs_xnu {
uint32_t f_bsize; /* fundamental file system block size */
int32_t f_iosize; /* optimal transfer block size */
uint64_t f_blocks; /* total data blocks in file system */
uint64_t f_bfree; /* free blocks in fs */
uint64_t f_bavail; /* free blocks avail to non-superuser */
uint64_t f_files; /* total file nodes in file system */
uint64_t f_ffree; /* free file nodes in fs */
uint64_t f_fsid; /* file system id (endian 32 matters) */
uint32_t f_owner; /* user that mounted the filesystem */
uint32_t f_type; /* type of filesystem */
uint32_t f_flags; /* copy of mount exported flags */
uint32_t f_fssubtype; /* fs sub-type (flavor) */
char f_fstypename[16]; /* fs type name */
char f_mntonname[4096]; /* directory on which mounted */
char f_mntfromname[4096]; /* mounted filesystem */
uint32_t f_flags_ext; /* extended flags */
uint32_t f_reserved[7]; /* For future use */
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_XNU_INTERNAL_H_ */

View file

@ -3,19 +3,21 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct statfs {
int64_t f_type; /* type of filesystem */
int64_t f_bsize; /* optimal transfer block size */
int64_t f_blocks; /* total data blocks in filesystem */
int64_t f_bfree; /* free blocks in filesystem */
int64_t f_bavail; /* free blocks available to */
int64_t f_files; /* total file nodes in filesystem */
int64_t f_ffree; /* free file nodes in filesystem */
int64_t f_fsid; /* filesystem id */
int64_t f_namelen; /* maximum length of filenames */
int64_t f_frsize; /* fragment size */
int64_t f_flags; /* mount flags of filesystem 2.6.36 */
int64_t f_spare[4];
struct statfs { /* cosmo abi */
int64_t f_type; /* type of filesystem */
int64_t f_bsize; /* optimal transfer block size */
int64_t f_blocks; /* total data blocks in filesystem */
int64_t f_bfree; /* free blocks in filesystem */
int64_t f_bavail; /* free blocks available to */
int64_t f_files; /* total file nodes in filesystem */
int64_t f_ffree; /* free file nodes in filesystem */
int64_t f_fsid; /* filesystem id */
int64_t f_namelen; /* maximum length of filenames */
int64_t f_frsize; /* fragment size */
int64_t f_flags; /* mount flags of filesystem 2.6.36 */
int64_t f_spare[4]; /* end of linux abi */
uint32_t f_owner;
char f_fstypename[16];
};
int statfs(const char *, struct statfs *);

View file

@ -0,0 +1,17 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_INTERNAL_H_
#include "libc/calls/struct/statfs-meta.internal.h"
#include "libc/calls/struct/statfs.h"
#include "libc/mem/alloca.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int sys_statfs(const char *, union statfs_meta *);
int sys_fstatfs(int, union statfs_meta *);
const char *DescribeStatfs(char[300], int, const struct statfs *);
#define DescribeStatfs(rc, sf) DescribeStatfs(alloca(300), rc, sf)
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_INTERNAL_H_ */

View file

@ -33,6 +33,7 @@ long wcstol(const wchar_t *, wchar_t **, int);
unsigned long wcstoul(const wchar_t *, wchar_t **, int);
long strtol(const char *, char **, int) paramsnonnull((1)) libcesque;
long sizetol(const char *, long) paramsnonnull() libcesque;
char *sizefmt(char *, uint64_t, uint64_t);
long long wcstoll(const wchar_t *, wchar_t **, int);
unsigned long long wcstoull(const wchar_t *, wchar_t **, int);
int wcscoll(const wchar_t *, const wchar_t *);

View file

@ -21,7 +21,6 @@ char *FormatFlex64(char[hasatleast 24], int64_t, char);
size_t uint64toarray_radix16(uint64_t, char[hasatleast 17]);
size_t uint64toarray_fixed16(uint64_t, char[hasatleast 17], uint8_t);
size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]);
char *FormatMemorySize(char *, uint64_t, uint64_t);
#ifndef __STRICT_ANSI__
size_t int128toarray_radix10(int128_t, char *);

View file

@ -0,0 +1,122 @@
/*-*- 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 2021 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/struct/statfs.h"
#include "libc/calls/struct/statfs.internal.h"
#include "libc/dce.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/sysv/consts/st.h"
const char *(DescribeStatfs)(char buf[300], int rc, const struct statfs *f) {
int i, n;
char ibuf[21];
int64_t flags;
if (rc == -1) return "n/a";
if (!f) return "NULL";
if ((!IsAsan() && kisdangerous(f)) ||
(IsAsan() && !__asan_is_valid(f, sizeof(*f)))) {
ksnprintf(buf, 300, "%p", f);
return buf;
}
i = 0;
n = 300;
i += ksnprintf(buf + i, n - i, "{.f_type=%#lx /* %s */", f->f_type,
f->f_fstypename);
sizefmt(ibuf, f->f_bsize, 1024);
i += ksnprintf(buf + i, n - i, ", .f_%s=%sb", "bsize", ibuf);
sizefmt(ibuf, f->f_blocks * f->f_bsize, 1024);
i += ksnprintf(buf + i, n - i, ", .f_%s=%sb", "blocks", ibuf);
sizefmt(ibuf, f->f_bfree * f->f_bsize, 1024);
i += ksnprintf(buf + i, n - i, ", .f_%s=%sb", "bfree", ibuf);
sizefmt(ibuf, f->f_bavail * f->f_bsize, 1024);
i += ksnprintf(buf + i, n - i, ", .f_%s=%sb", "bavail", ibuf);
i += ksnprintf(buf + i, n - i, ", .f_%s=%'zu", "files", f->f_files);
i += ksnprintf(buf + i, n - i, ", .f_%s=%'zu", "ffree", f->f_ffree);
i += ksnprintf(buf + i, n - i, ", .f_fsid=%#lx", f->f_fsid);
i += ksnprintf(buf + i, n - i, ", .f_%s=%'zu", "namelen", f->f_namelen);
i += ksnprintf(buf + i, n - i, ", .f_%s=%d", "owner", f->f_owner);
flags = f->f_flags;
i += ksnprintf(buf + i, n - i, ", .f_flags=");
if (ST_RDONLY && (flags & ST_RDONLY)) {
i += ksnprintf(buf + i, n - i, "ST_RDONLY|");
flags &= ~ST_RDONLY;
}
if (ST_NOSUID && (flags & ST_NOSUID)) {
i += ksnprintf(buf + i, n - i, "ST_NOSUID|");
flags &= ~ST_NOSUID;
}
if (ST_NODEV && (flags & ST_NODEV)) {
i += ksnprintf(buf + i, n - i, "ST_NODEV|");
flags &= ~ST_NODEV;
}
if (ST_NOEXEC && (flags & ST_NOEXEC)) {
i += ksnprintf(buf + i, n - i, "ST_NOEXEC|");
flags &= ~ST_NOEXEC;
}
if (ST_SYNCHRONOUS && (flags & ST_SYNCHRONOUS)) {
i += ksnprintf(buf + i, n - i, "ST_SYNCHRONOUS|");
flags &= ~ST_SYNCHRONOUS;
}
if (ST_MANDLOCK && (flags & ST_MANDLOCK)) {
i += ksnprintf(buf + i, n - i, "ST_MANDLOCK|");
flags &= ~ST_MANDLOCK;
}
if (ST_WRITE && (flags & ST_WRITE)) {
i += ksnprintf(buf + i, n - i, "ST_WRITE|");
flags &= ~ST_WRITE;
}
if (ST_APPEND && (flags & ST_APPEND)) {
i += ksnprintf(buf + i, n - i, "ST_APPEND|");
flags &= ~ST_APPEND;
}
if (ST_IMMUTABLE && (flags & ST_IMMUTABLE)) {
i += ksnprintf(buf + i, n - i, "ST_IMMUTABLE|");
flags &= ~ST_IMMUTABLE;
}
if (ST_NOATIME && (flags & ST_NOATIME)) {
i += ksnprintf(buf + i, n - i, "ST_NOATIME|");
flags &= ~ST_NOATIME;
}
if (ST_NODIRATIME && (flags & ST_NODIRATIME)) {
i += ksnprintf(buf + i, n - i, "ST_NODIRATIME|");
flags &= ~ST_NODIRATIME;
}
if (ST_RELATIME && (flags & ST_RELATIME)) {
i += ksnprintf(buf + i, n - i, "ST_RELATIME|");
flags &= ~ST_RELATIME;
}
i += ksnprintf(buf + i, n - i, "%#lx", flags);
if (n - i >= 2) {
buf[i + 0] = '}';
buf[i + 1] = 0;
}
return buf;
}

View file

@ -20,13 +20,13 @@
#include "libc/macros.internal.h"
/**
* Represents size of memory readably.
* Represents size as readable string.
*
* @param p is output buffer
* @param b should be 1024 or 1000
* @return pointer to nul byte
*/
char *FormatMemorySize(char *p, uint64_t x, uint64_t b) {
char *sizefmt(char *p, uint64_t x, uint64_t b) {
int i, suffix;
struct {
char suffix;
@ -48,7 +48,6 @@ char *FormatMemorySize(char *p, uint64_t x, uint64_t b) {
}
p = FormatUint64(p, x);
if (suffix) *p++ = suffix;
*p++ = 'b';
*p = 0;
return p;
}

View file

@ -1,2 +0,0 @@
.include "o/libc/sysv/macros.internal.inc"
.scall fstatfs,0xfff04022c215a08a,globl

View file

@ -1,2 +0,0 @@
.include "o/libc/sysv/macros.internal.inc"
.scall statfs,0xfff03f22b2159089,globl

View file

@ -0,0 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_fstatfs,0x09f04022c215a08a,globl,hidden

View file

@ -0,0 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_statfs,0x09d03f22b2159089,globl,hidden

View file

@ -304,6 +304,12 @@ syscon misc SIG_UNBLOCK 1 2 2 2 2 1 # bsd consensus; faked nt
syscon misc SIG_SETMASK 2 3 3 3 3 2 # bsd consensus; faked nt
syscon misc SIG_ATOMIC_MIN -2147483648 -2147483648 -9223372036854775808 -2147483648 -2147483648 0
# lseek() whence
#
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
syscon splice SEEK_HOLE 4 3 4 -1 -1 -1 #
syscon splice SEEK_DATA 3 4 3 -1 -1 -1 #
# splice() flags
#
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
@ -1146,21 +1152,21 @@ syscon ms MS_SYNC 4 16 0 2 4 4 # faked nt
syscon ms MS_ASYNC 1 1 1 1 1 1 # consensus (faked nt)
syscon ms MS_INVALIDATE 2 2 2 4 2 0
# statvfs() flags
# statfs() flags
#
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
syscon statvfs ST_RDONLY 1 1 1 1 1 0 # unix consensus
syscon statvfs ST_NOSUID 2 2 2 2 2 0 # unix consensus
syscon statvfs ST_NODEV 4 0 0 0 0x00000010 0
syscon statvfs ST_NOEXEC 8 0 0 0 4 0
syscon statvfs ST_SYNCHRONOUS 16 0 0 0 2 0
syscon statvfs ST_APPEND 0x0100 0 0 0 0 0
syscon statvfs ST_IMMUTABLE 0x0200 0 0 0 0 0
syscon statvfs ST_MANDLOCK 0x0040 0 0 0 0 0
syscon statvfs ST_NOATIME 0x0400 0 0 0x04000000 0 0
syscon statvfs ST_NODIRATIME 0x0800 0 0 0 0 0
syscon statvfs ST_WRITE 0x0080 0 0 0 0 0
syscon statvfs ST_RELATIME 0x1000 0 0 0 0x00020000 0
syscon statfs ST_RDONLY 1 1 1 1 1 0 # MNT_RDONLY on BSD
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
syscon statfs ST_SYNCHRONOUS 16 2 2 2 2 0 # MNT_SYNCHRONOUS on BSD
syscon statfs ST_NOATIME 0x0040 0x10000000 0x10000000 0x00008000 0x04000000 0 # MNT_NOATIME on BSD
syscon statfs ST_RELATIME 0x1000 0 0 0 0x00020000 0 # MNT_RELATIME on NetBSD
syscon statfs ST_APPEND 0x0100 0 0 0 0 0 #
syscon statfs ST_IMMUTABLE 0x0200 0 0 0 0 0 #
syscon statfs ST_MANDLOCK 0x0040 0 0 0 0 0 #
syscon statfs ST_NODIRATIME 0x0800 0 0 0 0 0 #
syscon statfs ST_WRITE 0x0080 0 0 0 0 0 #
# sendfile() flags
#

View file

@ -0,0 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon splice,SEEK_DATA,3,4,3,-1,-1,-1

View file

@ -0,0 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon splice,SEEK_HOLE,4,3,4,-1,-1,-1

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_APPEND,0x0100,0,0,0,0,0
.syscon statfs,ST_APPEND,0x0100,0,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_IMMUTABLE,0x0200,0,0,0,0,0
.syscon statfs,ST_IMMUTABLE,0x0200,0,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_MANDLOCK,0x0040,0,0,0,0,0
.syscon statfs,ST_MANDLOCK,0x0040,0,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_NOATIME,0x0400,0,0,0x04000000,0,0
.syscon statfs,ST_NOATIME,0x0040,0x10000000,0x10000000,0x00008000,0x04000000,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_NODEV,4,0,0,0,0x00000010,0
.syscon statfs,ST_NODEV,4,16,0,16,16,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_NODIRATIME,0x0800,0,0,0,0,0
.syscon statfs,ST_NODIRATIME,0x0800,0,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_NOEXEC,8,0,0,0,4,0
.syscon statfs,ST_NOEXEC,8,4,4,4,4,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_NOSUID,2,2,2,2,2,0
.syscon statfs,ST_NOSUID,2,8,8,8,8,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_RDONLY,1,1,1,1,1,0
.syscon statfs,ST_RDONLY,1,1,1,1,1,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_RELATIME,0x1000,0,0,0,0x00020000,0
.syscon statfs,ST_RELATIME,0x1000,0,0,0,0x00020000,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_SYNCHRONOUS,16,0,0,0,2,0
.syscon statfs,ST_SYNCHRONOUS,16,2,2,2,2,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon statvfs,ST_WRITE,0x0080,0,0,0,0,0
.syscon statfs,ST_WRITE,0x0080,0,0,0,0,0

16
libc/sysv/consts/seek.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SEEK_H_
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SEEK_H_
#include "libc/runtime/symbolic.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern const int SEEK_DATA;
extern const int SEEK_HOLE;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#define SEEK_DATA SYMBOLIC(SEEK_DATA)
#define SEEK_HOLE SYMBOLIC(SEEK_HOLE)
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SEEK_H_ */

View file

@ -168,8 +168,8 @@ scall sys_mknod 0x1c200e00e200e085 globl hidden
scall mknodat 0x1cc14022fffff103 globl # FreeBSD 12+
scall sys_mkfifo 0x0840840842084fff globl hidden
scall mkfifoat 0x1cb13f1f1fffffff globl
scall statfs 0xfff03f22b2159089 globl
scall fstatfs 0xfff04022c215a08a globl
scall sys_statfs 0x09d03f22b2159089 globl hidden
scall sys_fstatfs 0x09f04022c215a08a globl hidden
scall sys_getpriority 0x064064064206408c globl hidden
scall sys_setpriority 0x060060060206008d globl hidden # modern nice()
scall mlock 0x0cb0cb0cb20cb095 globl

View file

@ -1964,8 +1964,8 @@ child_execute_job (struct childbase *child,
if (bytes > 0)
{
if (!set_limit (RLIMIT_AS, bytes, bytes))
DB (DB_JOBS, (_("Set virtual memory limit of %s\n"),
(FormatMemorySize (buf, bytes, 1024), buf)));
DB (DB_JOBS, (_("Set virtual memory limit of %sb\n"),
(sizefmt (buf, bytes, 1024), buf)));
else
DB (DB_JOBS, (_("Failed to set virtual memory: %s\n"),
strerror (errno)));
@ -1993,8 +1993,8 @@ child_execute_job (struct childbase *child,
if (bytes > 0)
{
if (!set_limit (RLIMIT_RSS, bytes, bytes))
DB (DB_JOBS, (_("Set resident memory limit of %s\n"),
(FormatMemorySize (buf, bytes, 1024), buf)));
DB (DB_JOBS, (_("Set resident memory limit of %sb\n"),
(sizefmt (buf, bytes, 1024), buf)));
else
DB (DB_JOBS, (_("Failed to set resident memory: %s\n"),
strerror (errno)));
@ -2018,8 +2018,8 @@ child_execute_job (struct childbase *child,
if ((bytes = sizetol (s, 1000)) > 0)
{
if (!set_limit (RLIMIT_FSIZE, bytes, bytes * 1.5))
DB (DB_JOBS, (_("Set file size limit of %s\n"),
(FormatMemorySize (buf, bytes, 1000), buf)));
DB (DB_JOBS, (_("Set file size limit of %sb\n"),
(sizefmt (buf, bytes, 1000), buf)));
else
DB (DB_JOBS, (_("Failed to set file size limit: %s\n"),
strerror (errno)));
@ -2043,8 +2043,8 @@ child_execute_job (struct childbase *child,
if ((bytes = sizetol (s, 1000)) > 0)
{
if (!set_limit (RLIMIT_CORE, bytes, bytes))
DB (DB_JOBS, (_("Set core dump limit of %s\n"),
(FormatMemorySize (buf, bytes, 1000), buf)));
DB (DB_JOBS, (_("Set core dump limit of %sb\n"),
(sizefmt (buf, bytes, 1000), buf)));
else
DB (DB_JOBS, (_("Failed to set core dump limit: %s\n"),
strerror (errno)));

View file

@ -5010,11 +5010,10 @@ UNIX MODULE
Raised by accept, access, bind, chdir, chmod, chown, close, connect,
copy_file_range, dup, fcntl, flock, fsync, futimesat, opendir,
getpeername, getsockname, getsockopt, inotify_add_watch,
inotify_rm_watch, ioctl, link, listen, llseek, lseek, mkdir, mknod,
mmap, open, prctl, read, readahead, readlink, recv, rename, select,
send, shutdown, splice, stat, symlink, sync, sync_file_range,
timerfd_create, truncate, unlink, utimensat, write.
getpeername, getsockname, getsockopt, ioctl, link, listen, lseek,
mkdir, mknod, mmap, open, prctl, read, readahead, readlink, recv,
rename, select, send, shutdown, splice, stat, symlink, sync,
sync_file_range, timerfd_create, truncate, unlink, utimensat, write.
unix.EAGAIN
Resource temporarily unavailable (e.g. SO_RCVTIMEO expired, too many
@ -5042,28 +5041,27 @@ UNIX MODULE
calls that accept a pathname.
Raised by access, bind, chdir, chmod, chown, chroot, execve,
gethostname, inotify_add_watch, link, mkdir, mknod, open, readlink,
rename, rmdir, stat, symlink, truncate, unlink, utimensat.
gethostname, link, mkdir, mknod, open, readlink, rename, rmdir,
stat, symlink, truncate, unlink, utimensat.
unix.EACCES
Permission denied.
Raised by access, bind, chdir, chmod, chown, chroot, clock_getres,
connect, execve, fcntl, getpriority, inotify_add_watch, link, mkdir,
mknod, mmap, mprotect, msgctl, open, prctl, ptrace, readlink,
rename, rmdir, semget, send, setpgid, socket, stat, symlink,
truncate, unlink, uselib, utime, utimensat.
connect, execve, fcntl, getpriority, link, mkdir, mknod, mmap,
mprotect, msgctl, open, prctl, ptrace, readlink, rename, rmdir,
semget, send, setpgid, socket, stat, symlink, truncate, unlink,
uselib, utime, utimensat.
unix.ENOMEM
We require more vespene gas.
Raised by access, bind, chdir, chmod, chown, chroot, clone,
copy_file_range, execve, fanotify_init, fork, getgroups, getrlimit,
inotify_add_watch, inotify_init, ioperm, link, mbind, mincore,
mkdir, mknod, mlock, mmap, mprotect, mremap, msync, open, poll,
readlink, recv, rename, rmdir, select, send, sigaltstack, splice,
stat, subpage_prot, swapon, symlink, sync_file_range, tee,
timer_create, timerfd_create, unlink.
link, mbind, mincore, mkdir, mknod, mlock, mmap, mprotect, mremap,
msync, open, poll, readlink, recv, rename, rmdir, select, send,
sigaltstack, splice, stat, subpage_prot, swapon, symlink,
sync_file_range, tee, timer_create, timerfd_create, unlink.
unix.EPERM
Operation not permitted.
@ -5098,8 +5096,7 @@ UNIX MODULE
unix.EEXIST
File exists.
Raised by inotify_add_watch, link, mkdir, mknod, mmap, open, rename,
rmdir, symlink
Raised by link, mkdir, mknod, mmap, open, rename, rmdir, symlink
unix.EXDEV
Improper link.
@ -5120,14 +5117,14 @@ UNIX MODULE
unix.ENFILE
Too many open files in system.
Raised by accept, execve, inotify_init, mmap, open, pipe, socket,
socketpair, swapon, timerfd_create, uselib, userfaultfd.
Raised by accept, execve, mmap, open, pipe, socket, socketpair,
swapon, timerfd_create, uselib, userfaultfd.
unix.EMFILE
Too many open files.
Raised by accept, dup, execve, fanotify_init, fcntl, inotify_init,
open, pipe, socket, socketpair, timerfd_create.
Raised by accept, dup, execve, fcntl, open, pipe, socket,
socketpair, timerfd_create.
unix.ENOTTY
Inappropriate i/o control operation.
@ -5147,9 +5144,8 @@ UNIX MODULE
unix.ENOSPC
No space left on device.
Raised by copy_file_range, fsync, inotify_add_watch, link,
mkdir, mknod, open, rename, symlink, sync_file_range,
write.
Raised by copy_file_range, fsync, link, mkdir, mknod, open, rename,
symlink, sync_file_range, write.
unix.EDQUOT
Disk quota exceeded.

View file

@ -8,6 +8,7 @@
*/
#endif
#include "libc/calls/internal.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/bits.h"
#include "libc/macros.internal.h"
@ -30,7 +31,7 @@ uint64_t last;
void plan2(uint64_t addr, uint64_t end, const char *name) {
char sz[32];
FormatMemorySize(sz, end-addr+1, 1024);
sizefmt(sz, end-addr+1, 1024);
printf("%08x-%08x %-6s %s\n", addr>>16, end>>16, sz, name);
}