Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • martin/relibc
  • ashton/relibc
  • vincent/relibc
  • boomshroom/relibc
  • njskalski/relibc
  • microcolonel/relibc
  • gmacd/relibc
  • feliwir/relibc
  • devnexen/relibc
  • jamesgraves/relibc
  • oddcoder/relibc
  • andar1an/relibc
  • gugz0r/relibc
  • matijaskala/relibc
  • zen3ger/relibc
  • Majoneza/relibc
  • 4lDO2/relibc
  • enygmator/relibc
  • JustAnotherDev/relibc
  • doriancodes/relibc
  • adamantinum/relibc
  • wiredtv/relibc
  • stratact/relibc
  • Ramla-I/relibc
  • bitstr0m/relibc
  • bpisch/relibc
  • henritel/relibc
  • smckay/relibc
  • xTibor/relibc
  • devajithvs/relibc
  • andypython/relibc
  • t-nil/relibc
  • DataTriny/relibc
  • SteveLauC/relibc
  • dlrobertson/relibc
  • AgostonSzepessy/relibc
  • TheDarkula/relibc
  • willnode/relibc
  • bamontan/relibc
  • redoxeon/relibc
  • darley/relibc
  • ayf/relibc
  • heghe/relibc
  • Ivan/relibc
  • hasheddan/relibc
  • dahc/relibc
  • auwardoctor/relibc
  • kodicraft/relibc
  • arthurpaulino/relibc
  • jasonhansel/relibc
  • kel/relibc
  • GrayJack/relibc
  • sahitpj/relibc
  • plimkilde/relibc
  • BjornTheProgrammer/relibc
  • defra/relibc
  • Schyrsivochter/relibc
  • ebalalic/relibc
  • josh/relibc
  • adchacon/relibc
  • aaronjanse/relibc
  • josh_williams/relibc
  • 8tab/relibc
  • athei/relibc
  • carrot93/relibc
  • RA_GM1/relibc
  • zhaozhao/relibc
  • JCake/relibc
  • KGrewal1/relibc
  • emturner/relibc
  • LuigiPiucco/relibc
  • bfrascher/relibc
  • starsheriff/relibc
  • kcired/relibc
  • jamespcfrancis/relibc
  • neallred/relibc
  • omar-mohamed-khallaf/relibc
  • jD91mZM2/relibc
  • rw_van/relibc
  • Skallwar/relibc
  • matt-vdv/relibc
  • mati865/relibc
  • SoyaOhnishi/relibc
  • ArniDagur/relibc
  • tlam/relibc
  • glongo/relibc
  • kamirr/relibc
  • abdullah/relibc
  • saeedtabrizi/relibc
  • sajattack/relibc
  • lmiskiew/relibc
  • seanpk/relibc
  • MaikuZ/relibc
  • jamadazi/relibc
  • coolreader18/relibc
  • wt/relibc
  • lebensterben/relibc
  • redox-os/relibc
  • nicoan/relibc
  • uuuvn/relibc
  • vadorovsky/relibc
  • ids1024/relibc
  • raffaeleragni/relibc
  • freewilll/relibc
  • LLeny/relibc
  • alfredoyang/relibc
  • batonius/relibc
  • TornaxO7/relibc
  • bjorn3/relibc
  • Arcterus/relibc
  • Tommoa/relibc
  • samuela/relibc
  • mindriot101/relibc
  • lygstate/relibc
