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

@ -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_ */