1 // Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // SPDX-License-Identifier: BSD-3-Clause 3 4 //! Wrapper for interpreting syscall exit codes. 5 6 use std::os::raw::c_int; 7 8 /// Wrapper to interpret syscall exit codes and provide a rustacean `io::Result`. 9 #[derive(Debug)] 10 pub struct SyscallReturnCode<T: From<i8> + Eq = c_int>(pub T); 11 12 impl<T: From<i8> + Eq> SyscallReturnCode<T> { 13 /// Returns the last OS error if value is -1 or Ok(value) otherwise. into_result(self) -> std::io::Result<T>14 pub fn into_result(self) -> std::io::Result<T> { 15 if self.0 == T::from(-1) { 16 Err(std::io::Error::last_os_error()) 17 } else { 18 Ok(self.0) 19 } 20 } 21 /// Returns the last OS error if value is -1 or Ok(()) otherwise. into_empty_result(self) -> std::io::Result<()>22 pub fn into_empty_result(self) -> std::io::Result<()> { 23 self.into_result().map(|_| ()) 24 } 25 } 26 27 #[cfg(test)] 28 mod tests { 29 use super::*; 30 31 #[test] test_syscall_ops()32 fn test_syscall_ops() { 33 let mut syscall_code = SyscallReturnCode(1); 34 match syscall_code.into_result() { 35 Ok(_value) => (), 36 _ => unreachable!(), 37 } 38 39 syscall_code = SyscallReturnCode(-1); 40 assert!(syscall_code.into_result().is_err()); 41 42 syscall_code = SyscallReturnCode(1); 43 match syscall_code.into_empty_result() { 44 Ok(()) => (), 45 _ => unreachable!(), 46 } 47 48 syscall_code = SyscallReturnCode(-1); 49 assert!(syscall_code.into_empty_result().is_err()); 50 51 let mut syscall_code_long = SyscallReturnCode(1i64); 52 match syscall_code_long.into_result() { 53 Ok(_value) => (), 54 _ => unreachable!(), 55 } 56 57 syscall_code_long = SyscallReturnCode(-1i64); 58 assert!(syscall_code_long.into_result().is_err()); 59 } 60 } 61