-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathhello.rs
126 lines (108 loc) · 3.77 KB
/
hello.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! A simple testcase that prints a few messages to the console, demonstrating
//! the io-lifetimes API.
#[cfg(feature = "close")]
use io_lifetimes::example_ffi::*;
#[cfg(feature = "close")]
use std::{
fs::File,
io::{self, Write},
};
#[cfg(all(unix, feature = "close"))]
use io_lifetimes::{AsFd, OwnedFd};
#[cfg(all(windows, feature = "close"))]
use io_lifetimes::{AsHandle, OwnedHandle};
#[cfg(all(windows, feature = "close"))]
use std::{os::windows::io::RawHandle, ptr::null_mut};
#[cfg(all(unix, feature = "close"))]
fn main() -> io::Result<()> {
let fd = unsafe {
// Open a file, which returns an `Option<OwnedFd>`, which we can
// maybe convert into an `OwnedFile`.
let fd: OwnedFd = open("/dev/stdout\0".as_ptr() as *const _, O_WRONLY | O_CLOEXEC)
.ok_or_else(io::Error::last_os_error)?;
// Borrow the fd to write to it.
let result = write(fd.as_fd(), "hello, world\n".as_ptr() as *const _, 13);
match result {
-1 => return Err(io::Error::last_os_error()),
13 => (),
_ => return Err(io::Error::new(io::ErrorKind::Other, "short write")),
}
fd
};
// Convert into a `File`. No `unsafe` here!
let mut file = File::from(fd);
writeln!(&mut file, "greetings, y'all")?;
// We can borrow a `BorrowedFd` from a `File`.
unsafe {
let result = write(file.as_fd(), "sup?\n".as_ptr() as *const _, 5);
match result {
-1 => return Err(io::Error::last_os_error()),
5 => (),
_ => return Err(io::Error::new(io::ErrorKind::Other, "short write")),
}
}
// `OwnedFd` closes the fd in its `Drop` implementation.
Ok(())
}
/// The Windows analog of the above.
#[cfg(all(windows, feature = "close"))]
fn main() -> io::Result<()> {
let handle = unsafe {
// Open a file, which returns an `HandleOrInvalid`, which we can fallibly
// convert into an `OwnedFile`.
let handle: OwnedHandle = CreateFileW(
['C' as u16, 'O' as _, 'N' as _, 0].as_ptr(),
FILE_GENERIC_WRITE,
0,
null_mut(),
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
null_mut() as RawHandle as HANDLE,
)
.try_into()
.map_err(|_err| io::Error::last_os_error())?;
// Borrow the handle to write to it.
let mut number_of_bytes_written = 0;
let result = WriteFile(
handle.as_handle(),
"hello, world\n".as_ptr() as *const _,
13,
&mut number_of_bytes_written,
null_mut(),
);
match (result, number_of_bytes_written) {
(0, _) => return Err(io::Error::last_os_error()),
(_, 13) => (),
(_, _) => return Err(io::Error::new(io::ErrorKind::Other, "short write")),
}
handle
};
// Convert into a `File`. No `unsafe` here!
let mut file = File::from(handle);
writeln!(&mut file, "greetings, y'all")?;
// We can borrow a `BorrowedHandle` from a `File`.
unsafe {
let mut number_of_bytes_written = 0;
let result = WriteFile(
file.as_handle(),
"sup?\n".as_ptr() as *const _,
5,
&mut number_of_bytes_written,
null_mut(),
);
match (result, number_of_bytes_written) {
(0, _) => return Err(io::Error::last_os_error()),
(_, 5) => (),
(_, _) => return Err(io::Error::new(io::ErrorKind::Other, "short write")),
}
}
// `OwnedHandle` closes the handle in its `Drop` implementation.
Ok(())
}
#[cfg(all(
not(all(unix, feature = "close")),
not(all(windows, feature = "close"))
))]
fn main() {
println!("This example requires the \"close\" feature.");
}