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:
@@ -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
|
||||
@@ -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
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = ""
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user