diff --git a/include/byteswap.h b/include/byteswap.h new file mode 100644 index 0000000000..d38068bdc8 --- /dev/null +++ b/include/byteswap.h @@ -0,0 +1,28 @@ +#ifndef _BYTESWAP_H +#define _BYTESWAP_H + +#include + +static inline uint16_t bswap_16(uint16_t x) { + return (x >> 8) | (x << 8); +} + +static inline uint32_t bswap_32(uint32_t x) { + return ((x & 0x000000ff) << 24) | + ((x & 0x0000ff00) << 8) | + ((x & 0x00ff0000) >> 8) | + ((x & 0xff000000) >> 24); +} + +static inline uint64_t bswap_64(uint64_t x) { + return ((x & 0x00000000000000ffULL) << 56) | + ((x & 0x000000000000ff00ULL) << 40) | + ((x & 0x0000000000ff0000ULL) << 24) | + ((x & 0x00000000ff000000ULL) << 8) | + ((x & 0x000000ff00000000ULL) >> 8) | + ((x & 0x0000ff0000000000ULL) >> 24) | + ((x & 0x00ff000000000000ULL) >> 40) | + ((x & 0xff00000000000000ULL) >> 56); +} + +#endif diff --git a/include/sys/ioccom.h b/include/sys/ioccom.h new file mode 100644 index 0000000000..661a8c5546 --- /dev/null +++ b/include/sys/ioccom.h @@ -0,0 +1,47 @@ +#ifndef _SYS_IOCCOM_H +#define _SYS_IOCCOM_H + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS) - 1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS) - 1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS) - 1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS) - 1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS) + +#define _IOC_NONE 0U +#define _IOC_WRITE 1U +#define _IOC_READ 2U + +#define _IOC(dir, type, nr, size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +#define _IOC_TYPECHECK(t) (sizeof(t)) + +#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0) +#define _IOR(type, nr, argtype) _IOC(_IOC_READ, (type), (nr), (_IOC_TYPECHECK(argtype))) +#define _IOW(type, nr, argtype) _IOC(_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(argtype))) +#define _IOWR(type, nr, argtype) _IOC(_IOC_READ | _IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(argtype))) + +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE | _IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif diff --git a/src/header/elf/cbindgen.toml b/src/header/elf/cbindgen.toml index cf53dfec97..48436ad0f0 100644 --- a/src/header/elf/cbindgen.toml +++ b/src/header/elf/cbindgen.toml @@ -1,4 +1,6 @@ after_includes = """ +#define ELFMAG "\\177ELF" +#define SELFMAG 4 #define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) #define ELF32_ST_TYPE(val) ((val) & 0xf) #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) diff --git a/src/header/mod.rs b/src/header/mod.rs index 49e5e52ce6..b4178fa0f9 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -110,6 +110,7 @@ pub mod sys_select; // TODO: sys/shm.h pub mod sys_socket; pub mod sys_stat; +pub mod sys_statfs; pub mod sys_statvfs; #[allow(non_upper_case_globals)] pub mod sys_syscall; diff --git a/src/header/sys_mman/mod.rs b/src/header/sys_mman/mod.rs index 5d89b986fc..4c8fd5df40 100644 --- a/src/header/sys_mman/mod.rs +++ b/src/header/sys_mman/mod.rs @@ -34,6 +34,11 @@ pub const MAP_TYPE: c_int = 0x000F; pub const MAP_ANON: c_int = 0x0020; pub const MAP_ANONYMOUS: c_int = MAP_ANON; pub const MAP_STACK: c_int = 0x20000; +pub const MAP_GROWSDOWN: c_int = 0x0100; +pub const MAP_DENYWRITE: c_int = 0x0800; +pub const MAP_EXECUTABLE: c_int = 0x01000; +pub const MAP_LOCKED: c_int = 0x2000; +pub const MAP_NONBLOCK: c_int = 0x10000; /// cbindgen:ignore pub const MAP_FAILED: *mut c_void = usize::wrapping_neg(1) as *mut c_void; diff --git a/src/header/sys_socket/constants.rs b/src/header/sys_socket/constants.rs index c91ffb1af5..02ed135071 100644 --- a/src/header/sys_socket/constants.rs +++ b/src/header/sys_socket/constants.rs @@ -51,6 +51,11 @@ pub const MSG_TRUNC: c_int = 32; pub const MSG_DONTWAIT: c_int = 64; pub const MSG_WAITALL: c_int = 256; pub const MSG_CMSG_CLOEXEC: c_int = 0x40000000; +pub const MSG_NOSIGNAL: c_int = 0x4000; +pub const MSG_PROBE: c_int = 0x10; +pub const MSG_CONFIRM: c_int = 0x800; +pub const MSG_MORE: c_int = 0x8000; +pub const MSG_FASTOPEN: c_int = 0x20000000; pub const IP_ADD_SOURCE_MEMBERSHIP: c_int = 70; pub const IP_DROP_SOURCE_MEMBERSHIP: c_int = 71; diff --git a/src/header/sys_statfs/cbindgen.toml b/src/header/sys_statfs/cbindgen.toml new file mode 100644 index 0000000000..0832e99cab --- /dev/null +++ b/src/header/sys_statfs/cbindgen.toml @@ -0,0 +1,11 @@ +sys_includes = ["sys/types.h"] +include_guard = "_SYS_STATFS_H" +language = "C" +style = "tag" +usize_is_size_t = true + +[export] +include = ["statfs"] + +[fn] +prefix = "" diff --git a/src/header/sys_statfs/mod.rs b/src/header/sys_statfs/mod.rs new file mode 100644 index 0000000000..9b43b6ad8f --- /dev/null +++ b/src/header/sys_statfs/mod.rs @@ -0,0 +1,70 @@ +use crate::{ + c_str::CStr, + error::ResultExt, + header::fcntl::O_PATH, + out::Out, + platform::{ + Pal, Sys, + types::{c_char, c_int, c_long}, + }, +}; + +#[repr(C)] +#[derive(Default)] +pub struct statfs { + pub f_type: c_long, + pub f_bsize: c_long, + pub f_blocks: c_long, + pub f_bfree: c_long, + pub f_bavail: c_long, + pub f_files: c_long, + pub f_ffree: c_long, + pub f_fsid: [c_int; 2], + pub f_namelen: c_long, + pub f_frsize: c_long, + pub f_flags: c_long, + pub f_spare: [c_long; 4], +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn statfs(path: *const c_char, buf: *mut statfs) -> c_int { + let path = unsafe { CStr::from_ptr(path) }; + let buf = unsafe { Out::nonnull(buf) }; + let fd = Sys::open(path, O_PATH, 0).or_minus_one_errno(); + if fd < 0 { + return -1; + } + let res = unsafe { fill_statfs(fd, buf) }; + if let Ok(()) = Sys::close(fd) {} + res +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn fstatfs(fd: c_int, buf: *mut statfs) -> c_int { + let buf = unsafe { Out::nonnull(buf) }; + unsafe { fill_statfs(fd, buf) } +} + +unsafe fn fill_statfs(fd: c_int, mut buf: Out) -> c_int { + let mut sv = crate::header::sys_statvfs::statvfs::default(); + let sv_out = Out::from_mut(&mut sv); + let res = Sys::fstatvfs(fd, sv_out); + if res.is_err() { + return res.map(|()| 0).or_minus_one_errno(); + } + buf.write(statfs { + f_type: 0xEF53, + f_bsize: sv.f_bsize as c_long, + f_blocks: sv.f_blocks as c_long, + f_bfree: sv.f_bfree as c_long, + f_bavail: sv.f_bavail as c_long, + f_files: sv.f_files as c_long, + f_ffree: sv.f_ffree as c_long, + f_fsid: [sv.f_fsid as c_int, 0], + f_namelen: sv.f_namemax as c_long, + f_frsize: sv.f_frsize as c_long, + f_flags: sv.f_flag as c_long, + f_spare: [0; 4], + }); + 0 +}