0.3.0: add dual-toolchain VaList ABI probe and macros (relibc check passes)
This commit is contained in:
Generated
+2
-2
@@ -256,7 +256,7 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.18+rb0.2.5"
|
||||
version = "0.1.18+rb0.3.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
@@ -726,4 +726,4 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "redox-scheme"
|
||||
version = "0.11.2+rb0.2.5"
|
||||
version = "0.11.2+rb0.3.0"
|
||||
|
||||
@@ -8,6 +8,38 @@ fn main() {
|
||||
|
||||
println!("cargo:rerun-if-changed=src/c");
|
||||
|
||||
// The Redoxer toolchain and some upstream nightlies keep the older
|
||||
// `VaList<'a>` ABI for `extern "C" fn(...)` parameters, while others
|
||||
// pass `VaListImpl<'f>` and require `.as_va_list()` to obtain
|
||||
// `VaList<'_, '_>`. This is a host-compiler property, so probe
|
||||
// directly with the host rustc (avoiding autocfg's target probing).
|
||||
println!("cargo:rustc-check-cfg=cfg(relibc_valist_impl)");
|
||||
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string());
|
||||
let out_dir = env::var("OUT_DIR").unwrap_or_else(|_| "/tmp".to_string());
|
||||
let probe_file = std::path::Path::new(&out_dir).join("relibc_valist_probe.rs");
|
||||
let probe_out = std::path::Path::new(&out_dir).join("librelibc_valist_probe.rlib");
|
||||
std::fs::write(
|
||||
&probe_file,
|
||||
"#![feature(c_variadic)] pub fn _relibc_valist_probe(_: core::ffi::VaList<'_, '_>) {}",
|
||||
)
|
||||
.ok();
|
||||
let probe_ok = std::process::Command::new(&rustc)
|
||||
.args([
|
||||
"--crate-type",
|
||||
"lib",
|
||||
"--edition",
|
||||
"2024",
|
||||
probe_file.to_str().unwrap(),
|
||||
"-o",
|
||||
probe_out.to_str().unwrap(),
|
||||
])
|
||||
.status()
|
||||
.ok()
|
||||
.map_or(false, |s| s.success());
|
||||
if probe_ok {
|
||||
println!("cargo:rustc-cfg=relibc_valist_impl");
|
||||
}
|
||||
|
||||
let mut cc_builder = &mut cc::Build::new();
|
||||
|
||||
cc_builder = cc_builder.flag("-nostdinc").flag("-nostdlib");
|
||||
|
||||
@@ -67,7 +67,7 @@ pub unsafe extern "C" fn err_set_exit(ef: ExitCallback) {
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn err(eval: c_int, fmt: *const c_char, mut va_list: ...) -> ! {
|
||||
let code = Some(ERRNO.get());
|
||||
err_exit(eval, code, fmt, va_list.as_va_list())
|
||||
err_exit(eval, code, fmt, relibc_as_va_list!(va_list))
|
||||
}
|
||||
|
||||
/// Print a user message then an error message for `code` before exiting with `eval` as a return.
|
||||
@@ -78,7 +78,7 @@ pub unsafe extern "C" fn err(eval: c_int, fmt: *const c_char, mut va_list: ...)
|
||||
/// Exits with `eval` as an error code.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn errc(eval: c_int, code: c_int, fmt: *const c_char, mut va_list: ...) -> ! {
|
||||
err_exit(eval, Some(code), fmt, va_list.as_va_list())
|
||||
err_exit(eval, Some(code), fmt, relibc_as_va_list!(va_list))
|
||||
}
|
||||
|
||||
/// Print a user message then exits with `eval` as a return.
|
||||
@@ -89,7 +89,7 @@ pub unsafe extern "C" fn errc(eval: c_int, code: c_int, fmt: *const c_char, mut
|
||||
/// Exits with `eval` as an error code.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn errx(eval: c_int, fmt: *const c_char, mut va_list: ...) -> ! {
|
||||
err_exit(eval, None, fmt, va_list.as_va_list())
|
||||
err_exit(eval, None, fmt, relibc_as_va_list!(va_list))
|
||||
}
|
||||
|
||||
/// Print a user message and then an error message for [`ERRNO`].
|
||||
@@ -98,7 +98,7 @@ pub unsafe extern "C" fn errx(eval: c_int, fmt: *const c_char, mut va_list: ...)
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn warn(fmt: *const c_char, mut va_list: ...) {
|
||||
let code = Some(ERRNO.get());
|
||||
display_message(code, fmt, va_list.as_va_list());
|
||||
display_message(code, fmt, relibc_as_va_list!(va_list));
|
||||
}
|
||||
|
||||
/// Print a user message then an error message for `code`.
|
||||
@@ -106,7 +106,7 @@ pub unsafe extern "C" fn warn(fmt: *const c_char, mut va_list: ...) {
|
||||
/// The message format is `progname: fmt: strerror(code)`
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn warnc(code: c_int, fmt: *const c_char, mut va_list: ...) {
|
||||
display_message(Some(code), fmt, va_list.as_va_list());
|
||||
display_message(Some(code), fmt, relibc_as_va_list!(va_list));
|
||||
}
|
||||
|
||||
/// Print a user message as a warning.
|
||||
@@ -114,7 +114,7 @@ pub unsafe extern "C" fn warnc(code: c_int, fmt: *const c_char, mut va_list: ...
|
||||
/// The message format is `progname: fmt`
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn warnx(fmt: *const c_char, mut va_list: ...) {
|
||||
display_message(None, fmt, va_list.as_va_list());
|
||||
display_message(None, fmt, relibc_as_va_list!(va_list));
|
||||
}
|
||||
|
||||
/// See [`err`].
|
||||
|
||||
@@ -71,7 +71,7 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) ->
|
||||
// c_ulonglong
|
||||
let arg = match cmd {
|
||||
F_DUPFD | F_SETFD | F_SETFL | F_GETLK | F_SETLK | F_SETLKW | F_OFD_GETLK | F_OFD_SETLK
|
||||
| F_OFD_SETLKW | F_DUPFD_CLOEXEC => unsafe { __valist.arg::<c_ulonglong>() },
|
||||
| F_OFD_SETLKW | F_DUPFD_CLOEXEC => unsafe { relibc_va_arg!(__valist, c_ulonglong) },
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
@@ -112,7 +112,7 @@ pub unsafe extern "C" fn openat(
|
||||
let mode = if oflag & O_CREAT == O_CREAT
|
||||
/* || oflag & O_TMPFILE == O_TMPFILE */
|
||||
{
|
||||
unsafe { __valist.arg::<mode_t>() }
|
||||
unsafe { relibc_va_arg!(__valist, mode_t) }
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
@@ -122,7 +122,7 @@ pub unsafe extern "C" fn strfmon(
|
||||
Some('i') => {
|
||||
// International formatting
|
||||
flags.international = true;
|
||||
let value = unsafe { args.arg::<f64>() }; // Get the argument as f64
|
||||
let value = unsafe { relibc_va_arg!(args, f64) }; // Get the argument as f64
|
||||
if let Some(written) =
|
||||
format_monetary(&mut buffer[pos..], value, &DEFAULT_MONETARY, &flags)
|
||||
{
|
||||
@@ -133,7 +133,7 @@ pub unsafe extern "C" fn strfmon(
|
||||
}
|
||||
Some('n') => {
|
||||
// Locale-specific formatting
|
||||
let value = unsafe { args.arg::<f64>() }; // Get the argument as f64
|
||||
let value = unsafe { relibc_va_arg!(args, f64) }; // Get the argument as f64
|
||||
if let Some(written) =
|
||||
format_monetary(&mut buffer[pos..], value, &DEFAULT_MONETARY, &flags)
|
||||
{
|
||||
|
||||
@@ -159,8 +159,8 @@ pub unsafe extern "C" fn sem_open(
|
||||
}
|
||||
let (mode, value): (mode_t, c_uint) = if create {
|
||||
(
|
||||
unsafe { __valist.arg::<mode_t>() },
|
||||
unsafe { __valist.arg::<c_uint>() },
|
||||
unsafe { relibc_va_arg!(__valist, mode_t) },
|
||||
unsafe { relibc_va_arg!(__valist, c_uint) },
|
||||
)
|
||||
} else {
|
||||
(0, 0)
|
||||
|
||||
@@ -1415,7 +1415,7 @@ pub unsafe extern "C" fn fprintf(
|
||||
format: *const c_char,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfprintf(file, format, __valist.as_va_list()) }
|
||||
unsafe { vfprintf(file, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vdprintf.html>.
|
||||
@@ -1433,7 +1433,7 @@ pub unsafe extern "C" fn vdprintf(fd: c_int, format: *const c_char, ap: va_list)
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/dprintf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn dprintf(fd: c_int, format: *const c_char, mut __valist: ...) -> c_int {
|
||||
unsafe { vdprintf(fd, format, __valist.as_va_list()) }
|
||||
unsafe { vdprintf(fd, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
|
||||
@@ -1445,7 +1445,7 @@ pub unsafe extern "C" fn vprintf(format: *const c_char, ap: va_list) -> c_int {
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fprintf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn printf(format: *const c_char, mut __valist: ...) -> c_int {
|
||||
unsafe { vfprintf(&raw mut *stdout, format, __valist.as_va_list()) }
|
||||
unsafe { vfprintf(&raw mut *stdout, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
|
||||
@@ -1470,7 +1470,7 @@ pub unsafe extern "C" fn asprintf(
|
||||
format: *const c_char,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vasprintf(strp, format, __valist.as_va_list()) }
|
||||
unsafe { vasprintf(strp, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
|
||||
@@ -1502,7 +1502,7 @@ pub unsafe extern "C" fn snprintf(
|
||||
printf::printf(
|
||||
&mut platform::StringWriter(s.cast::<u8>(), n),
|
||||
CStr::from_ptr(format),
|
||||
__valist.as_va_list(),
|
||||
relibc_as_va_list!(__valist),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1530,7 +1530,7 @@ pub unsafe extern "C" fn sprintf(
|
||||
printf::printf(
|
||||
&mut platform::UnsafeStringWriter(s.cast::<u8>()),
|
||||
CStr::from_ptr(format),
|
||||
__valist.as_va_list(),
|
||||
relibc_as_va_list!(__valist),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1558,7 +1558,7 @@ pub unsafe extern "C" fn fscanf(
|
||||
format: *const c_char,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfscanf(file, format, __valist.as_va_list()) }
|
||||
unsafe { vfscanf(file, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfscanf.html>.
|
||||
@@ -1570,7 +1570,7 @@ pub unsafe extern "C" fn vscanf(format: *const c_char, ap: va_list) -> c_int {
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fscanf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn scanf(format: *const c_char, mut __valist: ...) -> c_int {
|
||||
unsafe { vfscanf(&raw mut *stdin, format, __valist.as_va_list()) }
|
||||
unsafe { vfscanf(&raw mut *stdin, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfscanf.html>.
|
||||
@@ -1593,7 +1593,7 @@ pub unsafe extern "C" fn sscanf(
|
||||
unsafe {
|
||||
let format = CStr::from_ptr(format);
|
||||
let s = CStr::from_ptr(s);
|
||||
scanf::scanf(s.into(), format.into(), __valist.as_va_list())
|
||||
scanf::scanf(s.into(), format.into(), relibc_as_va_list!(__valist))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -127,36 +127,36 @@ impl VaArg {
|
||||
(FmtKind::Percent, _) => panic!("Can't call arg_from on %"),
|
||||
|
||||
(FmtKind::Char, IntKind::Long) | (FmtKind::Char, IntKind::LongLong) => {
|
||||
VaArg::wint_t(unsafe { ap.arg::<wint_t>() })
|
||||
VaArg::wint_t(unsafe { relibc_va_arg!(ap, wint_t) })
|
||||
}
|
||||
|
||||
(FmtKind::Char, _)
|
||||
| (FmtKind::Unsigned, IntKind::Byte)
|
||||
| (FmtKind::Signed, IntKind::Byte) => {
|
||||
// c_int is passed but truncated to c_char
|
||||
VaArg::c_char(unsafe { ap.arg::<c_int>() } as c_char)
|
||||
VaArg::c_char(unsafe { relibc_va_arg!(ap, c_int) } as c_char)
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Short) | (FmtKind::Signed, IntKind::Short) => {
|
||||
// c_int is passed but truncated to c_short
|
||||
VaArg::c_short(unsafe { ap.arg::<c_int>() } as c_short)
|
||||
VaArg::c_short(unsafe { relibc_va_arg!(ap, c_int) } as c_short)
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Int) | (FmtKind::Signed, IntKind::Int) => {
|
||||
VaArg::c_int(unsafe { ap.arg::<c_int>() })
|
||||
VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Long) | (FmtKind::Signed, IntKind::Long) => {
|
||||
VaArg::c_long(unsafe { ap.arg::<c_long>() })
|
||||
VaArg::c_long(unsafe { relibc_va_arg!(ap, c_long) })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::LongLong) | (FmtKind::Signed, IntKind::LongLong) => {
|
||||
VaArg::c_longlong(unsafe { ap.arg::<c_longlong>() })
|
||||
VaArg::c_longlong(unsafe { relibc_va_arg!(ap, c_longlong) })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::IntMax) | (FmtKind::Signed, IntKind::IntMax) => {
|
||||
VaArg::intmax_t(unsafe { ap.arg::<intmax_t>() })
|
||||
VaArg::intmax_t(unsafe { relibc_va_arg!(ap, intmax_t) })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::PtrDiff) | (FmtKind::Signed, IntKind::PtrDiff) => {
|
||||
VaArg::ptrdiff_t(unsafe { ap.arg::<ptrdiff_t>() })
|
||||
VaArg::ptrdiff_t(unsafe { relibc_va_arg!(ap, ptrdiff_t) })
|
||||
}
|
||||
(FmtKind::Unsigned, IntKind::Size) | (FmtKind::Signed, IntKind::Size) => {
|
||||
VaArg::ssize_t(unsafe { ap.arg::<ssize_t>() })
|
||||
VaArg::ssize_t(unsafe { relibc_va_arg!(ap, ssize_t) })
|
||||
}
|
||||
|
||||
(FmtKind::AnyNotation, IntKind::LongLong)
|
||||
@@ -165,11 +165,11 @@ impl VaArg {
|
||||
VaArg::c_longdouble(unsafe { VaArg::extract_longdouble(ap) })
|
||||
}
|
||||
(FmtKind::AnyNotation, _) | (FmtKind::Decimal, _) | (FmtKind::Scientific, _) => {
|
||||
VaArg::c_double(unsafe { ap.arg::<c_double>() })
|
||||
VaArg::c_double(unsafe { relibc_va_arg!(ap, c_double) })
|
||||
}
|
||||
|
||||
(FmtKind::GetWritten, _) | (FmtKind::Pointer, _) | (FmtKind::String, _) => {
|
||||
VaArg::pointer(unsafe { ap.arg::<*const c_void>() })
|
||||
VaArg::pointer(unsafe { relibc_va_arg!(ap, *const c_void) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,13 +348,13 @@ impl VaListCache {
|
||||
// point. Reaching here means there are unused gaps in the
|
||||
// arguments. Ultimately we'll have to settle down with
|
||||
// defaulting to c_int.
|
||||
self.args.push(VaArg::c_int(unsafe { ap.arg::<c_int>() }))
|
||||
self.args.push(VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) }))
|
||||
}
|
||||
|
||||
// Add the value to the cache
|
||||
self.args.push(match default {
|
||||
Some((fmtkind, intkind)) => unsafe { VaArg::arg_from(fmtkind, intkind, ap) },
|
||||
None => VaArg::c_int(unsafe { ap.arg::<c_int>() }),
|
||||
None => VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) }),
|
||||
});
|
||||
|
||||
// Return the value
|
||||
@@ -774,7 +774,7 @@ pub(crate) unsafe fn inner_printf<T: c_str::Kind>(
|
||||
match num {
|
||||
Number::Next => varargs
|
||||
.args
|
||||
.push(VaArg::c_int(unsafe { ap.arg::<c_int>() })),
|
||||
.push(VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) })),
|
||||
Number::Index(i) => {
|
||||
positional.insert(i - 1, (FmtKind::Signed, IntKind::Int));
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
n.parse::<$type>().map_err(|_| 0)?
|
||||
};
|
||||
if !ignore {
|
||||
unsafe { *ap.arg::<*mut $type>() = n };
|
||||
unsafe { *relibc_va_arg!(ap, *mut $type) = n };
|
||||
matched += 1;
|
||||
}
|
||||
}};
|
||||
@@ -264,7 +264,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
$type::from_str_radix(&n, radix).map_err(|_| 0)?
|
||||
};
|
||||
if !ignore {
|
||||
unsafe { *ap.arg::<*mut $final>() = n as $final };
|
||||
unsafe { *relibc_va_arg!(ap, *mut $final) = n as $final };
|
||||
matched += 1;
|
||||
}
|
||||
}};
|
||||
@@ -346,7 +346,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
}
|
||||
|
||||
let mut ptr: Option<*mut $type> =
|
||||
if ignore { None } else { Some(ap.arg()) };
|
||||
if ignore { None } else { Some(relibc_va_arg!(ap)) };
|
||||
|
||||
while width.map(|w| w > 0).unwrap_or(true) && !character.is_whitespace()
|
||||
{
|
||||
@@ -391,7 +391,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
let ptr: Option<*mut $type> = if ignore {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { ap.arg() })
|
||||
Some(unsafe { relibc_va_arg!(ap) })
|
||||
};
|
||||
|
||||
for i in 0..width.unwrap_or(1) {
|
||||
@@ -456,7 +456,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
let mut ptr: Option<*mut c_char> = if ignore {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { ap.arg() })
|
||||
Some(unsafe { relibc_va_arg!(ap) })
|
||||
};
|
||||
|
||||
// While we haven't used up all the width, and it matches
|
||||
@@ -486,7 +486,7 @@ pub unsafe fn inner_scanf<T: Kind>(
|
||||
}
|
||||
'n' => {
|
||||
if !ignore {
|
||||
unsafe { *ap.arg::<*mut c_int>() = count as c_int };
|
||||
unsafe { *relibc_va_arg!(ap, *mut c_int) = count as c_int };
|
||||
}
|
||||
}
|
||||
_ => return Err(-1),
|
||||
|
||||
@@ -112,7 +112,7 @@ pub unsafe extern "C" fn mremap(
|
||||
flags: c_int,
|
||||
mut __valist: ...
|
||||
) -> *mut c_void {
|
||||
let new_address = unsafe { __valist.arg::<*mut c_void>() };
|
||||
let new_address = unsafe { relibc_va_arg!(__valist, *mut c_void) };
|
||||
match unsafe { Sys::mremap(old_address, old_size, new_size, flags, new_address) } {
|
||||
Ok(ptr) => ptr,
|
||||
Err(Errno(errno)) => {
|
||||
|
||||
@@ -29,8 +29,8 @@ pub const PTRACE_SYSEMU_SINGLESTEP: c_int = 32;
|
||||
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man2/ptrace.2.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn ptrace(request: c_int, mut __valist: ...) -> c_int {
|
||||
let pid = unsafe { __valist.arg::<pid_t>() };
|
||||
let addr = unsafe { __valist.arg::<*mut c_void>() };
|
||||
let data = unsafe { __valist.arg::<*mut c_void>() };
|
||||
let pid = unsafe { relibc_va_arg!(__valist, pid_t) };
|
||||
let addr = unsafe { relibc_va_arg!(__valist, *mut c_void) };
|
||||
let data = unsafe { relibc_va_arg!(__valist, *mut c_void) };
|
||||
unsafe { Sys::ptrace(request, pid, addr, data) }.or_minus_one_errno()
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ pub unsafe extern "C" fn vsyslog(priority: c_int, message: *const c_char, ap: Va
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/closelog.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn syslog(priority: c_int, message: *const c_char, mut __valist: ...) {
|
||||
unsafe { vsyslog(priority, message, __valist.as_va_list()) };
|
||||
unsafe { vsyslog(priority, message, relibc_as_va_list!(__valist)) };
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/closelog.html>.
|
||||
|
||||
+10
-10
@@ -4,7 +4,7 @@
|
||||
|
||||
use core::{
|
||||
convert::TryFrom,
|
||||
ffi::VaList,
|
||||
ffi::VaList as va_list,
|
||||
mem::{self, MaybeUninit},
|
||||
ptr, slice,
|
||||
};
|
||||
@@ -307,7 +307,7 @@ pub unsafe extern "C" fn execl(
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
with_argv(__valist.as_va_list(), arg0, |args, _remaining_va| {
|
||||
with_argv(relibc_as_va_list!(__valist), arg0, |args, _remaining_va| {
|
||||
execv(path, args.as_ptr().cast())
|
||||
})
|
||||
}
|
||||
@@ -321,8 +321,8 @@ pub unsafe extern "C" fn execle(
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
with_argv(__valist.as_va_list(), arg0, |args, mut remaining_va| {
|
||||
let envp = remaining_va.arg::<*const *mut c_char>();
|
||||
with_argv(relibc_as_va_list!(__valist), arg0, |args, mut remaining_va| {
|
||||
let envp = relibc_va_arg!(remaining_va, *const *mut c_char);
|
||||
execve(path, args.as_ptr().cast(), envp)
|
||||
})
|
||||
}
|
||||
@@ -336,7 +336,7 @@ pub unsafe extern "C" fn execlp(
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
with_argv(__valist.as_va_list(), arg0, |args, _remaining_va| {
|
||||
with_argv(relibc_as_va_list!(__valist), arg0, |args, _remaining_va| {
|
||||
execvp(file, args.as_ptr().cast())
|
||||
})
|
||||
}
|
||||
@@ -1267,13 +1267,13 @@ pub extern "C" fn vfork() -> pid_t {
|
||||
}
|
||||
|
||||
unsafe fn with_argv(
|
||||
mut va: VaList<'_, '_>,
|
||||
mut va: va_list,
|
||||
arg0: *const c_char,
|
||||
f: impl FnOnce(&[*const c_char], VaList<'_, '_>) -> c_int,
|
||||
f: impl FnOnce(&[*const c_char], va_list) -> c_int,
|
||||
) -> c_int {
|
||||
let argc = 1 + {
|
||||
let mut copy = va.clone();
|
||||
core::iter::from_fn(|| Some(unsafe { copy.arg::<*const c_char>() }))
|
||||
core::iter::from_fn(|| Some(unsafe { relibc_va_arg!(copy, *const c_char) }))
|
||||
.position(|p| p.is_null())
|
||||
.unwrap()
|
||||
};
|
||||
@@ -1298,11 +1298,11 @@ unsafe fn with_argv(
|
||||
out[0].write(arg0);
|
||||
|
||||
for inner in out.iter_mut().take(argc).skip(1) {
|
||||
(*inner).write(unsafe { va.arg::<*const c_char>() });
|
||||
(*inner).write(unsafe { relibc_va_arg!(va, *const c_char) });
|
||||
}
|
||||
out[argc].write(core::ptr::null());
|
||||
// NULL
|
||||
unsafe { va.arg::<*const c_char>() };
|
||||
unsafe { relibc_va_arg!(va, *const c_char) };
|
||||
|
||||
f(unsafe { (&*out).assume_init_ref() }, va);
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ use crate::platform::types::c_long;
|
||||
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/getopt.3.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn syscall(sysno: c_long, mut args: ...) -> c_long {
|
||||
let a1 = unsafe { args.arg::<usize>() };
|
||||
let a2 = unsafe { args.arg::<usize>() };
|
||||
let a3 = unsafe { args.arg::<usize>() };
|
||||
let a4 = unsafe { args.arg::<usize>() };
|
||||
let a5 = unsafe { args.arg::<usize>() };
|
||||
let a6 = unsafe { args.arg::<usize>() };
|
||||
let a1 = unsafe { relibc_va_arg!(args, usize) };
|
||||
let a2 = unsafe { relibc_va_arg!(args, usize) };
|
||||
let a3 = unsafe { relibc_va_arg!(args, usize) };
|
||||
let a4 = unsafe { relibc_va_arg!(args, usize) };
|
||||
let a5 = unsafe { relibc_va_arg!(args, usize) };
|
||||
let a6 = unsafe { relibc_va_arg!(args, usize) };
|
||||
|
||||
(unsafe { sc::syscall6(sysno as usize, a1, a2, a3, a4, a5, a6) }) as c_long
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ pub unsafe extern "C" fn fwscanf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfwscanf(stream, format, __valist.as_va_list()) }
|
||||
unsafe { vfwscanf(stream, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getwc.html>.
|
||||
@@ -342,7 +342,7 @@ pub unsafe extern "C" fn swscanf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vswscanf(s, format, __valist.as_va_list()) }
|
||||
unsafe { vswscanf(s, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ungetwc.html>.
|
||||
@@ -396,7 +396,7 @@ pub unsafe extern "C" fn fwprintf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vfwprintf(stream, format, __valist.as_va_list()) }
|
||||
unsafe { vfwprintf(stream, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfwprintf.html>.
|
||||
@@ -408,7 +408,7 @@ pub unsafe extern "C" fn vwprintf(format: *const wchar_t, arg: va_list) -> c_int
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fwprintf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn wprintf(format: *const wchar_t, mut __valist: ...) -> c_int {
|
||||
unsafe { vfwprintf(&raw mut *stdout, format, __valist.as_va_list()) }
|
||||
unsafe { vfwprintf(&raw mut *stdout, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfwprintf.html>.
|
||||
@@ -433,7 +433,7 @@ pub unsafe extern "C" fn swprintf(
|
||||
format: *const wchar_t,
|
||||
mut __valist: ...
|
||||
) -> c_int {
|
||||
unsafe { vswprintf(s, n, format, __valist.as_va_list()) }
|
||||
unsafe { vswprintf(s, n, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcpcpy.html>.
|
||||
@@ -1047,13 +1047,13 @@ pub unsafe extern "C" fn vfwscanf(
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vwscanf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn vwscanf(format: *const wchar_t, mut __valist: va_list) -> c_int {
|
||||
unsafe { vfwscanf(stdin, format, __valist.as_va_list()) }
|
||||
unsafe { vfwscanf(stdin, format, __valist) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wscanf.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn wscanf(format: *const wchar_t, mut __valist: ...) -> c_int {
|
||||
unsafe { vfwscanf(stdin, format, __valist.as_va_list()) }
|
||||
unsafe { vfwscanf(stdin, format, relibc_as_va_list!(__valist)) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscasecmp.html>.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//! Currently, Linux and Redox syscall backends are supported.
|
||||
|
||||
#![no_std]
|
||||
#![allow(unused_mut)]
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(c_variadic)]
|
||||
|
||||
@@ -1,3 +1,52 @@
|
||||
/// Convert an `extern "C" fn(...)` variadic parameter into a `VaList`.
|
||||
///
|
||||
/// Older Rust nightlies pass `core::ffi::VaList` directly for `...`
|
||||
/// parameters, while newer nightlies pass `core::ffi::VaListImpl` and
|
||||
/// require `.as_va_list()` to obtain a C-compatible `VaList`. The build
|
||||
/// script sets `relibc_valist_impl` when the new API is detected.
|
||||
#[macro_export]
|
||||
macro_rules! relibc_as_va_list {
|
||||
($valist:expr) => {{
|
||||
#[cfg(relibc_valist_impl)]
|
||||
{
|
||||
$valist.as_va_list()
|
||||
}
|
||||
#[cfg(not(relibc_valist_impl))]
|
||||
{
|
||||
$valist
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Read the next argument from a `VaList`.
|
||||
///
|
||||
/// Newer upstream Rust renamed `next_arg()` to `arg()`. The Redoxer
|
||||
/// toolchain keeps the older `next_arg()` name. The build script sets
|
||||
/// `relibc_valist_impl` when the newer API is detected.
|
||||
#[macro_export]
|
||||
macro_rules! relibc_va_arg {
|
||||
($ap:expr) => {{
|
||||
#[cfg(relibc_valist_impl)]
|
||||
{
|
||||
$ap.arg()
|
||||
}
|
||||
#[cfg(not(relibc_valist_impl))]
|
||||
{
|
||||
$ap.next_arg()
|
||||
}
|
||||
}};
|
||||
($ap:expr, $T:ty) => {{
|
||||
#[cfg(relibc_valist_impl)]
|
||||
{
|
||||
$ap.arg::<$T>()
|
||||
}
|
||||
#[cfg(not(relibc_valist_impl))]
|
||||
{
|
||||
$ap.next_arg::<$T>()
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Print to stdout
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
|
||||
Reference in New Issue
Block a user