relibc: add missing POSIX/Linux headers and constants

New headers:
- include/sys/ioccom.h: Linux UAPI ioctl encoding macros (_IO/_IOR/_IOW/_IOWR)
- include/byteswap.h: bswap_16/32/64 inline functions
- src/header/sys_statfs/: struct statfs + statfs()/fstatfs() functions
  (delegates to fstatvfs, converts to Linux struct statfs format)

New constants:
- sys_socket: MSG_NOSIGNAL, MSG_PROBE, MSG_CONFIRM, MSG_MORE, MSG_FASTOPEN
- sys_mman: MAP_GROWSDOWN, MAP_DENYWRITE, MAP_EXECUTABLE, MAP_LOCKED, MAP_NONBLOCK
- elf/cbindgen.toml: ELFMAG and SELFMAG #defines in after_includes

These headers eliminate the need for shim patches in libwayland (MSG_NOSIGNAL),
mesa (sys/ioccom.h), qtbase (sys/statfs.h, ELFMAG), pipewire/wireplumber
(byteswap.h, MAP_* flags).
This commit is contained in:
Red Bear OS
2026-07-10 14:15:18 +03:00
parent ee3107d873
commit 32df50c8fa
8 changed files with 169 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
#ifndef _BYTESWAP_H
#define _BYTESWAP_H
#include <stdint.h>
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
+47
View File
@@ -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
+2
View File
@@ -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))
+1
View File
@@ -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;
+5
View File
@@ -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;
+5
View File
@@ -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;
+11
View File
@@ -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 = ""
+70
View File
@@ -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<statfs>) -> 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
}