-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcat.rs
67 lines (58 loc) · 1.83 KB
/
cat.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
//! cat - concatenate and print files.
use std::env::args;
use std::io;
use a10::fs::OpenOptions;
use a10::io::ReadBufPool;
use a10::{Extract, SubmissionQueue};
mod runtime;
fn main() -> io::Result<()> {
// Create a new I/O uring.
let mut ring = a10::Ring::new(1)?;
// Get our copy of the submission queue.
let sq = ring.submission_queue().clone();
// Collect the files we want to concatenate.
let mut filenames: Vec<String> = args().skip(1).collect();
// Default to reading from standard in.
if filenames.is_empty() {
filenames.push(String::from("-"));
}
// Run our cat program.
runtime::block_on(&mut ring, cat(sq, filenames))
}
async fn cat(sq: SubmissionQueue, filenames: Vec<String>) -> io::Result<()> {
let stdout = a10::io::stdout(sq.clone());
// Read and write 8 pages at a time.
let buf_pool = ReadBufPool::new(sq.clone(), 1, 8 * 4096)?;
let mut buf = buf_pool.get();
let mut n;
for filename in filenames {
let stdin;
let file;
let file = if filename == "-" {
stdin = a10::io::stdin(sq.clone());
&*stdin
} else {
file = OpenOptions::new().open(sq.clone(), filename.into()).await?;
&file
};
loop {
buf.release();
buf = file.read(buf).await?;
if buf.is_empty() {
// Read the entire file.
break;
}
loop {
(buf, n) = stdout.write(buf).extract().await?;
if n == buf.len() {
// Written all the bytes, try reading again.
break;
} else {
// Remove the bytes we've already written and try again.
buf.remove(..n);
}
}
}
}
Ok(())
}