1 // Copyright 2024 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use std::os::fd::AsFd;
6
7 use nix::unistd::pipe;
8 use nix::unistd::read;
9 use nix::unistd::write;
10
11 use crate::rutabaga_os::AsBorrowedDescriptor;
12 use crate::rutabaga_os::AsRawDescriptor;
13 use crate::rutabaga_os::FromRawDescriptor;
14 use crate::rutabaga_os::OwnedDescriptor;
15 use crate::rutabaga_os::RawDescriptor;
16 use crate::rutabaga_utils::RutabagaResult;
17
18 pub struct ReadPipe {
19 descriptor: OwnedDescriptor,
20 }
21
22 pub struct WritePipe {
23 descriptor: OwnedDescriptor,
24 }
25
create_pipe() -> RutabagaResult<(ReadPipe, WritePipe)>26 pub fn create_pipe() -> RutabagaResult<(ReadPipe, WritePipe)> {
27 let (read_pipe, write_pipe) = pipe()?;
28 Ok((
29 ReadPipe {
30 descriptor: read_pipe.into(),
31 },
32 WritePipe {
33 descriptor: write_pipe.into(),
34 },
35 ))
36 }
37
38 impl ReadPipe {
read(&self, data: &mut [u8]) -> RutabagaResult<usize>39 pub fn read(&self, data: &mut [u8]) -> RutabagaResult<usize> {
40 let bytes_read = read(self.descriptor.as_raw_descriptor(), data)?;
41 Ok(bytes_read)
42 }
43 }
44
45 impl AsBorrowedDescriptor for ReadPipe {
as_borrowed_descriptor(&self) -> &OwnedDescriptor46 fn as_borrowed_descriptor(&self) -> &OwnedDescriptor {
47 &self.descriptor
48 }
49 }
50
51 impl WritePipe {
new(descriptor: RawDescriptor) -> WritePipe52 pub fn new(descriptor: RawDescriptor) -> WritePipe {
53 // SAFETY: Safe because we know the underlying OS descriptor is valid and
54 // owned by us.
55 let owned = unsafe { OwnedDescriptor::from_raw_descriptor(descriptor) };
56 WritePipe { descriptor: owned }
57 }
58
write(&self, data: &[u8]) -> RutabagaResult<usize>59 pub fn write(&self, data: &[u8]) -> RutabagaResult<usize> {
60 let bytes_written = write(self.descriptor.as_fd(), data)?;
61 Ok(bytes_written)
62 }
63 }
64
65 impl AsBorrowedDescriptor for WritePipe {
as_borrowed_descriptor(&self) -> &OwnedDescriptor66 fn as_borrowed_descriptor(&self) -> &OwnedDescriptor {
67 &self.descriptor
68 }
69 }
70
71 impl AsRawDescriptor for WritePipe {
as_raw_descriptor(&self) -> RawDescriptor72 fn as_raw_descriptor(&self) -> RawDescriptor {
73 self.descriptor.as_raw_descriptor()
74 }
75 }
76