Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions c-gull/src/nss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,8 @@ unsafe fn getgr_r(
};
let pad = align_of::<*const c_char>() - (buf.addr()) % align_of::<*const c_char>();
buf = buf.add(pad);
buflen -= pad;
let gr_mem = buf.cast::<*mut c_char>();
buf = gr_mem.add(num_members + 1).cast::<c_char>();
buflen -= buf.addr() - gr_mem.addr();

let mut cur_mem = gr_mem;
if num_members != 0 {
Expand All @@ -319,7 +317,6 @@ unsafe fn getgr_r(
buf = buf.add(member.len());
write(buf, 0);
buf = buf.add(1);
buflen -= member.len() + 1;
}
}
write(cur_mem, null_mut());
Expand Down
2 changes: 1 addition & 1 deletion c-scape/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ rand = { version = "0.9.0", default-features = false }
rustix-dlmalloc = { version = "0.2.1", optional = true }
rustix-openpty = "0.2.0"
bitflags = { version = "2.4.1", default-features = false }
printf-compat = { version = "0.2.1", default-features = false }
printf-compat = { version = "0.3.0", default-features = false }
num-complex = { version = "0.4.4", default-features = false, features = ["libm"] }
posix-regex = { version = "0.1.1", features = ["no_std"] }

Expand Down
8 changes: 3 additions & 5 deletions c-scape/src/fs/fcntl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,16 @@ use libc::c_int;
use crate::convert_res;

