Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: str: introduce `kstrtobool` function

Add a Rust wrapper for the kernel's `kstrtobool` function that converts
common user inputs into boolean values.

Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250902-rnull-up-v6-16-v7-5-b5212cc89b98@kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Andreas Hindborg and committed by
Jens Axboe
b1dae0be cdde7a19

+79
+79
rust/kernel/str.rs
··· 4 4 5 5 use crate::{ 6 6 alloc::{flags::*, AllocError, KVec}, 7 + error::{to_result, Result}, 7 8 fmt::{self, Write}, 8 9 prelude::*, 9 10 }; ··· 919 918 920 919 Ok(()) 921 920 } 921 + } 922 + 923 + /// # Safety 924 + /// 925 + /// - `string` must point to a null terminated string that is valid for read. 926 + unsafe fn kstrtobool_raw(string: *const u8) -> Result<bool> { 927 + let mut result: bool = false; 928 + 929 + // SAFETY: 930 + // - By function safety requirement, `string` is a valid null-terminated string. 931 + // - `result` is a valid `bool` that we own. 932 + to_result(unsafe { bindings::kstrtobool(string, &mut result) })?; 933 + Ok(result) 934 + } 935 + 936 + /// Convert common user inputs into boolean values using the kernel's `kstrtobool` function. 937 + /// 938 + /// This routine returns `Ok(bool)` if the first character is one of 'YyTt1NnFf0', or 939 + /// \[oO\]\[NnFf\] for "on" and "off". Otherwise it will return `Err(EINVAL)`. 940 + /// 941 + /// # Examples 942 + /// 943 + /// ``` 944 + /// # use kernel::{c_str, str::kstrtobool}; 945 + /// 946 + /// // Lowercase 947 + /// assert_eq!(kstrtobool(c_str!("true")), Ok(true)); 948 + /// assert_eq!(kstrtobool(c_str!("tr")), Ok(true)); 949 + /// assert_eq!(kstrtobool(c_str!("t")), Ok(true)); 950 + /// assert_eq!(kstrtobool(c_str!("twrong")), Ok(true)); 951 + /// assert_eq!(kstrtobool(c_str!("false")), Ok(false)); 952 + /// assert_eq!(kstrtobool(c_str!("f")), Ok(false)); 953 + /// assert_eq!(kstrtobool(c_str!("yes")), Ok(true)); 954 + /// assert_eq!(kstrtobool(c_str!("no")), Ok(false)); 955 + /// assert_eq!(kstrtobool(c_str!("on")), Ok(true)); 956 + /// assert_eq!(kstrtobool(c_str!("off")), Ok(false)); 957 + /// 958 + /// // Camel case 959 + /// assert_eq!(kstrtobool(c_str!("True")), Ok(true)); 960 + /// assert_eq!(kstrtobool(c_str!("False")), Ok(false)); 961 + /// assert_eq!(kstrtobool(c_str!("Yes")), Ok(true)); 962 + /// assert_eq!(kstrtobool(c_str!("No")), Ok(false)); 963 + /// assert_eq!(kstrtobool(c_str!("On")), Ok(true)); 964 + /// assert_eq!(kstrtobool(c_str!("Off")), Ok(false)); 965 + /// 966 + /// // All caps 967 + /// assert_eq!(kstrtobool(c_str!("TRUE")), Ok(true)); 968 + /// assert_eq!(kstrtobool(c_str!("FALSE")), Ok(false)); 969 + /// assert_eq!(kstrtobool(c_str!("YES")), Ok(true)); 970 + /// assert_eq!(kstrtobool(c_str!("NO")), Ok(false)); 971 + /// assert_eq!(kstrtobool(c_str!("ON")), Ok(true)); 972 + /// assert_eq!(kstrtobool(c_str!("OFF")), Ok(false)); 973 + /// 974 + /// // Numeric 975 + /// assert_eq!(kstrtobool(c_str!("1")), Ok(true)); 976 + /// assert_eq!(kstrtobool(c_str!("0")), Ok(false)); 977 + /// 978 + /// // Invalid input 979 + /// assert_eq!(kstrtobool(c_str!("invalid")), Err(EINVAL)); 980 + /// assert_eq!(kstrtobool(c_str!("2")), Err(EINVAL)); 981 + /// ``` 982 + pub fn kstrtobool(string: &CStr) -> Result<bool> { 983 + // SAFETY: 984 + // - The pointer returned by `CStr::as_char_ptr` is guaranteed to be 985 + // null terminated. 986 + // - `string` is live and thus the string is valid for read. 987 + unsafe { kstrtobool_raw(string.as_char_ptr()) } 988 + } 989 + 990 + /// Convert `&[u8]` to `bool` by deferring to [`kernel::str::kstrtobool`]. 991 + /// 992 + /// Only considers at most the first two bytes of `bytes`. 993 + pub fn kstrtobool_bytes(bytes: &[u8]) -> Result<bool> { 994 + // `ktostrbool` only considers the first two bytes of the input. 995 + let stack_string = [*bytes.first().unwrap_or(&0), *bytes.get(1).unwrap_or(&0), 0]; 996 + // SAFETY: `stack_string` is null terminated and it is live on the stack so 997 + // it is valid for read. 998 + unsafe { kstrtobool_raw(stack_string.as_ptr()) } 922 999 } 923 1000 924 1001 /// An owned string that is guaranteed to have exactly one `NUL` byte, which is at the end.