| 1 | //! This is just a sample of what FFI using this crate can look like. |
| 2 | |
| 3 | #![cfg_attr (not(io_safety_is_in_std), allow(unused_imports))] |
| 4 | #![allow (missing_docs)] |
| 5 | |
| 6 | #[cfg (any(unix, target_os = "wasi" , target_os = "hermit" ))] |
| 7 | use crate::{BorrowedFd, OwnedFd}; |
| 8 | #[cfg (windows)] |
| 9 | use crate::{BorrowedHandle, HandleOrInvalid}; |
| 10 | |
| 11 | #[cfg (any(unix, target_os = "wasi" , target_os = "hermit" ))] |
| 12 | use libc::{c_char, c_int, c_void, size_t, ssize_t}; |
| 13 | #[cfg (windows)] |
| 14 | use { |
| 15 | core::ffi::c_void, |
| 16 | windows_sys::core::PCWSTR, |
| 17 | windows_sys::Win32::Foundation::BOOL, |
| 18 | windows_sys::Win32::Security::SECURITY_ATTRIBUTES, |
| 19 | windows_sys::Win32::Storage::FileSystem::{ |
| 20 | FILE_CREATION_DISPOSITION, FILE_FLAGS_AND_ATTRIBUTES, FILE_SHARE_MODE, |
| 21 | }, |
| 22 | windows_sys::Win32::System::IO::OVERLAPPED, |
| 23 | }; |
| 24 | |
| 25 | // Declare a few FFI functions ourselves, to show off the FFI ergonomics. |
| 26 | #[cfg (all( |
| 27 | io_safety_is_in_std, |
| 28 | any(unix, target_os = "wasi" , target_os = "hermit" ) |
| 29 | ))] |
| 30 | unsafeextern "C" { |
| 31 | pub unsafefn open(pathname: *const c_char, flags: c_int, ...) -> Option<OwnedFd>; |
| 32 | } |
| 33 | #[cfg (any(unix, target_os = "wasi" ))] |
| 34 | unsafeextern "C" { |
| 35 | pub unsafefn read(fd: BorrowedFd<'_>, ptr: *mut c_void, size: size_t) -> ssize_t; |
| 36 | pub unsafefn write(fd: BorrowedFd<'_>, ptr: *const c_void, size: size_t) -> ssize_t; |
| 37 | } |
| 38 | #[cfg (any(unix, target_os = "wasi" ))] |
| 39 | pub use libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY}; |
| 40 | |
| 41 | // The Windows analogs of the above. Note the use of [`HandleOrInvalid`] as |
| 42 | // the return type for `CreateFileW`, since that function is defined to return |
| 43 | // [`INVALID_HANDLE_VALUE`] on error instead of null. |
| 44 | #[cfg (windows)] |
| 45 | extern "system" { |
| 46 | pub fn CreateFileW( |
| 47 | lpfilename: PCWSTR, |
| 48 | dwdesiredaccess: u32, |
| 49 | dwsharemode: FILE_SHARE_MODE, |
| 50 | lpsecurityattributes: *const SECURITY_ATTRIBUTES, |
| 51 | dwcreationdisposition: FILE_CREATION_DISPOSITION, |
| 52 | dwflagsandattributes: FILE_FLAGS_AND_ATTRIBUTES, |
| 53 | htemplatefile: HANDLE, |
| 54 | ) -> HandleOrInvalid; |
| 55 | pub fn ReadFile( |
| 56 | hfile: BorrowedHandle<'_>, |
| 57 | lpbuffer: *mut c_void, |
| 58 | nnumberofbytestoread: u32, |
| 59 | lpnumberofbytesread: *mut u32, |
| 60 | lpoverlapped: *mut OVERLAPPED, |
| 61 | ) -> BOOL; |
| 62 | pub fn WriteFile( |
| 63 | hfile: BorrowedHandle<'_>, |
| 64 | lpbuffer: *const c_void, |
| 65 | nnumberofbytestowrite: u32, |
| 66 | lpnumberofbyteswritten: *mut u32, |
| 67 | lpoverlapped: *mut OVERLAPPED, |
| 68 | ) -> BOOL; |
| 69 | } |
| 70 | |
| 71 | #[cfg (windows)] |
| 72 | pub use { |
| 73 | windows_sys::Win32::Foundation::HANDLE, |
| 74 | windows_sys::Win32::Storage::FileSystem::{ |
| 75 | CREATE_ALWAYS, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, FILE_GENERIC_READ, FILE_GENERIC_WRITE, |
| 76 | OPEN_EXISTING, |
| 77 | }, |
| 78 | }; |
| 79 | |