11a0216d1Sopenharmony_ci//! A simple testcase that prints a few messages to the console, demonstrating 21a0216d1Sopenharmony_ci//! the io-lifetimes API. 31a0216d1Sopenharmony_ci 41a0216d1Sopenharmony_ci#![cfg_attr(not(io_safety_is_in_std), allow(unused_imports))] 51a0216d1Sopenharmony_ci 61a0216d1Sopenharmony_ci#[cfg(feature = "close")] 71a0216d1Sopenharmony_ciuse io_lifetimes::example_ffi::*; 81a0216d1Sopenharmony_ci#[cfg(feature = "close")] 91a0216d1Sopenharmony_ciuse std::{ 101a0216d1Sopenharmony_ci fs::File, 111a0216d1Sopenharmony_ci io::{self, Write}, 121a0216d1Sopenharmony_ci}; 131a0216d1Sopenharmony_ci 141a0216d1Sopenharmony_ci#[cfg(all(unix, feature = "close"))] 151a0216d1Sopenharmony_ciuse io_lifetimes::{AsFd, OwnedFd}; 161a0216d1Sopenharmony_ci 171a0216d1Sopenharmony_ci#[cfg(all(windows, feature = "close"))] 181a0216d1Sopenharmony_ciuse io_lifetimes::{AsHandle, OwnedHandle}; 191a0216d1Sopenharmony_ci#[cfg(all(windows, feature = "close"))] 201a0216d1Sopenharmony_ciuse std::{convert::TryInto, os::windows::io::RawHandle, ptr::null_mut}; 211a0216d1Sopenharmony_ci 221a0216d1Sopenharmony_ci#[cfg(all(io_safety_is_in_std, unix, feature = "close"))] 231a0216d1Sopenharmony_cifn main() -> io::Result<()> { 241a0216d1Sopenharmony_ci let fd = unsafe { 251a0216d1Sopenharmony_ci // Open a file, which returns an `Option<OwnedFd>`, which we can 261a0216d1Sopenharmony_ci // maybe convert into an `OwnedFile`. 271a0216d1Sopenharmony_ci let fd: OwnedFd = open("/dev/stdout\0".as_ptr() as *const _, O_WRONLY | O_CLOEXEC) 281a0216d1Sopenharmony_ci .ok_or_else(io::Error::last_os_error)?; 291a0216d1Sopenharmony_ci 301a0216d1Sopenharmony_ci // Borrow the fd to write to it. 311a0216d1Sopenharmony_ci let result = write(fd.as_fd(), "hello, world\n".as_ptr() as *const _, 13); 321a0216d1Sopenharmony_ci match result { 331a0216d1Sopenharmony_ci -1 => return Err(io::Error::last_os_error()), 341a0216d1Sopenharmony_ci 13 => (), 351a0216d1Sopenharmony_ci _ => return Err(io::Error::new(io::ErrorKind::Other, "short write")), 361a0216d1Sopenharmony_ci } 371a0216d1Sopenharmony_ci 381a0216d1Sopenharmony_ci fd 391a0216d1Sopenharmony_ci }; 401a0216d1Sopenharmony_ci 411a0216d1Sopenharmony_ci // Convert into a `File`. No `unsafe` here! 421a0216d1Sopenharmony_ci let mut file = File::from(fd); 431a0216d1Sopenharmony_ci writeln!(&mut file, "greetings, y'all")?; 441a0216d1Sopenharmony_ci 451a0216d1Sopenharmony_ci // We can borrow a `BorrowedFd` from a `File`. 461a0216d1Sopenharmony_ci unsafe { 471a0216d1Sopenharmony_ci let result = write(file.as_fd(), "sup?\n".as_ptr() as *const _, 5); 481a0216d1Sopenharmony_ci match result { 491a0216d1Sopenharmony_ci -1 => return Err(io::Error::last_os_error()), 501a0216d1Sopenharmony_ci 5 => (), 511a0216d1Sopenharmony_ci _ => return Err(io::Error::new(io::ErrorKind::Other, "short write")), 521a0216d1Sopenharmony_ci } 531a0216d1Sopenharmony_ci } 541a0216d1Sopenharmony_ci 551a0216d1Sopenharmony_ci // `OwnedFd` closes the fd in its `Drop` implementation. 561a0216d1Sopenharmony_ci 571a0216d1Sopenharmony_ci Ok(()) 581a0216d1Sopenharmony_ci} 591a0216d1Sopenharmony_ci 601a0216d1Sopenharmony_ci/// The Windows analog of the above. 611a0216d1Sopenharmony_ci#[cfg(all(windows, feature = "close"))] 621a0216d1Sopenharmony_cifn main() -> io::Result<()> { 631a0216d1Sopenharmony_ci let handle = unsafe { 641a0216d1Sopenharmony_ci // Open a file, which returns an `HandleOrInvalid`, which we can fallibly 651a0216d1Sopenharmony_ci // convert into an `OwnedFile`. 661a0216d1Sopenharmony_ci let handle: OwnedHandle = CreateFileW( 671a0216d1Sopenharmony_ci ['C' as u16, 'O' as _, 'N' as _, 0].as_ptr(), 681a0216d1Sopenharmony_ci FILE_GENERIC_WRITE, 691a0216d1Sopenharmony_ci 0, 701a0216d1Sopenharmony_ci null_mut(), 711a0216d1Sopenharmony_ci OPEN_EXISTING, 721a0216d1Sopenharmony_ci FILE_ATTRIBUTE_NORMAL, 731a0216d1Sopenharmony_ci null_mut() as RawHandle as HANDLE, 741a0216d1Sopenharmony_ci ) 751a0216d1Sopenharmony_ci .try_into() 761a0216d1Sopenharmony_ci .map_err(|_err| io::Error::last_os_error())?; 771a0216d1Sopenharmony_ci 781a0216d1Sopenharmony_ci // Borrow the handle to write to it. 791a0216d1Sopenharmony_ci let mut number_of_bytes_written = 0; 801a0216d1Sopenharmony_ci let result = WriteFile( 811a0216d1Sopenharmony_ci handle.as_handle(), 821a0216d1Sopenharmony_ci "hello, world\n".as_ptr() as *const _, 831a0216d1Sopenharmony_ci 13, 841a0216d1Sopenharmony_ci &mut number_of_bytes_written, 851a0216d1Sopenharmony_ci null_mut(), 861a0216d1Sopenharmony_ci ); 871a0216d1Sopenharmony_ci match (result, number_of_bytes_written) { 881a0216d1Sopenharmony_ci (0, _) => return Err(io::Error::last_os_error()), 891a0216d1Sopenharmony_ci (_, 13) => (), 901a0216d1Sopenharmony_ci (_, _) => return Err(io::Error::new(io::ErrorKind::Other, "short write")), 911a0216d1Sopenharmony_ci } 921a0216d1Sopenharmony_ci 931a0216d1Sopenharmony_ci handle 941a0216d1Sopenharmony_ci }; 951a0216d1Sopenharmony_ci 961a0216d1Sopenharmony_ci // Convert into a `File`. No `unsafe` here! 971a0216d1Sopenharmony_ci let mut file = File::from(handle); 981a0216d1Sopenharmony_ci writeln!(&mut file, "greetings, y'all")?; 991a0216d1Sopenharmony_ci 1001a0216d1Sopenharmony_ci // We can borrow a `BorrowedHandle` from a `File`. 1011a0216d1Sopenharmony_ci unsafe { 1021a0216d1Sopenharmony_ci let mut number_of_bytes_written = 0; 1031a0216d1Sopenharmony_ci let result = WriteFile( 1041a0216d1Sopenharmony_ci file.as_handle(), 1051a0216d1Sopenharmony_ci "sup?\n".as_ptr() as *const _, 1061a0216d1Sopenharmony_ci 5, 1071a0216d1Sopenharmony_ci &mut number_of_bytes_written, 1081a0216d1Sopenharmony_ci null_mut(), 1091a0216d1Sopenharmony_ci ); 1101a0216d1Sopenharmony_ci match (result, number_of_bytes_written) { 1111a0216d1Sopenharmony_ci (0, _) => return Err(io::Error::last_os_error()), 1121a0216d1Sopenharmony_ci (_, 5) => (), 1131a0216d1Sopenharmony_ci (_, _) => return Err(io::Error::new(io::ErrorKind::Other, "short write")), 1141a0216d1Sopenharmony_ci } 1151a0216d1Sopenharmony_ci } 1161a0216d1Sopenharmony_ci 1171a0216d1Sopenharmony_ci // `OwnedHandle` closes the handle in its `Drop` implementation. 1181a0216d1Sopenharmony_ci 1191a0216d1Sopenharmony_ci Ok(()) 1201a0216d1Sopenharmony_ci} 1211a0216d1Sopenharmony_ci 1221a0216d1Sopenharmony_ci#[cfg(all( 1231a0216d1Sopenharmony_ci not(all(io_safety_is_in_std, unix, feature = "close")), 1241a0216d1Sopenharmony_ci not(all(windows, feature = "close")) 1251a0216d1Sopenharmony_ci))] 1261a0216d1Sopenharmony_cifn main() { 1271a0216d1Sopenharmony_ci println!("On Unix, this example requires Rust >= 1.63 and the \"close\" feature."); 1281a0216d1Sopenharmony_ci} 129