Skip to content

Commit c32aee2

Browse files
authored
Merge pull request #16 from RustLangES/feat/runners
2 parents 38423fd + 3d28c9f commit c32aee2

File tree

32 files changed

+802
-156
lines changed

32 files changed

+802
-156
lines changed

Cargo.lock

Lines changed: 101 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/runner/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ authors = ["Apika Luca"]
99
test = true
1010

1111
[dependencies]
12+
async-io = "2.4.1"
1213
hakoniwa = "1.1.0"
1314
lsp-types = "0.97.0"
15+
nix = "0.29.0"
1416
os_pipe = "1.2.1"
1517
thiserror.workspace = true
1618
tokio.workspace = true

backend/runner/src/hakoniwa_ext.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use std::{io::Read, ops, os::fd::AsFd, ptr::read};
2+
3+
use async_io::Async;
4+
use hakoniwa::{Child, ExitStatus};
5+
use nix::{
6+
sys::wait::{self, WaitPidFlag, WaitStatus},
7+
unistd::Pid,
8+
};
9+
10+
pub trait HakoniwaChildExt {
11+
fn try_wait(&self) -> Option<ExitStatus>;
12+
}
13+
14+
impl HakoniwaChildExt for Child {
15+
fn try_wait(&self) -> Option<ExitStatus> {
16+
match wait::waitpid(Pid::from_raw(self.id() as i32), Some(WaitPidFlag::WNOHANG)) {
17+
Ok(WaitStatus::StillAlive) => None,
18+
Ok(WaitStatus::Exited(_, code)) => Some(ExitStatus {
19+
code,
20+
// Mario reference
21+
reason: "Life is good".to_owned(),
22+
exit_code: None,
23+
rusage: None,
24+
}),
25+
Ok(WaitStatus::Signaled(_, signal, _) | WaitStatus::Stopped(_, signal)) => {
26+
Some(ExitStatus {
27+
code: signal as i32,
28+
reason: signal.as_str().to_owned(),
29+
exit_code: None,
30+
rusage: None,
31+
})
32+
}
33+
Ok(WaitStatus::Continued(_)) => None,
34+
Ok(_) => None,
35+
Err(err) => {
36+
println!("[ERROR] {err}");
37+
None
38+
}
39+
}
40+
}
41+
}
42+
43+
pub struct AsyncOsReader(Async<os_pipe::PipeReader>);
44+
45+
impl From<os_pipe::PipeReader> for AsyncOsReader {
46+
fn from(value: os_pipe::PipeReader) -> Self {
47+
Self(Async::new(value).expect("Cannot create async wrapper"))
48+
}
49+
}
50+
51+
impl AsFd for AsyncOsReader {
52+
fn as_fd(&self) -> std::os::unix::prelude::BorrowedFd<'_> {
53+
self.0.as_fd()
54+
}
55+
}
56+
57+
impl AsyncOsReader {
58+
pub async fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
59+
_ = self.0.readable().await?;
60+
unsafe { self.0.get_mut() }.read(buf)
61+
}
62+
63+
pub async fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
64+
let mut total_bytes = 0;
65+
66+
loop {
67+
let read_bytes = self.read(buf.as_mut_slice()).await?;
68+
69+
if read_bytes == 0 {
70+
break;
71+
}
72+
73+
total_bytes += read_bytes;
74+
}
75+
76+
Ok(total_bytes)
77+
}
78+
}
79+
80+
impl ops::Deref for AsyncOsReader {
81+
type Target = os_pipe::PipeReader;
82+
83+
fn deref(&self) -> &Self::Target {
84+
&self.0.get_ref()
85+
}
86+
}

0 commit comments

Comments
 (0)