#[no_mangle]
unsafe extern "C" fn fcntl(fd: c_int, cmd: c_int, mut args: ...) -> c_int {
let args = args.as_va_list();
unsafe extern "C" fn fcntl(fd: c_int, cmd: c_int, args: ...) -> c_int {
_fcntl::<libc::flock>(fd, cmd, args)
}

#[no_mangle]
unsafe extern "C" fn fcntl64(fd: c_int, cmd: c_int, mut args: ...) -> c_int {
let args = args.as_va_list();
unsafe extern "C" fn fcntl64(fd: c_int, cmd: c_int, args: ...) -> c_int {
_fcntl::<libc::flock64>(fd, cmd, args)
}

unsafe fn _fcntl<FlockTy: Flock>(fd: c_int, cmd: c_int, mut args: VaList<'_, '_>) -> c_int {
unsafe fn _fcntl<FlockTy: Flock>(fd: c_int, cmd: c_int, mut args: VaList<'_>) -> c_int {
match cmd {
libc::F_GETFL => {
libc!(libc::fcntl(fd, libc::F_GETFL));
Expand Down
48 changes: 19 additions & 29 deletions c-scape/src/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,30 +714,24 @@ unsafe fn parse_oflags(mode: *const c_char) -> Option<OFlags> {
}

#[no_mangle]
unsafe extern "C" fn printf(fmt: *const c_char, mut args: ...) -> c_int {
let va_list = args.as_va_list();
vprintf(fmt, va_list)
unsafe extern "C" fn printf(fmt: *const c_char, args: ...) -> c_int {
vprintf(fmt, args)
}

#[no_mangle]
unsafe extern "C" fn vprintf(fmt: *const c_char, va_list: VaList<'_, '_>) -> c_int {
unsafe extern "C" fn vprintf(fmt: *const c_char, va_list: VaList<'_>) -> c_int {
//libc!(libc::vprintf(fmt, va_list));

vfprintf(stdout, fmt, va_list)
}

#[no_mangle]
unsafe extern "C" fn sprintf(ptr: *mut c_char, fmt: *const c_char, mut args: ...) -> c_int {
let va_list = args.as_va_list();
vsprintf(ptr, fmt, va_list)
unsafe extern "C" fn sprintf(ptr: *mut c_char, fmt: *const c_char, args: ...) -> c_int {
vsprintf(ptr, fmt, args)
}

#[no_mangle]
unsafe extern "C" fn vsprintf(
ptr: *mut c_char,
fmt: *const c_char,
va_list: VaList<'_, '_>,
) -> c_int {
unsafe extern "C" fn vsprintf(ptr: *mut c_char, fmt: *const c_char, va_list: VaList<'_>) -> c_int {
//libc!(libc::vsprintf(ptr, fmt, va_list));

let mut out = String::new();
Expand All @@ -762,18 +756,17 @@ unsafe extern "C" fn snprintf(
ptr: *mut c_char,
len: usize,
fmt: *const c_char,
mut args: ...
args: ...
) -> c_int {
let va_list = args.as_va_list();
vsnprintf(ptr, len, fmt, va_list)
vsnprintf(ptr, len, fmt, args)
}

#[no_mangle]
unsafe extern "C" fn vsnprintf(
ptr: *mut c_char,
len: usize,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
//libc!(libc::vsnprintf(ptr, len, fmt, va_list));

Expand All @@ -797,13 +790,12 @@ unsafe extern "C" fn vsnprintf(
}

#[no_mangle]
unsafe extern "C" fn dprintf(fd: c_int, fmt: *const c_char, mut args: ...) -> c_int {
let va_list = args.as_va_list();
vdprintf(fd, fmt, va_list)
unsafe extern "C" fn dprintf(fd: c_int, fmt: *const c_char, args: ...) -> c_int {
vdprintf(fd, fmt, args)
}

#[no_mangle]
unsafe extern "C" fn vdprintf(fd: c_int, fmt: *const c_char, va_list: VaList<'_, '_>) -> c_int {
unsafe extern "C" fn vdprintf(fd: c_int, fmt: *const c_char, va_list: VaList<'_>) -> c_int {
//libc!(libc::vdprintf(fd, fmt, va_list));

let mut out = String::new();
Expand All @@ -830,16 +822,15 @@ unsafe extern "C" fn vdprintf(fd: c_int, fmt: *const c_char, va_list: VaList<'_,
}

#[no_mangle]
unsafe extern "C" fn fprintf(file: *mut libc::FILE, fmt: *const c_char, mut args: ...) -> c_int {
let va_list = args.as_va_list();
vfprintf(file, fmt, va_list)
unsafe extern "C" fn fprintf(file: *mut libc::FILE, fmt: *const c_char, args: ...) -> c_int {
vfprintf(file, fmt, args)
}

#[no_mangle]
unsafe extern "C" fn vfprintf(
file: *mut libc::FILE,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
//libc!(libc::vfprintf(file, fmt, va_list));

Expand All @@ -858,9 +849,9 @@ unsafe extern "C" fn vfprintf(
unsafe extern "C" fn vasprintf(
strp: *mut *mut c_char,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
let len = va_list.with_copy(|va_list| vsnprintf(null_mut(), 0, fmt, va_list));
let len = vsnprintf(null_mut(), 0, fmt, va_list.clone());
if len < 0 {
return -1;
}
Expand All @@ -875,9 +866,8 @@ unsafe extern "C" fn vasprintf(
}

#[no_mangle]
unsafe extern "C" fn asprintf(strp: *mut *mut c_char, fmt: *const c_char, mut args: ...) -> c_int {
let va_list = args.as_va_list();
vasprintf(strp, fmt, va_list)
unsafe extern "C" fn asprintf(strp: *mut *mut c_char, fmt: *const c_char, args: ...) -> c_int {
vasprintf(strp, fmt, args)
}

#[no_mangle]
Expand Down
51 changes: 18 additions & 33 deletions c-scape/src/stdio/chk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ unsafe extern "C" fn __snprintf_chk(
flag: c_int,
slen: size_t,
fmt: *const c_char,
mut args: ...
args: ...
) -> c_int {
let va_list = args.as_va_list();
__vsnprintf_chk(ptr, len, flag, slen, fmt, va_list)
__vsnprintf_chk(ptr, len, flag, slen, fmt, args)
}

// <https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib---vsnprintf-chk-1.html>
Expand All @@ -31,7 +30,7 @@ unsafe extern "C" fn __vsnprintf_chk(
flag: c_int,
slen: size_t,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
if slen < len {
__chk_fail();
Expand All @@ -51,10 +50,9 @@ unsafe extern "C" fn __sprintf_chk(
flag: c_int,
strlen: size_t,
format: *const c_char,
mut args: ...
args: ...
) -> c_int {
let va_list = args.as_va_list();
__vsprintf_chk(ptr, flag, strlen, format, va_list)
__vsprintf_chk(ptr, flag, strlen, format, args)
}

#[no_mangle]
Expand All @@ -63,7 +61,7 @@ unsafe extern "C" fn __vsprintf_chk(
flag: c_int,
strlen: size_t,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
if flag > 0 {
unimplemented!("__USE_FORTIFY_LEVEL > 0");
Expand All @@ -88,10 +86,9 @@ unsafe extern "C" fn __fprintf_chk(
file: *mut libc::FILE,
flag: c_int,
fmt: *const c_char,
mut args: ...
args: ...
) -> c_int {
let va_list = args.as_va_list();
__vfprintf_chk(file, flag, fmt, va_list)
__vfprintf_chk(file, flag, fmt, args)
}

// <https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib---vfprintf-chk-1.html>
Expand All @@ -100,7 +97,7 @@ unsafe extern "C" fn __vfprintf_chk(
file: *mut libc::FILE,
flag: c_int,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
if flag > 0 {
unimplemented!("__USE_FORTIFY_LEVEL > 0");
Expand All @@ -113,17 +110,12 @@ unsafe extern "C" fn __vfprintf_chk(

// <https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib---printf-chk-1.html>
#[no_mangle]
unsafe extern "C" fn __printf_chk(flag: c_int, fmt: *const c_char, mut args: ...) -> c_int {
let va_list = args.as_va_list();
__vprintf_chk(flag, fmt, va_list)
unsafe extern "C" fn __printf_chk(flag: c_int, fmt: *const c_char, args: ...) -> c_int {
__vprintf_chk(flag, fmt, args)
}

#[no_mangle]
unsafe extern "C" fn __vprintf_chk(
flag: c_int,
fmt: *const c_char,
va_list: VaList<'_, '_>,
) -> c_int {
unsafe extern "C" fn __vprintf_chk(flag: c_int, fmt: *const c_char, va_list: VaList<'_>) -> c_int {
if flag > 0 {
unimplemented!("__USE_FORTIFY_LEVEL > 0");
}
Expand All @@ -138,18 +130,17 @@ unsafe extern "C" fn __asprintf_chk(
strp: *mut *mut c_char,
flag: c_int,
fmt: *const c_char,
mut args: ...
args: ...
) -> c_int {
let va_list = args.as_va_list();
__vasprintf_chk(strp, flag, fmt, va_list)
__vasprintf_chk(strp, flag, fmt, args)
}

#[no_mangle]
unsafe extern "C" fn __vasprintf_chk(
strp: *mut *mut c_char,
flag: c_int,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
if flag > 0 {
unimplemented!("__USE_FORTIFY_LEVEL > 0");
Expand All @@ -159,22 +150,16 @@ unsafe extern "C" fn __vasprintf_chk(
}

#[no_mangle]
unsafe extern "C" fn __dprintf_chk(
fd: c_int,
flag: c_int,
fmt: *const c_char,
mut args: ...
) -> c_int {
let va_list = args.as_va_list();
__vdprintf_chk(fd, flag, fmt, va_list)
unsafe extern "C" fn __dprintf_chk(fd: c_int, flag: c_int, fmt: *const c_char, args: ...) -> c_int {
__vdprintf_chk(fd, flag, fmt, args)
}

#[no_mangle]
unsafe extern "C" fn __vdprintf_chk(
fd: c_int,
flag: c_int,
fmt: *const c_char,
va_list: VaList<'_, '_>,
va_list: VaList<'_>,
) -> c_int {
if flag > 0 {
unimplemented!("__USE_FORTIFY_LEVEL > 0");
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-04-28"
channel = "nightly-2025-12-07"
components = ["rustc", "cargo", "rust-std", "rust-src", "rustfmt"]
57 changes: 50 additions & 7 deletions tests/example_crates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,57 @@ fn example_crate_c_scape_unwinding() {

#[test]
fn example_crate_c_gull_unwinding() {
test_crate(
"c-gull-unwinding",
&[],
&[("RUST_BACKTRACE", "0")],
"Hello, world!\nHello world using libc `printf`!\n",
"\nthread 'main' panicked at src/main.rs:18:5:\ncatch me!\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n",
None,
// Note: Rust's default unwind now prints a message with the process's PID. The assert_cmd
// command does not let us get the child's PID. So we have to use the std::process::Command API
// instead.
use std::process::Command;
use std::process::Stdio;

#[cfg(target_arch = "x86_64")]
let arch = "x86_64";
#[cfg(target_arch = "aarch64")]
let arch = "aarch64";
#[cfg(target_arch = "riscv64")]
let arch = "riscv64gc";
#[cfg(target_arch = "x86")]
let arch = "i686";
#[cfg(target_arch = "arm")]
let arch = "armv5te";
#[cfg(target_env = "gnueabi")]
let env = "gnueabi";
#[cfg(all(target_env = "gnu", target_abi = "eabi"))]
let env = "gnueabi";
#[cfg(all(target_env = "gnu", not(target_abi = "eabi")))]
let env = "gnu";

let mut command = Command::new("cargo");
command.arg("run").arg("--quiet");
command.arg(&format!("--target={}-unknown-linux-{}", arch, env));

command.env("RUST_BACKTRACE", "0");
command.current_dir("example-crates/c-gull-unwinding");

command.stdout(Stdio::piped());
command.stderr(Stdio::piped());

let child = command.spawn().unwrap();
let pid = child.id();
let output = child.wait_with_output().unwrap();

assert_eq!(
std::str::from_utf8(&output.stdout).unwrap(),
"Hello, world!\nHello world using libc `printf`!\n"
);
assert_eq!(
std::str::from_utf8(&output.stderr).unwrap(),
format!(
"\nthread 'main' ({pid}) panicked at src/main.rs:18:5:\n\
catch me!\n\
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n"
)
.as_str()
);
assert!(output.status.success());
}

#[test]
Expand Down