use crate::convert_res;
use core::ptr::{null_mut, without_provenance_mut};
use errno::{set_errno, Errno};
use libc::{c_int, c_void, intptr_t};
static mut CURRENT: *mut c_void = null_mut();
#[no_mangle]
unsafe extern "C" fn brk(ptr: *mut c_void) -> c_int {
libc!(libc::brk(ptr));
let new = match convert_res(rustix::runtime::kernel_brk(ptr)) {
Some(new) => new,
None => return -1,
};
if ptr != new {
set_errno(Errno(libc::ENOMEM));
return -1;
}
CURRENT = new;
0
}
#[no_mangle]
unsafe extern "C" fn sbrk(increment: intptr_t) -> *mut c_void {
libc!(libc::sbrk(increment));
let mut old = CURRENT;
if old.is_null() {
old = match convert_res(rustix::runtime::kernel_brk(null_mut())) {
Some(old) => old,
None => return without_provenance_mut(!0),
};
}
if increment == 0 {
CURRENT = old;
return old;
}
let want = old
.cast::<u8>()
.wrapping_add(increment as usize)
.cast::<c_void>();
let ok = if increment > 0 {
want > old
} else {
want < old
};
if !ok {
CURRENT = old;
set_errno(Errno(libc::ENOMEM));
return without_provenance_mut(!0);
}
let new = match convert_res(rustix::runtime::kernel_brk(want)) {
Some(new) => new,
None => {
CURRENT = old;
return without_provenance_mut(!0);
}
};
CURRENT = new;
if new != want {
set_errno(Errno(libc::ENOMEM));
return without_provenance_mut(!0);
}
old
}