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 | extern "C" { |
31 | pub fn open(pathname: *const c_char, flags: c_int, ...) -> Option<OwnedFd>; |
32 | } |
33 | #[cfg (any(unix, target_os = "wasi" ))] |
34 | extern "C" { |
35 | pub fn read(fd: BorrowedFd<'_>, ptr: *mut c_void, size: size_t) -> ssize_t; |
36 | pub fn 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 | |