milestone: desktop path Phases 1-5
Phase 1 (Runtime Substrate): 4 check binaries, --probe, POSIX tests Phase 2 (Wayland Compositor): bounded scaffold, zero warnings Phase 3 (KWin Session): preflight checker (KWin stub, gated on Qt6Quick) Phase 4 (KDE Plasma): 18 KF6 enabled, preflight checker Phase 5 (Hardware GPU): DRM/firmware/Mesa preflight checker Build: zero warnings, all scripts syntax-clean. Oracle-verified.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, prelude::*},
|
||||
os::unix::io::{AsRawFd, FromRawFd, RawFd},
|
||||
};
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
}
|
||||
fn nonblock(file: &File) -> io::Result<()> {
|
||||
syscall::fcntl(
|
||||
file.as_raw_fd() as usize,
|
||||
syscall::F_SETFL,
|
||||
syscall::O_NONBLOCK,
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(from_syscall_error)
|
||||
}
|
||||
fn dup(file: &File, buf: &str) -> io::Result<File> {
|
||||
let stream =
|
||||
syscall::dup(file.as_raw_fd() as usize, buf.as_bytes()).map_err(from_syscall_error)?;
|
||||
Ok(unsafe { File::from_raw_fd(stream as RawFd) })
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let server = File::create("chan:hello_world")?;
|
||||
|
||||
nonblock(&server)?;
|
||||
|
||||
let mut event_file = File::open("event:")?;
|
||||
let mut time_file = File::open(format!("time:{}", syscall::CLOCK_MONOTONIC))?;
|
||||
|
||||
let mut time = syscall::TimeSpec::default();
|
||||
time_file.read(&mut time)?;
|
||||
time.tv_sec += 1;
|
||||
time_file.write(&time)?;
|
||||
time.tv_sec += 2;
|
||||
time_file.write(&time)?;
|
||||
time.tv_sec += 2;
|
||||
time_file.write(&time)?;
|
||||
|
||||
const TOKEN_TIMER: usize = 0;
|
||||
const TOKEN_STREAM: usize = 1;
|
||||
const TOKEN_SERVER: usize = 2;
|
||||
const TOKEN_CLIENT: usize = 3;
|
||||
|
||||
event_file.write(&syscall::Event {
|
||||
id: time_file.as_raw_fd() as usize,
|
||||
flags: syscall::EVENT_READ,
|
||||
data: TOKEN_TIMER,
|
||||
})?;
|
||||
event_file.write(&syscall::Event {
|
||||
id: server.as_raw_fd() as usize,
|
||||
flags: syscall::EVENT_WRITE | syscall::EVENT_READ,
|
||||
data: TOKEN_SERVER,
|
||||
})?;
|
||||
|
||||
let mut event = syscall::Event::default();
|
||||
|
||||
println!("Testing accept events...");
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_TIMER);
|
||||
assert_eq!(event.flags, syscall::EVENT_READ);
|
||||
println!("-> Timed out");
|
||||
|
||||
let mut client = File::open("chan:hello_world")?;
|
||||
event_file.write(&syscall::Event {
|
||||
id: client.as_raw_fd() as usize,
|
||||
flags: syscall::EVENT_WRITE | syscall::EVENT_READ,
|
||||
data: TOKEN_CLIENT,
|
||||
})?;
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_SERVER);
|
||||
assert_eq!(event.flags, syscall::EVENT_WRITE | syscall::EVENT_READ);
|
||||
println!("-> Accept event");
|
||||
|
||||
println!("Testing write events...");
|
||||
|
||||
let mut stream = dup(&server, "listen")?;
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_CLIENT);
|
||||
assert_eq!(event.flags, syscall::EVENT_WRITE);
|
||||
println!("-> Writable event");
|
||||
|
||||
event_file.write(&syscall::Event {
|
||||
id: stream.as_raw_fd() as usize,
|
||||
flags: syscall::EVENT_READ | syscall::EVENT_WRITE,
|
||||
data: TOKEN_STREAM,
|
||||
})?;
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_STREAM);
|
||||
assert_eq!(event.flags, syscall::EVENT_WRITE);
|
||||
println!("-> Writable event");
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_TIMER);
|
||||
assert_eq!(event.flags, syscall::EVENT_READ);
|
||||
println!("-> Timed out");
|
||||
|
||||
println!("Testing read events...");
|
||||
|
||||
client.write(b"a")?;
|
||||
|
||||
let mut buf = [0; 5];
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_STREAM);
|
||||
assert_eq!(event.flags, syscall::EVENT_READ);
|
||||
println!("-> Readable event");
|
||||
|
||||
assert_eq!(stream.read(&mut buf)?, 1);
|
||||
assert_eq!(buf[0], b'a');
|
||||
|
||||
stream.write(b"b")?;
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_CLIENT);
|
||||
assert_eq!(event.flags, syscall::EVENT_READ);
|
||||
println!("-> Readable event");
|
||||
|
||||
assert_eq!(client.read(&mut buf)?, 1);
|
||||
assert_eq!(buf[0], b'b');
|
||||
|
||||
drop(client);
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_STREAM);
|
||||
println!("-> Readable event (EOF)");
|
||||
|
||||
assert_eq!(stream.read(&mut buf)?, 0);
|
||||
|
||||
event_file.read(&mut event)?;
|
||||
assert_eq!(event.data, TOKEN_TIMER);
|
||||
println!("-> Timed out");
|
||||
|
||||
println!("Everything tested!");
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
use std::{fs::File, io};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let mut client = File::open("chan:hello")?;
|
||||
io::copy(&mut client, &mut io::stdout())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, prelude::*},
|
||||
os::unix::io::{AsRawFd, FromRawFd, RawFd},
|
||||
};
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let server = File::create("chan:hello")?;
|
||||
|
||||
loop {
|
||||
let stream =
|
||||
syscall::dup(server.as_raw_fd() as usize, b"listen").map_err(from_syscall_error)?;
|
||||
let mut stream = unsafe { File::from_raw_fd(stream as RawFd) };
|
||||
|
||||
stream.write(b"Hello World!\n")?;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
io::{self, prelude::*},
|
||||
os::unix::io::{AsRawFd, FromRawFd, RawFd},
|
||||
str,
|
||||
};
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let server = File::create("chan:log")?;
|
||||
let mut event_file = File::open("event:")?;
|
||||
|
||||
syscall::fcntl(
|
||||
server.as_raw_fd() as usize,
|
||||
syscall::F_SETFL,
|
||||
syscall::O_NONBLOCK,
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(from_syscall_error)?;
|
||||
event_file.write(&syscall::Event {
|
||||
id: server.as_raw_fd() as usize,
|
||||
data: 0,
|
||||
flags: syscall::EVENT_READ | syscall::EVENT_WRITE,
|
||||
})?;
|
||||
|
||||
let mut clients = HashMap::new();
|
||||
let mut next_id = 1;
|
||||
|
||||
'outer: loop {
|
||||
let mut event = syscall::Event::default();
|
||||
event_file.read(&mut event)?;
|
||||
|
||||
if event.data == 0 {
|
||||
println!("Listener recevied flags: {:?}", event.flags);
|
||||
if event.flags & syscall::EVENT_WRITE == syscall::EVENT_WRITE {
|
||||
loop {
|
||||
let stream = match syscall::dup(server.as_raw_fd() as usize, b"listen")
|
||||
.map_err(from_syscall_error)
|
||||
{
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => break,
|
||||
stream => stream?,
|
||||
};
|
||||
let stream = unsafe { File::from_raw_fd(stream as RawFd) };
|
||||
|
||||
event_file.write(&syscall::Event {
|
||||
id: stream.as_raw_fd() as usize,
|
||||
data: next_id,
|
||||
flags: syscall::EVENT_READ | syscall::EVENT_WRITE,
|
||||
})?;
|
||||
|
||||
clients.insert(next_id, stream);
|
||||
println!("-> Spawned client #{}", next_id);
|
||||
next_id += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Client #{} received flags: {:?}", event.data, event.flags);
|
||||
let client = clients.get_mut(&event.data).unwrap();
|
||||
|
||||
if event.flags & syscall::EVENT_READ == syscall::EVENT_READ {
|
||||
println!("-> Reading");
|
||||
let mut buf = [0; 128];
|
||||
loop {
|
||||
let len = match client.read(&mut buf) {
|
||||
Ok(0) => {
|
||||
println!("--> EOF");
|
||||
clients.remove(&event.data);
|
||||
continue 'outer;
|
||||
}
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => break,
|
||||
len => len?,
|
||||
};
|
||||
println!(
|
||||
"--> Read {}/128 bytes: {:?}",
|
||||
len,
|
||||
str::from_utf8(&buf[..len])
|
||||
);
|
||||
}
|
||||
}
|
||||
if event.flags & syscall::EVENT_WRITE == syscall::EVENT_WRITE {
|
||||
println!("-> Writing");
|
||||
const BUF: &str = "Hello from the log server\n";
|
||||
let mut written = 0;
|
||||
while written < BUF.len() {
|
||||
let len = match client.write(BUF[written..].as_bytes()) {
|
||||
Ok(0) => panic!("EOF should never happen here"),
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => break,
|
||||
len => len?,
|
||||
};
|
||||
println!(
|
||||
"--> Wrote {}/{} bytes: {:?}",
|
||||
len,
|
||||
BUF.len(),
|
||||
&BUF[written..]
|
||||
);
|
||||
written += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
use std::{
|
||||
fs::{File, OpenOptions},
|
||||
io::{self, prelude::*},
|
||||
os::unix::io::{AsRawFd, FromRawFd, RawFd},
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
}
|
||||
fn nonblock(file: &File) -> io::Result<()> {
|
||||
syscall::fcntl(
|
||||
file.as_raw_fd() as usize,
|
||||
syscall::F_SETFL,
|
||||
syscall::O_NONBLOCK,
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(from_syscall_error)
|
||||
}
|
||||
fn dup(file: &File, buf: &str) -> io::Result<File> {
|
||||
let stream =
|
||||
syscall::dup(file.as_raw_fd() as usize, buf.as_bytes()).map_err(from_syscall_error)?;
|
||||
Ok(unsafe { File::from_raw_fd(stream as RawFd) })
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let mut buf = [0; 5];
|
||||
let server = File::create("chan:hello_world")?;
|
||||
{
|
||||
println!("Testing O_EXCL...");
|
||||
assert_eq!(
|
||||
OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open("chan:hello_world")
|
||||
.unwrap_err()
|
||||
.kind(),
|
||||
io::ErrorKind::AlreadyExists
|
||||
);
|
||||
|
||||
println!("Testing connecting...");
|
||||
|
||||
File::open("chan:hello_world")?; // closed connection will silently be skipped
|
||||
let mut client = File::create("chan:hello_world")?; // O_CREAT without O_EXCL does nothing
|
||||
let tmp = File::open("chan:hello_world")?; // multiple connections are handled
|
||||
|
||||
let mut stream = dup(&server, "listen")?;
|
||||
assert!(dup(&server, "listen").is_ok());
|
||||
drop(tmp);
|
||||
|
||||
println!("Testing basic I/O...");
|
||||
|
||||
stream.write(b"abc")?;
|
||||
stream.flush()?;
|
||||
println!("-> Wrote message");
|
||||
|
||||
assert_eq!(client.read(&mut buf)?, 3);
|
||||
assert_eq!(&buf[..3], b"abc");
|
||||
println!("-> Read message");
|
||||
|
||||
println!("Testing close...");
|
||||
|
||||
drop(client);
|
||||
assert_eq!(
|
||||
stream.write(b"a").unwrap_err().kind(),
|
||||
io::ErrorKind::BrokenPipe
|
||||
);
|
||||
assert_eq!(stream.read(&mut buf)?, 0);
|
||||
}
|
||||
println!("Testing alternative connect method...");
|
||||
|
||||
let mut client = dup(&server, "connect")?;
|
||||
let mut stream = dup(&server, "listen")?;
|
||||
|
||||
println!("Testing blocking I/O...");
|
||||
|
||||
let mut client_clone = client.try_clone()?;
|
||||
|
||||
let thread = thread::spawn(move || -> io::Result<()> {
|
||||
println!("--> Thread: Sleeping for 1 second...");
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
println!("--> Thread: Writing...");
|
||||
client_clone.write(b"def")?;
|
||||
client_clone.flush()?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
assert_eq!(stream.read(&mut buf)?, 3);
|
||||
assert_eq!(&buf[..3], b"def");
|
||||
println!("-> Read message");
|
||||
|
||||
thread.join().unwrap().unwrap();
|
||||
|
||||
println!("Testing non-blocking I/O...");
|
||||
|
||||
nonblock(&client)?;
|
||||
nonblock(&server)?;
|
||||
|
||||
assert_eq!(
|
||||
client.read(&mut buf).unwrap_err().kind(),
|
||||
io::ErrorKind::WouldBlock
|
||||
);
|
||||
println!("-> Read would block");
|
||||
|
||||
assert_eq!(
|
||||
dup(&server, "listen").unwrap_err().kind(),
|
||||
io::ErrorKind::WouldBlock
|
||||
);
|
||||
println!("-> Accept would block");
|
||||
|
||||
drop(client);
|
||||
{
|
||||
let mut client = File::open("chan:hello_world")?;
|
||||
nonblock(&client)?;
|
||||
|
||||
assert_eq!(
|
||||
client.write(b"a").unwrap_err().kind(),
|
||||
io::ErrorKind::WouldBlock
|
||||
);
|
||||
println!("-> Write before accept would block");
|
||||
}
|
||||
|
||||
let mut client = dup(&server, "connect")?;
|
||||
nonblock(&client)?;
|
||||
|
||||
assert_eq!(
|
||||
client.write(b"a").unwrap_err().kind(),
|
||||
io::ErrorKind::WouldBlock
|
||||
);
|
||||
println!("-> Write before accept would block (alternative connection method)");
|
||||
|
||||
println!("Everything tested!");
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use std::{fs::File, io, os::unix::io::AsRawFd, slice};
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
}
|
||||
fn main() -> Result<(), io::Error> {
|
||||
let file1 = File::open("shm:example")?;
|
||||
let file2 = File::open("shm:example")?;
|
||||
|
||||
let one = unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
syscall::fmap(
|
||||
file1.as_raw_fd() as usize,
|
||||
&syscall::Map {
|
||||
offset: 0,
|
||||
size: 128,
|
||||
flags: syscall::PROT_READ | syscall::PROT_WRITE | syscall::MAP_SHARED,
|
||||
address: 0,
|
||||
},
|
||||
)
|
||||
.map_err(from_syscall_error)? as *mut u8,
|
||||
128,
|
||||
)
|
||||
};
|
||||
// FIXME: While the length can be unaligned, the offset cannot. This test is incorrectly
|
||||
// written.
|
||||
let two = unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
syscall::fmap(
|
||||
file2.as_raw_fd() as usize,
|
||||
&syscall::Map {
|
||||
offset: 64,
|
||||
size: 64,
|
||||
flags: syscall::PROT_READ | syscall::PROT_WRITE | syscall::MAP_SHARED,
|
||||
address: 0,
|
||||
},
|
||||
)
|
||||
.map_err(from_syscall_error)? as *mut u8,
|
||||
64,
|
||||
)
|
||||
};
|
||||
|
||||
println!("Testing writing between");
|
||||
for i in 0..128 {
|
||||
one[i as usize] = i;
|
||||
}
|
||||
for i in 0..64 {
|
||||
assert_eq!(two[i as usize], 64 + i);
|
||||
}
|
||||
|
||||
println!("Testing fpath");
|
||||
let mut buf = [0; 128];
|
||||
let len = syscall::fpath(file1.as_raw_fd() as usize, &mut buf).map_err(from_syscall_error)?;
|
||||
assert_eq!(&buf[..len], b"shm:example");
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
use std::{fs::File, io, mem, os::unix::io::AsRawFd, thread, time::Duration};
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
}
|
||||
fn main() -> Result<(), io::Error> {
|
||||
let file = File::open("shm:counter")?;
|
||||
println!("Reading from map... ");
|
||||
let counter = unsafe {
|
||||
&mut *(syscall::fmap(
|
||||
file.as_raw_fd() as usize,
|
||||
&syscall::Map {
|
||||
offset: 0,
|
||||
address: 0,
|
||||
size: mem::size_of::<usize>(),
|
||||
flags: syscall::PROT_READ | syscall::PROT_WRITE | syscall::MAP_SHARED,
|
||||
},
|
||||
)
|
||||
.map_err(from_syscall_error)? as *mut usize)
|
||||
};
|
||||
println!("Read value {}", counter);
|
||||
*counter += 1;
|
||||
println!("Increased value to {}", counter);
|
||||
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, prelude::*},
|
||||
os::unix::io::{AsRawFd, FromRawFd, RawFd},
|
||||
};
|
||||
|
||||
fn from_syscall_error(error: syscall::Error) -> io::Error {
|
||||
io::Error::from_raw_os_error(error.errno as i32)
|
||||
}
|
||||
fn dup(file: &File, buf: &str) -> io::Result<File> {
|
||||
let stream =
|
||||
syscall::dup(file.as_raw_fd() as usize, buf.as_bytes()).map_err(from_syscall_error)?;
|
||||
Ok(unsafe { File::from_raw_fd(stream as RawFd) })
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let mut buf = [0; 5];
|
||||
let server = File::create("chan:")?;
|
||||
|
||||
let mut client = dup(&server, "connect")?;
|
||||
let mut stream = dup(&server, "listen")?;
|
||||
|
||||
println!("Testing basic I/O...");
|
||||
|
||||
stream.write(b"abc")?;
|
||||
stream.flush()?;
|
||||
println!("-> Wrote message");
|
||||
|
||||
assert_eq!(client.read(&mut buf)?, 3);
|
||||
assert_eq!(&buf[..3], b"abc");
|
||||
println!("-> Read message");
|
||||
|
||||
println!("Testing connecting to unnamed socket by name (makes no sense)...");
|
||||
assert_eq!(
|
||||
File::open("chan:").unwrap_err().kind(),
|
||||
io::ErrorKind::NotFound
|
||||
);
|
||||
|
||||
println!("Everything tested!");
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user