114 results
Show changes
Showing
with 401 additions and 153 deletions
[toolchain]
channel = "nightly-2024-05-11"
channel = "nightly-2025-01-12"
components = ["rust-src"]
//! Nul-terminated byte strings.
use core::{marker::PhantomData, ptr::NonNull, str::Utf8Error};
use alloc::{
......@@ -49,7 +51,7 @@ impl<'a> CStr<'a> {
pub fn to_string_lossy(self) -> Cow<'a, str> {
String::from_utf8_lossy(self.to_bytes())
}
pub fn as_ptr(self) -> *const c_char {
pub const fn as_ptr(self) -> *const c_char {
self.ptr.as_ptr()
}
pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &'a [u8]) -> Self {
......@@ -80,6 +82,15 @@ impl<'a> CStr<'a> {
unsafe impl Send for CStr<'_> {}
unsafe impl Sync for CStr<'_> {}
impl From<&core::ffi::CStr> for CStr<'_> {
fn from(s: &core::ffi::CStr) -> Self {
// SAFETY:
// * We can assume that `s` is valid because the caller should have upheld its
// safety concerns when constructing it.
unsafe { Self::from_ptr(s.as_ptr()) }
}
}
#[derive(Debug)]
pub struct FromBytesWithNulError;
......
//! Equivalent of Rust's `Vec<T>`, but using relibc's own allocator.
use crate::{
io::{self, Write},
platform::{self, types::*, WriteByte},
......
......@@ -60,6 +60,17 @@ _start:
"
);
#[cfg(target_arch = "riscv64")]
global_asm!(
"
.globl _start
_start:
mv a0, sp
la t0, relibc_start
jalr ra, t0
"
);
#[linkage = "weak"]
#[no_mangle]
extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
......
......@@ -72,6 +72,8 @@ global_asm!(
"#
);
// risc-v has no _init / _fini functions; it exclusively uses init/fini arrays
#[linkage = "weak"]
#[no_mangle]
extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
......
......@@ -58,6 +58,8 @@ global_asm!(
"#
);
// risc-v has no _init / _fini functions; it exclusively uses init/fini arrays
#[linkage = "weak"]
#[no_mangle]
extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
......
use alloc::boxed::Box;
use crate::{header::errno::STR_ERROR, platform::types::c_int};
/// Positive error codes (EINVAL, not -EINVAL).
#[derive(Debug, Eq, PartialEq)]
// TODO: Move to a more generic place.
pub struct Errno(pub c_int);
impl Errno {
pub fn sync(self) -> Self {
crate::platform::ERRNO.set(self.0);
self
}
}
pub type Result<T, E = Errno> = core::result::Result<T, E>;
#[cfg(target_os = "redox")]
impl From<syscall::Error> for Errno {
#[inline]
fn from(value: syscall::Error) -> Self {
Errno(value.errno)
}
}
#[cfg(target_os = "redox")]
impl From<Errno> for syscall::Error {
#[inline]
fn from(value: Errno) -> Self {
syscall::Error::new(value.0)
}
}
impl From<Errno> for crate::io::Error {
#[inline]
fn from(Errno(errno): Errno) -> Self {
Self::from_raw_os_error(errno)
}
}
// TODO: core::error::Error
impl core::fmt::Display for Errno {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match usize::try_from(self.0).ok().and_then(|i| STR_ERROR.get(i)) {
Some(desc) => write!(f, "{desc}"),
None => write!(f, "unknown error ({})", self.0),
}
}
}
pub trait ResultExt<T> {
fn or_minus_one_errno(self) -> T;
}
impl<T: From<i8>> ResultExt<T> for Result<T, Errno> {
fn or_minus_one_errno(self) -> T {
match self {
Self::Ok(v) => v,
Self::Err(Errno(errno)) => {
crate::platform::ERRNO.set(errno);
T::from(-1)
}
}
}
}
pub trait ResultExtPtrMut<T> {
fn or_errno_null_mut(self) -> *mut T;
}
impl<T> ResultExtPtrMut<T> for Result<*mut T, Errno> {
fn or_errno_null_mut(self) -> *mut T {
match self {
Self::Ok(ptr) => ptr,
Self::Err(Errno(errno)) => {
crate::platform::ERRNO.set(errno);
core::ptr::null_mut()
}
}
}
}
impl<T> ResultExtPtrMut<T> for Result<Box<T>, Errno> {
fn or_errno_null_mut(self) -> *mut T {
match self {
Self::Ok(ptr) => Box::into_raw(ptr),
Self::Err(Errno(errno)) => {
crate::platform::ERRNO.set(errno);
core::ptr::null_mut()
}
}
}
}
use crate::{
c_str::CStr,
error::{Errno, ResultExt},
header::{
fcntl::O_CREAT,
unistd::{SEEK_CUR, SEEK_END, SEEK_SET},
},
io,
platform::{types::*, Pal, Sys},
pthread::ResultExt,
};
use core::ops::Deref;
......@@ -25,39 +25,28 @@ impl File {
}
}
pub fn open(path: CStr, oflag: c_int) -> io::Result<Self> {
match Sys::open(path, oflag, 0) {
-1 => Err(io::last_os_error()),
ok => Ok(Self::new(ok)),
}
pub fn open(path: CStr, oflag: c_int) -> Result<Self, Errno> {
Sys::open(path, oflag, 0)
.map(Self::new)
.map_err(Errno::sync)
}
pub fn create(path: CStr, oflag: c_int, mode: mode_t) -> io::Result<Self> {
match Sys::open(path, oflag | O_CREAT, mode) {
-1 => Err(io::last_os_error()),
ok => Ok(Self::new(ok)),
}
pub fn create(path: CStr, oflag: c_int, mode: mode_t) -> Result<Self, Errno> {
Sys::open(path, oflag | O_CREAT, mode)
.map(Self::new)
.map_err(Errno::sync)
}
pub fn sync_all(&self) -> io::Result<()> {
match Sys::fsync(self.fd) {
-1 => Err(io::last_os_error()),
_ok => Ok(()),
}
pub fn sync_all(&self) -> Result<(), Errno> {
Sys::fsync(self.fd).map_err(Errno::sync)
}
pub fn set_len(&self, size: u64) -> io::Result<()> {
match Sys::ftruncate(self.fd, size as off_t) {
-1 => Err(io::last_os_error()),
_ok => Ok(()),
}
pub fn set_len(&self, size: u64) -> Result<(), Errno> {
Sys::ftruncate(self.fd, size as off_t).map_err(Errno::sync)
}
pub fn try_clone(&self) -> io::Result<Self> {
match Sys::dup(self.fd) {
-1 => Err(io::last_os_error()),
ok => Ok(Self::new(ok)),
}
Ok(Self::new(Sys::dup(self.fd)?))
}
/// Create a new file pointing to the same underlying descriptor. This file
......@@ -73,7 +62,7 @@ impl File {
impl io::Read for &File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match Sys::read(self.fd, buf).or_minus_one_errno() /* TODO */ {
match Sys::read(self.fd, buf).map(|read| read as ssize_t).or_minus_one_errno() /* TODO */ {
-1 => Err(io::last_os_error()),
ok => Ok(ok as usize),
}
......@@ -82,7 +71,10 @@ impl io::Read for &File {
impl io::Write for &File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match Sys::write(self.fd, buf).or_minus_one_errno() {
match Sys::write(self.fd, buf)
.map(|read| read as ssize_t)
.or_minus_one_errno()
{
-1 => Err(io::last_os_error()),
ok => Ok(ok as usize),
}
......@@ -101,10 +93,7 @@ impl io::Seek for &File {
io::SeekFrom::End(end) => (end as off_t, SEEK_END),
};
match Sys::lseek(self.fd, offset, whence) {
-1 => Err(io::last_os_error()),
ok => Ok(ok as u64),
}
Ok(Sys::lseek(self.fd, offset, whence)? as u64)
}
}
......
......@@ -20,7 +20,7 @@ pub type elf_gregset_t = [c_ulong; 34];
pub type elf_fpregset_t = user_fpsimd_struct;
#[no_mangle]
pub extern "C" fn _cbindgen_only_generates_structs_if_they_are_mentioned_which_is_dumb_aarch64_user(
pub extern "C" fn _cbindgen_export_aarch64_user(
a: user_regs_struct,
b: user_fpsimd_struct,
c: elf_gregset_t,
......
sys_includes = []
include_guard = "_RISCV64_USER_H"
language = "C"
style = "Tag"
[enum]
prefix_with_name = true
use crate::platform::types::*;
#[repr(C)]
pub struct user_regs_struct {
pub regs: [c_ulong; 31], // x1-x31
pub pc: c_ulong,
}
#[repr(C)]
pub struct user_fpregs_f_struct {
pub fpregs: [c_float; 32],
pub fcsr: c_uint,
}
#[repr(C)]
pub struct user_fpregs_g_struct {
pub fpregs: [c_double; 32],
pub fcsr: c_uint,
}
#[repr(C)]
pub struct user_fpregs_struct {
pub f_regs: user_fpregs_f_struct,
pub g_regs: user_fpregs_g_struct,
}
pub type elf_greg_t = c_ulong;
pub type elf_gregset_t = user_regs_struct;
pub type elf_fpregset_t = user_fpregs_struct;
#[no_mangle]
pub extern "C" fn _cbindgen_only_generates_structs_if_they_are_mentioned_which_is_dumb_riscv64_user(
a: user_regs_struct,
b: user_fpregs_struct,
c: elf_gregset_t,
d: elf_greg_t,
e: elf_fpregset_t,
) {
}
......@@ -72,7 +72,7 @@ pub struct user {
}
#[no_mangle]
pub extern "C" fn _cbindgen_only_generates_structs_if_they_are_mentioned_which_is_dumb_x86_user(
pub extern "C" fn _cbindgen_export_x86_user(
a: user_fpregs_struct,
b: user_regs_struct,
c: user,
......
//! arpa/inet implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xns/arpainet.h.html
//! `arpa/inet.h` implementation.
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/arpa_inet.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{
ptr, slice,
......@@ -15,144 +20,192 @@ use crate::{
platform::{self, types::*},
};
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/htonl.html>.
#[no_mangle]
pub extern "C" fn htonl(hostlong: uint32_t) -> uint32_t {
hostlong.to_be()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/htonl.html>.
#[no_mangle]
pub extern "C" fn htons(hostshort: uint16_t) -> uint16_t {
hostshort.to_be()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/inet_addr.html>.
///
/// # Deprecated
/// The `inet_addr()` function was marked obsolescent in the Open Group Base
/// Specifications Issue 8.
#[deprecated]
#[no_mangle]
pub extern "C" fn ntohl(netlong: uint32_t) -> uint32_t {
u32::from_be(netlong)
}
pub unsafe extern "C" fn inet_addr(cp: *const c_char) -> in_addr_t {
let mut val: in_addr = in_addr { s_addr: 0 };
#[no_mangle]
pub extern "C" fn ntohs(netshort: uint16_t) -> uint16_t {
u16::from_be(netshort)
if unsafe { inet_aton(cp, &mut val) } > 0 {
val.s_addr
} else {
INADDR_NONE
}
}
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/inet_aton.3.html>.
#[no_mangle]
pub unsafe extern "C" fn inet_aton(cp: *const c_char, inp: *mut in_addr) -> c_int {
// TODO: octal/hex
inet_pton(AF_INET, cp, inp as *mut c_void)
unsafe { inet_pton(AF_INET, cp, inp as *mut c_void) }
}
/// See <https://pubs.opengroup.org/onlinepubs/7908799/xns/inet_lnaof.html>.
///
/// # Deprecation
/// The `inet_lnaof()` function was specified in Networking Services Issue 5,
/// but not in the Open Group Base Specifications Issue 6 and later.
#[deprecated]
#[no_mangle]
pub unsafe extern "C" fn inet_ntoa(addr: in_addr) -> *const c_char {
static mut NTOA_ADDR: [c_char; 16] = [0; 16];
pub extern "C" fn inet_lnaof(r#in: in_addr) -> in_addr_t {
if r#in.s_addr >> 24 < 128 {
r#in.s_addr & 0xff_ffff
} else if r#in.s_addr >> 24 < 192 {
r#in.s_addr & 0xffff
} else {
r#in.s_addr & 0xff
}
}
/// See <https://pubs.opengroup.org/onlinepubs/7908799/xns/inet_makeaddr.html>.
///
/// # Deprecation
/// The `inet_makeaddr()` function was specified in Networking Services Issue
/// 5, but not in the Open Group Base Specifications Issue 6 and later.
#[deprecated]
#[no_mangle]
pub extern "C" fn inet_makeaddr(net: in_addr_t, lna: in_addr_t) -> in_addr {
let mut output: in_addr = in_addr { s_addr: 0 };
if net < 256 {
output.s_addr = lna | net << 24;
} else if net < 65536 {
output.s_addr = lna | net << 16;
} else {
output.s_addr = lna | net << 8;
}
inet_ntop(
AF_INET,
&addr as *const in_addr as *const c_void,
NTOA_ADDR.as_mut_ptr(),
16,
)
output
}
/// See <https://pubs.opengroup.org/onlinepubs/7908799/xns/inet_netof.html>.
///
/// # Deprecation
/// The `inet_netof()` function was specified in Networking Services Issue 5,
/// but not in the Open Group Base Specifications Issue 6 and later.
#[deprecated]
#[no_mangle]
pub unsafe extern "C" fn inet_pton(domain: c_int, src: *const c_char, dest: *mut c_void) -> c_int {
if domain != AF_INET {
platform::ERRNO.set(EAFNOSUPPORT);
-1
pub extern "C" fn inet_netof(r#in: in_addr) -> in_addr_t {
if r#in.s_addr >> 24 < 128 {
r#in.s_addr & 0xff_ffff
} else if r#in.s_addr >> 24 < 192 {
r#in.s_addr & 0xffff
} else {
let s_addr = slice::from_raw_parts_mut(
&mut (*(dest as *mut in_addr)).s_addr as *mut _ as *mut u8,
4,
);
let src_cstr = CStr::from_ptr(src);
let mut octets = str::from_utf8_unchecked(src_cstr.to_bytes()).split('.');
for i in 0..4 {
if let Some(n) = octets.next().and_then(|x| u8::from_str(x).ok()) {
s_addr[i] = n;
} else {
return 0;
}
}
if octets.next() == None {
1 // Success
} else {
0
}
r#in.s_addr & 0xff
}
}
/// See <https://pubs.opengroup.org/onlinepubs/7908799/xns/inet_network.html>.
///
/// # Deprecation
/// The `inet_network()` function was specified in Networking Services Issue 5,
/// but not in the Open Group Base Specifications Issue 6 and later.
#[deprecated]
#[no_mangle]
pub unsafe extern "C" fn inet_network(cp: *const c_char) -> in_addr_t {
ntohl(unsafe { inet_addr(cp) })
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/inet_addr.html>.
///
/// # Deprecation
/// The `inet_ntoa()` function was marked obsolescent in the Open Group Base
/// Specifications Issue 8.
#[deprecated]
#[no_mangle]
pub unsafe extern "C" fn inet_ntoa(r#in: in_addr) -> *const c_char {
static mut NTOA_ADDR: [c_char; 16] = [0; 16];
unsafe {
inet_ntop(
AF_INET,
&r#in as *const in_addr as *const c_void,
NTOA_ADDR.as_mut_ptr(),
16,
)
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/inet_ntop.html>.
#[no_mangle]
pub unsafe extern "C" fn inet_ntop(
domain: c_int,
af: c_int,
src: *const c_void,
dest: *mut c_char,
dst: *mut c_char,
size: socklen_t,
) -> *const c_char {
if domain != AF_INET {
if af != AF_INET {
platform::ERRNO.set(EAFNOSUPPORT);
ptr::null()
} else if size < 16 {
platform::ERRNO.set(ENOSPC);
ptr::null()
} else {
let s_addr = slice::from_raw_parts(
&(*(src as *const in_addr)).s_addr as *const _ as *const u8,
4,
);
let s_addr = unsafe {
slice::from_raw_parts(
&(*(src as *const in_addr)).s_addr as *const _ as *const u8,
4,
)
};
let addr = format!("{}.{}.{}.{}\0", s_addr[0], s_addr[1], s_addr[2], s_addr[3]);
ptr::copy(addr.as_ptr() as *const c_char, dest, addr.len());
dest
}
}
#[no_mangle]
pub unsafe extern "C" fn inet_addr(cp: *const c_char) -> in_addr_t {
let mut val: in_addr = in_addr { s_addr: 0 };
if inet_aton(cp, &mut val) > 0 {
val.s_addr
} else {
INADDR_NONE
}
}
#[no_mangle]
pub extern "C" fn inet_lnaof(input: in_addr) -> in_addr_t {
if input.s_addr >> 24 < 128 {
input.s_addr & 0xff_ffff
} else if input.s_addr >> 24 < 192 {
input.s_addr & 0xffff
} else {
input.s_addr & 0xff
unsafe {
ptr::copy(addr.as_ptr() as *const c_char, dst, addr.len());
}
dst
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/inet_ntop.html>.
#[no_mangle]
pub extern "C" fn inet_makeaddr(net: in_addr_t, host: in_addr_t) -> in_addr {
let mut output: in_addr = in_addr { s_addr: 0 };
if net < 256 {
output.s_addr = host | net << 24;
} else if net < 65536 {
output.s_addr = host | net << 16;
pub unsafe extern "C" fn inet_pton(af: c_int, src: *const c_char, dst: *mut c_void) -> c_int {
if af != AF_INET {
platform::ERRNO.set(EAFNOSUPPORT);
-1
} else {
output.s_addr = host | net << 8;
let s_addr = unsafe {
slice::from_raw_parts_mut(&mut (*(dst as *mut in_addr)).s_addr as *mut _ as *mut u8, 4)
};
let src_cstr = unsafe { CStr::from_ptr(src) };
let mut octets = unsafe { str::from_utf8_unchecked(src_cstr.to_bytes()).split('.') };
for i in 0..4 {
if let Some(n) = octets.next().and_then(|x| u8::from_str(x).ok()) {
s_addr[i] = n;
} else {
return 0;
}
}
if octets.next() == None {
1 // Success
} else {
0
}
}
output
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/htonl.html>.
#[no_mangle]
pub extern "C" fn inet_netof(input: in_addr) -> in_addr_t {
if input.s_addr >> 24 < 128 {
input.s_addr & 0xff_ffff
} else if input.s_addr >> 24 < 192 {
input.s_addr & 0xffff
} else {
input.s_addr & 0xff
}
pub extern "C" fn ntohl(netlong: uint32_t) -> uint32_t {
u32::from_be(netlong)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/htonl.html>.
#[no_mangle]
pub unsafe extern "C" fn inet_network(cp: *mut c_char) -> in_addr_t {
ntohl(inet_addr(cp))
pub extern "C" fn ntohs(netshort: uint16_t) -> uint16_t {
u16::from_be(netshort)
}
sys_includes = []
sys_includes = ["features.h"]
include_guard = "_RELIBC_ASSERT_H"
trailer = "#include <bits/assert.h>"
language = "C"
......@@ -8,6 +8,3 @@ cpp_compat = true
[enum]
prefix_with_name = true
[fn]
no_return = "__attribute__((noreturn))"
//! assert implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/assert.h.html
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{c_str::CStr, platform::types::*};
#[no_mangle]
......@@ -9,9 +12,9 @@ pub unsafe extern "C" fn __assert_fail(
line: c_int,
cond: *const c_char,
) -> ! {
let func = CStr::from_ptr(func).to_str().unwrap();
let file = CStr::from_ptr(file).to_str().unwrap();
let cond = CStr::from_ptr(cond).to_str().unwrap();
let func = unsafe { CStr::from_ptr(func) }.to_str().unwrap();
let file = unsafe { CStr::from_ptr(file) }.to_str().unwrap();
let cond = unsafe { CStr::from_ptr(cond) }.to_str().unwrap();
eprintln!("{}: {}:{}: Assertion `{}` failed.", func, file, line, cond);
......
......@@ -11,19 +11,19 @@ after_includes = """
#define PTHREAD_ONCE_INIT ((pthread_once_t){0})
#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t){0})
#define pthread_cleanup_push(routine, arg) do { \
struct { \
void (*routine)(void *); \
void *arg; \
void *prev; \
} __relibc_internal_pthread_ll_entry = { \
.routine = (void (*)(void *))(routine), \
.arg = (void *)(arg), \
}; \
#define pthread_cleanup_push(ROUTINE, ARG) do { \\
struct { \\
void (*routine)(void *); \\
void *arg; \\
void *prev; \\
} __relibc_internal_pthread_ll_entry = { \\
.routine = (void (*)(void *))(ROUTINE), \\
.arg = (void *)(ARG), \\
}; \\
__relibc_internal_pthread_cleanup_push(&__relibc_internal_pthread_ll_entry);
#define pthread_cleanup_pop(execute) \
__relibc_internal_pthread_cleanup_pop((execute)); \
#define pthread_cleanup_pop(EXECUTE) \\
__relibc_internal_pthread_cleanup_pop((EXECUTE)); \\
} while(0)
"""
......
//! `crypt.h` implementation.
//!
//! Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/crypt.3.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use ::scrypt::password_hash::{Salt, SaltString};
use alloc::{
ffi::CString,
......@@ -26,6 +33,7 @@ use self::{
sha::{crypt_sha, ShaType::*},
};
/// See <https://www.man7.org/linux/man-pages/man3/crypt.3.html>.
#[repr(C)]
pub struct crypt_data {
initialized: c_int,
......@@ -48,18 +56,21 @@ fn gen_salt() -> Option<String> {
Some(SaltString::encode_b64(&bytes).ok()?.as_str().to_string())
}
/// See <https://www.man7.org/linux/man-pages/man3/crypt.3.html>.
#[no_mangle]
pub unsafe extern "C" fn crypt_r(
key: *const c_char,
setting: *const c_char,
data: *mut crypt_data,
) -> *mut c_char {
if (*data).initialized == 0 {
*data = crypt_data::new();
if unsafe { (*data).initialized } == 0 {
unsafe { *data = crypt_data::new() };
}
let key = CStr::from_ptr(key).to_str().expect("key must be utf-8");
let setting = CStr::from_ptr(setting)
let key = unsafe { CStr::from_ptr(key) }
.to_str()
.expect("key must be utf-8");
let setting = unsafe { CStr::from_ptr(setting) }
.to_str()
.expect("setting must be utf-8");
let setting_bytes = setting.as_bytes();
......@@ -89,8 +100,10 @@ pub unsafe extern "C" fn crypt_r(
let len = inner.len();
if let Ok(ret) = CString::new(inner) {
let ret_ptr = ret.into_raw();
let dst = (*data).buff.as_mut_ptr();
ptr::copy_nonoverlapping(ret_ptr, dst.cast(), len);
let dst = unsafe { (*data).buff }.as_mut_ptr();
unsafe {
ptr::copy_nonoverlapping(ret_ptr, dst.cast(), len);
}
ret_ptr.cast()
} else {
ptr::null_mut()
......
sys_includes = ["bits/ctype.h"]
sys_includes = ["bits/ctype.h", "features.h"]
include_guard = "_RELIBC_CTYPE_H"
language = "C"
style = "Tag"
......
//! ctype implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/ctype.h.html
//! `ctype.h` implementation.
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/ctype.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
// TODO: *_l functions
use crate::platform::types::*;
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isalnum.html>.
#[no_mangle]
pub extern "C" fn isalnum(c: c_int) -> c_int {
c_int::from(isdigit(c) != 0 || isalpha(c) != 0)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isalpha.html>.
#[no_mangle]
pub extern "C" fn isalpha(c: c_int) -> c_int {
c_int::from(islower(c) != 0 || isupper(c) != 0)
}
/// See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/isascii.html>.
///
/// The `isascii()` function was marked obsolescent in the Open Group Base
/// Specifications Issue 7, and removed in Issue 8.
#[deprecated]
#[no_mangle]
pub extern "C" fn isascii(c: c_int) -> c_int {
c_int::from((c & !0x7f) == 0)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isblank.html>.
#[no_mangle]
pub extern "C" fn isblank(c: c_int) -> c_int {
c_int::from(c == c_int::from(b' ') || c == c_int::from(b'\t'))
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/iscntrl.html>.
#[no_mangle]
pub extern "C" fn iscntrl(c: c_int) -> c_int {
c_int::from((c >= 0x00 && c <= 0x1f) || c == 0x7f)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isdigit.html>.
#[no_mangle]
pub extern "C" fn isdigit(c: c_int) -> c_int {
c_int::from(c >= c_int::from(b'0') && c <= c_int::from(b'9'))
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isgraph.html>.
#[no_mangle]
pub extern "C" fn isgraph(c: c_int) -> c_int {
c_int::from(c >= 0x21 && c <= 0x7e)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/islower.html>.
#[no_mangle]
pub extern "C" fn islower(c: c_int) -> c_int {
c_int::from(c >= c_int::from(b'a') && c <= c_int::from(b'z'))
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isprint.html>.
#[no_mangle]
pub extern "C" fn isprint(c: c_int) -> c_int {
c_int::from(c >= 0x20 && c < 0x7f)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ispunct.html>.
#[no_mangle]
pub extern "C" fn ispunct(c: c_int) -> c_int {
c_int::from(
......@@ -57,6 +78,7 @@ pub extern "C" fn ispunct(c: c_int) -> c_int {
)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isspace.html>.
#[no_mangle]
pub extern "C" fn isspace(c: c_int) -> c_int {
c_int::from(
......@@ -69,23 +91,29 @@ pub extern "C" fn isspace(c: c_int) -> c_int {
)
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isupper.html>.
#[no_mangle]
pub extern "C" fn isupper(c: c_int) -> c_int {
c_int::from(c >= c_int::from(b'A') && c <= c_int::from(b'Z'))
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isxdigit.html>.
#[no_mangle]
pub extern "C" fn isxdigit(c: c_int) -> c_int {
c_int::from(isdigit(c) != 0 || (c | 32 >= c_int::from(b'a') && c | 32 <= c_int::from(b'f')))
}
/// See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/toascii.html>.
///
/// The `toascii()` function was marked obsolescent in the Open Group Base
/// Specifications Issue 7, and removed in Issue 8.
#[deprecated]
#[no_mangle]
/// The comment in musl:
/// "nonsense function that should NEVER be used!"
pub extern "C" fn toascii(c: c_int) -> c_int {
c & 0x7f
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tolower.html>.
#[no_mangle]
pub extern "C" fn tolower(c: c_int) -> c_int {
if isupper(c) != 0 {
......@@ -95,6 +123,7 @@ pub extern "C" fn tolower(c: c_int) -> c_int {
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/toupper.html>.
#[no_mangle]
pub extern "C" fn toupper(c: c_int) -> c_int {
if islower(c) != 0 {
......
sys_includes = ["sys/types.h"]
sys_includes = ["sys/types.h", "features.h"]
include_guard = "_RELIBC_DIRENT_H"
language = "C"
style = "Both"
......