diff --git a/src/header/err/mod.rs b/src/header/err/mod.rs index 9cc963d4b3..9e2bf400ec 100644 --- a/src/header/err/mod.rs +++ b/src/header/err/mod.rs @@ -17,10 +17,6 @@ //! and an error string for ERRNO. `errc` would operate in the same way except the functions takes //! an error code for which to print an error string. -// Allow is intentional. Almost every line of the simple functions below are unsafe. -// unsafe_op_in_unsafe_fn only adds visual noise or a needless indentation here. -#![allow(unsafe_op_in_unsafe_fn)] - use core::{ ffi::{VaList as va_list, c_char, c_int}, ptr, @@ -46,16 +42,22 @@ static mut error_sink: *mut FILE = ptr::null_mut(); #[unsafe(no_mangle)] pub unsafe extern "C" fn err_set_file(fp: *mut FILE) { if fp.is_null() { - error_sink = stdio::stderr; + unsafe { + error_sink = stdio::stderr; + } } else { - error_sink = fp; + unsafe { + error_sink = fp; + } } } /// Set or remove a callback to invoke before exiting on error. #[unsafe(no_mangle)] pub unsafe extern "C" fn err_set_exit(ef: ExitCallback) { - on_exit = ef; + unsafe { + on_exit = ef; + } } /// Print a user message then an error message for [`ERRNO`] followed by exiting with `eval`. @@ -67,7 +69,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, va_list: ...) -> ! { let code = Some(ERRNO.get()); - err_exit(eval, code, fmt, va_list) + unsafe { err_exit(eval, code, fmt, va_list) } } /// Print a user message then an error message for `code` before exiting with `eval` as a return. @@ -78,7 +80,7 @@ pub unsafe extern "C" fn err(eval: c_int, fmt: *const c_char, 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, va_list: ...) -> ! { - err_exit(eval, Some(code), fmt, va_list) + unsafe { err_exit(eval, Some(code), fmt, va_list) } } /// Print a user message then exits with `eval` as a return. @@ -89,7 +91,7 @@ pub unsafe extern "C" fn errc(eval: c_int, code: c_int, fmt: *const c_char, va_l /// Exits with `eval` as an error code. #[unsafe(no_mangle)] pub unsafe extern "C" fn errx(eval: c_int, fmt: *const c_char, va_list: ...) -> ! { - err_exit(eval, None, fmt, va_list) + unsafe { err_exit(eval, None, fmt, va_list) } } /// Print a user message and then an error message for [`ERRNO`]. @@ -98,7 +100,9 @@ pub unsafe extern "C" fn errx(eval: c_int, fmt: *const c_char, va_list: ...) -> #[unsafe(no_mangle)] pub unsafe extern "C" fn warn(fmt: *const c_char, va_list: ...) { let code = Some(ERRNO.get()); - display_message(code, fmt, va_list); + unsafe { + display_message(code, fmt, va_list); + } } /// Print a user message then an error message for `code`. @@ -106,7 +110,9 @@ pub unsafe extern "C" fn warn(fmt: *const c_char, 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, va_list: ...) { - display_message(Some(code), fmt, va_list); + unsafe { + display_message(Some(code), fmt, va_list); + } } /// Print a user message as a warning. @@ -114,45 +120,55 @@ pub unsafe extern "C" fn warnc(code: c_int, fmt: *const c_char, va_list: ...) { /// The message format is `progname: fmt` #[unsafe(no_mangle)] pub unsafe extern "C" fn warnx(fmt: *const c_char, va_list: ...) { - display_message(None, fmt, va_list); + unsafe { + display_message(None, fmt, va_list); + } } /// See [`err`]. #[unsafe(no_mangle)] pub unsafe extern "C" fn verr(eval: c_int, fmt: *const c_char, args: va_list) -> ! { let code = Some(ERRNO.get()); - err_exit(eval, code, fmt, args); + unsafe { + err_exit(eval, code, fmt, args); + } } /// See [`errc`]. #[unsafe(no_mangle)] pub unsafe extern "C" fn verrc(eval: c_int, code: c_int, fmt: *const c_char, args: va_list) -> ! { - err_exit(eval, Some(code), fmt, args) + unsafe { err_exit(eval, Some(code), fmt, args) } } /// See [`errx`]; #[unsafe(no_mangle)] pub unsafe extern "C" fn verrx(eval: c_int, fmt: *const c_char, args: va_list) -> ! { - err_exit(eval, None, fmt, args) + unsafe { err_exit(eval, None, fmt, args) } } /// See [`warn`]. #[unsafe(no_mangle)] pub unsafe extern "C" fn vwarn(fmt: *const c_char, args: va_list) { let code = Some(ERRNO.get()); - display_message(code, fmt, args); + unsafe { + display_message(code, fmt, args); + } } /// See [`warnc`]. #[unsafe(no_mangle)] pub unsafe extern "C" fn vwarnc(code: c_int, fmt: *const c_char, args: va_list) { - display_message(Some(code), fmt, args); + unsafe { + display_message(Some(code), fmt, args); + } } /// See [`warnx`]. #[unsafe(no_mangle)] pub unsafe extern "C" fn vwarnx(fmt: *const c_char, args: va_list) { - display_message(None, fmt, args); + unsafe { + display_message(None, fmt, args); + } } // Write error messages for err and warn to the currently set sink. @@ -160,45 +176,61 @@ unsafe fn display_message(code: Option, fmt: *const c_char, args: va_list // SAFETY: // * error_sink is only null once on start but otherwise always stderr or a user set file // * User is trusted to pass in a valid file pointer if err_set_file is used - if error_sink.is_null() { - error_sink = stdio::stderr; + if unsafe { error_sink.is_null() } { + unsafe { + error_sink = stdio::stderr; + } } - let sink = error_sink; + let sink = unsafe { error_sink }; // "progname:" is always printed // SAFETY: // * program_invocation_short_name is never null as it is set on start // * program_invocation_short_name is not globally mutable so the user can't mangle it - fprintf( - sink, - c"%s".as_ptr(), - platform::program_invocation_short_name, - ); + unsafe { + fprintf( + sink, + c"%s".as_ptr(), + platform::program_invocation_short_name, + ); + } // Print user message if any if !fmt.is_null() { - fputs(c": ".as_ptr(), sink); - vfprintf(sink, fmt, args); + unsafe { + fputs(c": ".as_ptr(), sink); + vfprintf(sink, fmt, args); + } } // Print error message for non-x functions if let Some(code) = code { - let message = strerror(code); - fprintf(sink, c": %s".as_ptr(), message); + unsafe { + let message = strerror(code); + fprintf(sink, c": %s".as_ptr(), message); + } } // Always write new line - fputc(b'\n'.into(), sink); + unsafe { + fputc(b'\n'.into(), sink); + } } // Write an error message as per err and then exit. unsafe fn err_exit(eval: c_int, code: Option, fmt: *const c_char, args: va_list) -> ! { - display_message(code, fmt, args); - - if let Some(callback) = on_exit { - // errx will hit the unwrap. - callback(code.unwrap_or_else(|| ERRNO.get())); + unsafe { + display_message(code, fmt, args); } - exit(eval); + if let Some(callback) = unsafe { on_exit } { + // errx will hit the unwrap. + unsafe { + callback(code.unwrap_or_else(|| ERRNO.get())); + } + } + + unsafe { + exit(eval); + } }