1use core::time::Duration;
4
5pub use crate::bindings::descriptor as RawFd;
6use crate::{
7 error::{ArgumentError, RawTwzError, TwzError},
8 nk, Result,
9};
10
11bitflags::bitflags! {
12 #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
14pub struct FdFlags : crate::bindings::fd_flags {
15 const IS_TERMINAL = crate::bindings::FD_IS_TERMINAL;
17}
18}
19
20#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default)]
21#[repr(u32)]
22pub enum FdKind {
24 #[default]
25 Regular = crate::bindings::fd_kind_FdKind_Regular,
26 Directory = crate::bindings::fd_kind_FdKind_Directory,
27 SymLink = crate::bindings::fd_kind_FdKind_SymLink,
28 Pty = crate::bindings::fd_kind_FdKind_Pty,
29 Socket = crate::bindings::fd_kind_FdKind_Socket,
30 Pipe = crate::bindings::fd_kind_FdKind_Pipe,
31 Compartment = crate::bindings::fd_kind_FdKind_Compartment,
32 Other = u32::MAX,
33}
34
35impl From<u32> for FdKind {
36 fn from(value: u32) -> Self {
37 match value {
38 crate::bindings::fd_kind_FdKind_Regular => Self::Regular,
39 crate::bindings::fd_kind_FdKind_Directory => Self::Directory,
40 crate::bindings::fd_kind_FdKind_SymLink => Self::SymLink,
41 crate::bindings::fd_kind_FdKind_Pty => Self::Pty,
42 crate::bindings::fd_kind_FdKind_Socket => Self::Socket,
43 crate::bindings::fd_kind_FdKind_Pipe => Self::Pipe,
44 crate::bindings::fd_kind_FdKind_Compartment => Self::Compartment,
45 _ => Self::Other,
46 }
47 }
48}
49
50impl Into<u32> for FdKind {
51 fn into(self) -> u32 {
52 match self {
53 Self::Regular => crate::bindings::fd_kind_FdKind_Regular,
54 Self::Directory => crate::bindings::fd_kind_FdKind_Directory,
55 Self::SymLink => crate::bindings::fd_kind_FdKind_SymLink,
56 Self::Pty => crate::bindings::fd_kind_FdKind_Pty,
57 Self::Socket => crate::bindings::fd_kind_FdKind_Socket,
58 Self::Pipe => crate::bindings::fd_kind_FdKind_Pipe,
59 Self::Compartment => crate::bindings::fd_kind_FdKind_Compartment,
60 Self::Other => u32::MAX,
61 }
62 }
63}
64
65#[derive(Copy, Clone, Debug, Default)]
67pub struct FdInfo {
68 pub flags: FdFlags,
70 pub size: u64,
72 pub kind: FdKind,
74 pub id: twizzler_types::ObjID,
76 pub created: Duration,
78 pub accessed: Duration,
80 pub modified: Duration,
82 pub unix_mode: u32,
84}
85
86impl From<crate::bindings::fd_info> for FdInfo {
87 fn from(value: crate::bindings::fd_info) -> Self {
88 Self {
89 flags: FdFlags::from_bits_truncate(value.flags),
90 size: value.len,
91 kind: FdKind::from(value.kind),
92 id: value.id,
93 created: value.created.into(),
94 accessed: value.accessed.into(),
95 modified: value.modified.into(),
96 unix_mode: value.unix_mode,
97 }
98 }
99}
100
101impl From<FdInfo> for crate::bindings::fd_info {
102 fn from(value: FdInfo) -> Self {
103 Self {
104 flags: value.flags.bits(),
105 len: value.size,
106 kind: value.kind.into(),
107 id: value.id,
108 created: value.created.into(),
109 accessed: value.accessed.into(),
110 modified: value.modified.into(),
111 unix_mode: value.unix_mode,
112 }
113 }
114}
115
116impl From<Result<RawFd>> for crate::bindings::open_result {
117 fn from(value: Result<RawFd>) -> Self {
118 match value {
119 Ok(fd) => Self {
120 fd,
121 err: RawTwzError::success().raw(),
122 },
123 Err(e) => Self {
124 fd: 0,
125 err: e.raw(),
126 },
127 }
128 }
129}
130
131impl From<crate::bindings::open_result> for Result<RawFd> {
132 fn from(value: crate::bindings::open_result) -> Self {
133 let raw = RawTwzError::new(value.err);
134 if raw.is_success() {
135 Ok(value.fd)
136 } else {
137 Err(raw.error())
138 }
139 }
140}
141
142pub fn twz_rt_fd_get_info(fd: RawFd) -> Result<FdInfo> {
144 let mut info = core::mem::MaybeUninit::uninit();
145 unsafe {
146 if nk!(crate::bindings::twz_rt_fd_get_info(fd, info.as_mut_ptr())) {
147 return Ok(info.assume_init().into());
148 }
149 }
150 Err(TwzError::Argument(ArgumentError::BadHandle))
151}
152
153pub use crate::bindings::name_entry as NameEntry;
154
155impl NameEntry {
156 pub const NAME_MAX_LEN: usize = crate::bindings::NAME_ENTRY_LEN as usize;
157 pub fn new(iname: &[u8], info: crate::bindings::fd_info) -> Self {
158 let nl = iname.len().min(Self::NAME_MAX_LEN);
159 let mut name = [0; Self::NAME_MAX_LEN];
160 name[0..nl].copy_from_slice(&iname[0..nl]);
161 Self {
162 name,
163 info,
164 name_len: nl as u32,
165 linkname_len: 0,
166 }
167 }
168
169 pub fn new_symlink(iname: &[u8], ilinkname: &[u8], info: crate::bindings::fd_info) -> Self {
170 let nl = iname.len().min(Self::NAME_MAX_LEN);
171 let linknl = ilinkname.len().min(Self::NAME_MAX_LEN - nl);
172 let mut name = [0; Self::NAME_MAX_LEN];
173 name[0..nl].copy_from_slice(&iname[0..nl]);
174 name[nl..(nl + linknl)].copy_from_slice(&ilinkname[0..linknl]);
175 Self {
176 name,
177 info,
178 name_len: nl as u32,
179 linkname_len: linknl as u32,
180 }
181 }
182
183 pub fn name_bytes(&self) -> &[u8] {
184 &self.name[0..self.name_len as usize]
185 }
186
187 pub fn linkname_bytes(&self) -> &[u8] {
188 &self.name[self.name_len as usize..(self.name_len + self.linkname_len) as usize]
189 }
190}
191
192pub fn twz_rt_fd_enumerate_names(
196 fd: RawFd,
197 entries: &mut [NameEntry],
198 off: usize,
199) -> Result<usize> {
200 unsafe {
201 nk!(crate::bindings::twz_rt_fd_enumerate_names(
202 fd,
203 entries.as_mut_ptr(),
204 entries.len(),
205 off
206 )
207 .into())
208 }
209}
210
211use crate::bindings::{
212 binding_info, descriptor, object_bind_info, objid, prot_kind, socket_address, socket_bind_info,
213};
214impl binding_info {
215 pub fn new_object_binding(fd: descriptor, kind: OpenKind, flags: u32, id: objid) -> Self {
216 let mut this = Self {
217 kind: kind.into(),
218 flags,
219 fd,
220 bind_data: [0; _],
221 bind_len: size_of::<object_bind_info>() as u32,
222 };
223 let bind_info = object_bind_info { id };
224 let bind_info_bytes = &bind_info as *const _ as *const u8;
225 let slice =
226 unsafe { core::slice::from_raw_parts(bind_info_bytes, size_of::<object_bind_info>()) };
227 this.bind_data[0..(this.bind_len as usize)].copy_from_slice(slice);
228 this
229 }
230
231 pub fn new_socket_binding(
232 fd: descriptor,
233 kind: OpenKind,
234 flags: u32,
235 addr: socket_address,
236 prot: prot_kind,
237 ) -> Self {
238 let mut this = Self {
239 kind: kind.into(),
240 flags,
241 fd,
242 bind_data: [0; _],
243 bind_len: size_of::<socket_bind_info>() as u32,
244 };
245 let bind_info = socket_bind_info { addr, prot };
246 let bind_info_bytes = &bind_info as *const _ as *const u8;
247 let slice =
248 unsafe { core::slice::from_raw_parts(bind_info_bytes, size_of::<socket_bind_info>()) };
249 this.bind_data[0..(this.bind_len as usize)].copy_from_slice(slice);
250 this
251 }
252
253 pub fn new_fd_binding(fd: descriptor, kind: OpenKind, flags: u32, bind_fd: descriptor) -> Self {
254 let mut this = Self {
255 kind: kind.into(),
256 flags,
257 fd,
258 bind_data: [0; _],
259 bind_len: size_of::<descriptor>() as u32,
260 };
261 let bind_info_bytes = &bind_fd as *const _ as *const u8;
262 let slice =
263 unsafe { core::slice::from_raw_parts(bind_info_bytes, size_of::<descriptor>()) };
264 this.bind_data[0..(this.bind_len as usize)].copy_from_slice(slice);
265 this
266 }
267}
268
269pub fn twz_rt_fd_read_binds(binds: &mut [binding_info]) -> usize {
270 unsafe {
271 nk!(crate::bindings::twz_rt_fd_read_binds(
272 binds.as_mut_ptr(),
273 binds.len()
274 ))
275 }
276}
277
278pub fn twz_rt_fd_copen(
280 name: &core::ffi::CStr,
281 create: crate::bindings::create_options,
282 flags: u32,
283) -> Result<RawFd> {
284 let name_len = name.count_bytes().min(crate::bindings::NAME_DATA_MAX);
285 let mut info = crate::bindings::open_info {
286 len: name_len,
287 create,
288 flags,
289 name: [0; _],
290 };
291 info.name[0..name_len].copy_from_slice(&name.to_bytes()[0..name_len]);
292 unsafe {
293 nk!(crate::bindings::twz_rt_fd_open(
294 crate::bindings::open_kind_OpenKind_Path,
295 flags,
296 (&mut info as *mut crate::bindings::open_info).cast(),
297 size_of_val(&info),
298 )
299 .into())
300 }
301}
302
303pub fn twz_rt_fd_open(
305 name: &str,
306 create: crate::bindings::create_options,
307 flags: u32,
308) -> Result<RawFd> {
309 let name_len = name.as_bytes().len().min(crate::bindings::NAME_DATA_MAX);
310 let mut info = crate::bindings::open_info {
311 len: name_len,
312 create,
313 flags,
314 name: [0; _],
315 };
316 info.name[0..name_len].copy_from_slice(&name.as_bytes()[0..name_len]);
317 unsafe {
318 nk!(crate::bindings::twz_rt_fd_open(
319 crate::bindings::open_kind_OpenKind_Path,
320 flags,
321 (&mut info as *mut crate::bindings::open_info).cast(),
322 size_of_val(&info),
323 )
324 .into())
325 }
326}
327
328pub fn twz_rt_fd_remove(name: &str) -> Result<()> {
330 unsafe {
331 RawTwzError::new(nk!(crate::bindings::twz_rt_fd_remove(
332 name.as_ptr().cast(),
333 name.len(),
334 )))
335 .result()
336 }
337}
338
339pub fn twz_rt_fd_mkns(name: &str) -> Result<()> {
341 unsafe {
342 RawTwzError::new(nk!(crate::bindings::twz_rt_fd_mkns(
343 name.as_ptr().cast(),
344 name.len(),
345 )))
346 .result()
347 }
348}
349
350pub fn twz_rt_fd_symlink(name: &str, target: &str) -> Result<()> {
352 unsafe {
353 RawTwzError::new(nk!(crate::bindings::twz_rt_fd_symlink(
354 name.as_ptr().cast(),
355 name.len(),
356 target.as_ptr().cast(),
357 target.len(),
358 )))
359 .result()
360 }
361}
362
363pub fn twz_rt_fd_rename(old_name: &str, new_name: &str) -> Result<()> {
365 unsafe {
366 RawTwzError::new(nk!(crate::bindings::twz_rt_fd_rename(
367 old_name.as_ptr().cast(),
368 old_name.len(),
369 new_name.as_ptr().cast(),
370 new_name.len(),
371 )))
372 .result()
373 }
374}
375
376pub fn twz_rt_fd_readlink(name: &str, buf: &mut [u8]) -> Result<usize> {
377 let mut len: u64 = 0;
378 unsafe {
379 RawTwzError::new(nk!(crate::bindings::twz_rt_fd_readlink(
380 name.as_ptr().cast(),
381 name.len(),
382 buf.as_mut_ptr().cast(),
383 buf.len(),
384 &mut len,
385 )))
386 .result()?;
387 }
388 Ok(len as usize)
389}
390
391#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
392#[repr(u32)]
393pub enum OpenKind {
394 Object = crate::bindings::open_kind_OpenKind_Object,
395 Path = crate::bindings::open_kind_OpenKind_Path,
396 Pipe = crate::bindings::open_kind_OpenKind_Pipe,
397 SocketConnect = crate::bindings::open_kind_OpenKind_SocketConnect,
398 SocketBind = crate::bindings::open_kind_OpenKind_SocketBind,
399 SocketAccept = crate::bindings::open_kind_OpenKind_SocketAccept,
400 PtyServer = crate::bindings::open_kind_OpenKind_PtyServer,
401 PtyClient = crate::bindings::open_kind_OpenKind_PtyClient,
402 Compartment = crate::bindings::open_kind_OpenKind_Compartment,
403 KernelConsole = crate::bindings::open_kind_OpenKind_KernelConsole,
404}
405
406impl TryFrom<u32> for OpenKind {
407 type Error = ();
408
409 fn try_from(val: u32) -> core::result::Result<OpenKind, Self::Error> {
410 match val {
411 crate::bindings::open_kind_OpenKind_Pipe => Ok(Self::Pipe),
412 crate::bindings::open_kind_OpenKind_SocketConnect => Ok(Self::SocketConnect),
413 crate::bindings::open_kind_OpenKind_SocketBind => Ok(Self::SocketBind),
414 crate::bindings::open_kind_OpenKind_SocketAccept => Ok(Self::SocketAccept),
415 crate::bindings::open_kind_OpenKind_PtyServer => Ok(Self::PtyServer),
416 crate::bindings::open_kind_OpenKind_PtyClient => Ok(Self::PtyClient),
417 crate::bindings::open_kind_OpenKind_Path => Ok(Self::Path),
418 crate::bindings::open_kind_OpenKind_Object => Ok(Self::Object),
419 crate::bindings::open_kind_OpenKind_Compartment => Ok(Self::Compartment),
420 crate::bindings::open_kind_OpenKind_KernelConsole => Ok(Self::KernelConsole),
421
422 _ => Err(()),
423 }
424 }
425}
426
427impl From<OpenKind> for u32 {
428 fn from(val: OpenKind) -> u32 {
429 match val {
430 OpenKind::Pipe => crate::bindings::open_kind_OpenKind_Pipe,
431 OpenKind::Path => crate::bindings::open_kind_OpenKind_Path,
432 OpenKind::Object => crate::bindings::open_kind_OpenKind_Object,
433 OpenKind::SocketConnect => crate::bindings::open_kind_OpenKind_SocketConnect,
434 OpenKind::SocketBind => crate::bindings::open_kind_OpenKind_SocketBind,
435 OpenKind::SocketAccept => crate::bindings::open_kind_OpenKind_SocketAccept,
436 OpenKind::PtyServer => crate::bindings::open_kind_OpenKind_PtyServer,
437 OpenKind::PtyClient => crate::bindings::open_kind_OpenKind_PtyClient,
438 OpenKind::Compartment => crate::bindings::open_kind_OpenKind_Compartment,
439 OpenKind::KernelConsole => crate::bindings::open_kind_OpenKind_KernelConsole,
440 }
441 }
442}
443
444#[derive(Clone, Copy, Default)]
445#[repr(transparent)]
446pub struct SocketAddress(pub crate::bindings::socket_address);
447
448#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
449#[repr(u32)]
450pub enum ProtKind {
451 Stream = crate::bindings::prot_kind_ProtKind_Stream,
452 Datagram = crate::bindings::prot_kind_ProtKind_Datagram,
453}
454
455impl SocketAddress {
456 fn new_v4(octets: [u8; 4], port: u16) -> Self {
457 Self(crate::bindings::socket_address {
458 kind: crate::bindings::addr_kind_AddrKind_Ipv4,
459 addr_octets: crate::bindings::socket_address_addrs { v4: octets },
460 port,
461 flowinfo: 0,
462 scope_id: 0,
463 })
464 }
465
466 fn new_v6(octets: [u8; 16], port: u16, flowinfo: u32, scope_id: u32) -> Self {
467 Self(crate::bindings::socket_address {
468 kind: crate::bindings::addr_kind_AddrKind_Ipv6,
469 addr_octets: crate::bindings::socket_address_addrs { v6: octets },
470 port,
471 flowinfo,
472 scope_id,
473 })
474 }
475
476 fn v4_octets(&self) -> [u8; 4] {
477 assert!(self.is_v4());
478 unsafe { self.0.addr_octets.v4 }
479 }
480
481 fn v6_octets(&self) -> [u8; 16] {
482 assert!(!self.is_v4());
483 unsafe { self.0.addr_octets.v6 }
484 }
485
486 fn is_v4(&self) -> bool {
487 self.0.kind == crate::bindings::addr_kind_AddrKind_Ipv4
488 }
489}
490
491impl From<SocketAddress> for core::net::IpAddr {
492 fn from(value: SocketAddress) -> Self {
493 if value.is_v4() {
494 Self::V4(core::net::Ipv4Addr::from_octets(value.v4_octets()))
495 } else {
496 Self::V6(core::net::Ipv6Addr::from_octets(value.v6_octets()))
497 }
498 }
499}
500
501impl From<SocketAddress> for core::net::SocketAddr {
502 fn from(value: SocketAddress) -> Self {
503 if value.is_v4() {
504 Self::V4(core::net::SocketAddrV4::new(
505 core::net::Ipv4Addr::from_octets(value.v4_octets()),
506 value.0.port,
507 ))
508 } else {
509 Self::V6(core::net::SocketAddrV6::new(
510 core::net::Ipv6Addr::from_octets(value.v6_octets()),
511 value.0.port,
512 value.0.flowinfo,
513 value.0.scope_id,
514 ))
515 }
516 }
517}
518
519impl From<core::net::Ipv4Addr> for SocketAddress {
520 fn from(value: core::net::Ipv4Addr) -> Self {
521 Self::new_v4(value.octets(), 0)
522 }
523}
524
525impl From<core::net::Ipv6Addr> for SocketAddress {
526 fn from(value: core::net::Ipv6Addr) -> Self {
527 Self::new_v6(value.octets(), 0, 0, 0)
528 }
529}
530
531impl From<core::net::SocketAddrV4> for SocketAddress {
532 fn from(value: core::net::SocketAddrV4) -> Self {
533 Self::new_v4(value.ip().octets(), value.port())
534 }
535}
536
537impl From<core::net::SocketAddrV6> for SocketAddress {
538 fn from(value: core::net::SocketAddrV6) -> Self {
539 Self::new_v6(
540 value.ip().octets(),
541 value.port(),
542 value.flowinfo(),
543 value.scope_id(),
544 )
545 }
546}
547
548impl From<core::net::SocketAddr> for SocketAddress {
549 fn from(value: core::net::SocketAddr) -> Self {
550 match value {
551 core::net::SocketAddr::V4(v4) => v4.into(),
552 core::net::SocketAddr::V6(v6) => v6.into(),
553 }
554 }
555}
556
557impl From<core::net::IpAddr> for SocketAddress {
558 fn from(value: core::net::IpAddr) -> Self {
559 match value {
560 core::net::IpAddr::V4(v4) => v4.into(),
561 core::net::IpAddr::V6(v6) => v6.into(),
562 }
563 }
564}
565
566pub fn twz_rt_fd_open_socket_bind(
568 addr: SocketAddress,
569 flags: u32,
570 prot: ProtKind,
571) -> Result<RawFd> {
572 let mut binding = crate::bindings::socket_bind_info {
573 addr: addr.0,
574 prot: prot as u32,
575 };
576 unsafe {
577 nk!(crate::bindings::twz_rt_fd_open(
578 OpenKind::SocketBind.into(),
579 flags,
580 ((&mut binding) as *mut crate::bindings::socket_bind_info).cast(),
581 core::mem::size_of::<crate::bindings::socket_bind_info>(),
582 ))
583 .into()
584 }
585}
586
587pub fn twz_rt_fd_open_socket(flags: u32, _prot: ProtKind) -> Result<RawFd> {
589 unsafe {
590 nk!(crate::bindings::twz_rt_fd_open(
591 OpenKind::SocketBind.into(),
592 flags,
593 core::ptr::null_mut(),
594 0,
595 ))
596 .into()
597 }
598}
599
600pub fn twz_rt_fd_socket_rebind(
602 fd: RawFd,
603 addr: SocketAddress,
604 flags: u32,
605 prot: ProtKind,
606) -> Result<()> {
607 let mut binding = crate::bindings::socket_bind_info {
608 addr: addr.0,
609 prot: prot as u32,
610 };
611 unsafe {
612 RawTwzError::new(nk!(crate::bindings::twz_rt_fd_reopen(
613 fd,
614 OpenKind::SocketBind.into(),
615 flags,
616 ((&mut binding) as *mut crate::bindings::socket_bind_info).cast(),
617 core::mem::size_of::<crate::bindings::socket_bind_info>(),
618 )))
619 .result()
620 }
621}
622
623pub fn twz_rt_fd_open_socket_accept(mut fd: RawFd, flags: u32) -> Result<RawFd> {
625 unsafe {
626 nk!(crate::bindings::twz_rt_fd_open(
627 OpenKind::SocketAccept.into(),
628 flags,
629 ((&mut fd) as *mut RawFd).cast(),
630 core::mem::size_of::<RawFd>(),
631 ))
632 .into()
633 }
634}
635
636pub fn twz_rt_fd_open_socket_connect(
638 addr: SocketAddress,
639 flags: u32,
640 prot: ProtKind,
641) -> Result<RawFd> {
642 let mut binding = crate::bindings::socket_bind_info {
643 addr: addr.0,
644 prot: prot as u32,
645 };
646 unsafe {
647 nk!(crate::bindings::twz_rt_fd_open(
648 OpenKind::SocketConnect.into(),
649 flags,
650 ((&mut binding) as *mut crate::bindings::socket_bind_info).cast(),
651 core::mem::size_of::<crate::bindings::socket_bind_info>(),
652 ))
653 .into()
654 }
655}
656
657pub fn twz_rt_fd_socket_reconnect(
659 fd: RawFd,
660 addr: SocketAddress,
661 flags: u32,
662 prot: ProtKind,
663) -> Result<()> {
664 let mut binding = crate::bindings::socket_bind_info {
665 addr: addr.0,
666 prot: prot as u32,
667 };
668 unsafe {
669 RawTwzError::new(nk!(crate::bindings::twz_rt_fd_reopen(
670 fd,
671 OpenKind::SocketConnect.into(),
672 flags,
673 ((&mut binding) as *mut crate::bindings::socket_bind_info).cast(),
674 core::mem::size_of::<crate::bindings::socket_bind_info>(),
675 )))
676 .result()
677 }
678}
679
680pub fn twz_rt_fd_open_pty_server(id: twizzler_types::ObjID, flags: u32) -> Result<RawFd> {
682 let mut binding = crate::bindings::object_bind_info { id };
683 unsafe {
684 nk!(crate::bindings::twz_rt_fd_open(
685 OpenKind::PtyServer.into(),
686 flags,
687 ((&mut binding) as *mut crate::bindings::object_bind_info).cast(),
688 core::mem::size_of::<crate::bindings::object_bind_info>(),
689 ))
690 .into()
691 }
692}
693
694pub fn twz_rt_fd_open_pty_client(id: twizzler_types::ObjID, flags: u32) -> Result<RawFd> {
696 let mut binding = crate::bindings::object_bind_info { id };
697 unsafe {
698 nk!(crate::bindings::twz_rt_fd_open(
699 OpenKind::PtyClient.into(),
700 flags,
701 ((&mut binding) as *mut crate::bindings::object_bind_info).cast(),
702 core::mem::size_of::<crate::bindings::object_bind_info>(),
703 ))
704 .into()
705 }
706}
707
708pub fn twz_rt_fd_open_compartment(id: crate::bindings::objid, flags: u32) -> Result<RawFd> {
710 let mut binding = crate::bindings::object_bind_info { id };
711 unsafe {
712 nk!(crate::bindings::twz_rt_fd_open(
713 OpenKind::Compartment.into(),
714 flags,
715 ((&mut binding) as *mut crate::bindings::object_bind_info).cast(),
716 core::mem::size_of::<crate::bindings::object_bind_info>(),
717 ))
718 .into()
719 }
720}
721
722pub fn twz_rt_fd_open_pipe(id: Option<crate::bindings::objid>, flags: u32) -> Result<RawFd> {
724 let mut binding = crate::bindings::object_bind_info {
725 id: id.unwrap_or(0),
726 };
727 unsafe {
728 nk!(crate::bindings::twz_rt_fd_open(
729 OpenKind::Pipe.into(),
730 flags,
731 ((&mut binding) as *mut crate::bindings::object_bind_info).cast(),
732 core::mem::size_of::<crate::bindings::object_bind_info>(),
733 ))
734 .into()
735 }
736}
737
738pub fn twz_rt_fd_dup(fd: RawFd) -> Result<RawFd> {
740 let mut new_fd = core::mem::MaybeUninit::<RawFd>::uninit();
741 unsafe {
742 let e = nk!(crate::bindings::twz_rt_fd_cmd(
743 fd,
744 crate::bindings::FD_CMD_DUP,
745 core::ptr::null_mut(),
746 new_fd.as_mut_ptr().cast(),
747 ));
748 let raw = RawTwzError::new(e);
749 if raw.is_success() {
750 Ok(new_fd.assume_init())
751 } else {
752 Err(raw.error())
753 }
754 }
755}
756
757pub fn twz_rt_fd_sync(fd: RawFd) {
759 unsafe {
760 nk!(crate::bindings::twz_rt_fd_cmd(
761 fd,
762 crate::bindings::FD_CMD_SYNC,
763 core::ptr::null_mut(),
764 core::ptr::null_mut(),
765 ));
766 }
767}
768
769pub fn twz_rt_fd_truncate(fd: RawFd, mut len: u64) -> Result<()> {
771 unsafe {
772 let e = nk!(crate::bindings::twz_rt_fd_cmd(
773 fd,
774 crate::bindings::FD_CMD_TRUNCATE,
775 (&mut len as *mut u64).cast(),
776 core::ptr::null_mut(),
777 ));
778 let raw = RawTwzError::new(e);
779 if !raw.is_success() {
780 return Err(raw.error());
781 }
782 }
783 Ok(())
784}
785
786pub fn twz_rt_fd_shutdown(fd: RawFd, read: bool, write: bool) -> Result<()> {
787 let mut bits: u32 = 0;
788 if read {
789 bits |= 1;
790 }
791 if write {
792 bits |= 2;
793 }
794 unsafe {
795 let e = nk!(crate::bindings::twz_rt_fd_cmd(
796 fd,
797 crate::bindings::FD_CMD_SHUTDOWN,
798 (&mut bits as *mut u32).cast(),
799 core::ptr::null_mut(),
800 ));
801 let raw = RawTwzError::new(e);
802 if !raw.is_success() {
803 return Err(raw.error());
804 }
805 }
806 Ok(())
807}
808
809pub fn twz_rt_fd_close(fd: RawFd) {
811 unsafe { nk!(crate::bindings::twz_rt_fd_close(fd)) }
812}
813
814#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
815#[repr(u32)]
816pub enum NameRoot {
817 Root = crate::bindings::name_root_NameRoot_Root,
818 Home = crate::bindings::name_root_NameRoot_Home,
819 Current = crate::bindings::name_root_NameRoot_Current,
820 Temp = crate::bindings::name_root_NameRoot_Temp,
821 Exe = crate::bindings::name_root_NameRoot_Exe,
822}
823
824impl From<u32> for NameRoot {
825 fn from(value: u32) -> Self {
826 match value {
827 crate::bindings::name_root_NameRoot_Root => NameRoot::Root,
828 crate::bindings::name_root_NameRoot_Home => NameRoot::Home,
829 crate::bindings::name_root_NameRoot_Current => NameRoot::Current,
830 crate::bindings::name_root_NameRoot_Temp => NameRoot::Temp,
831 crate::bindings::name_root_NameRoot_Exe => NameRoot::Exe,
832 _ => panic!("invalid NameRoot value"),
833 }
834 }
835}
836
837pub fn twz_rt_get_nameroot(root: NameRoot, buf: &mut [u8]) -> Result<usize> {
838 unsafe {
839 nk!(
840 crate::bindings::twz_rt_get_nameroot(root as u32, buf.as_mut_ptr().cast(), buf.len())
841 .into()
842 )
843 }
844}
845
846pub fn twz_rt_set_nameroot(root: NameRoot, buf: &[u8]) -> Result<()> {
847 let res = unsafe {
848 nk!(crate::bindings::twz_rt_set_nameroot(
849 root as u32,
850 buf.as_ptr().cast(),
851 buf.len()
852 ))
853 };
854 let r = RawTwzError::new(res);
855 if r.is_success() {
856 Ok(())
857 } else {
858 Err(r.error())
859 }
860}
861
862#[derive(Default, Copy, Clone)]
863#[repr(u32)]
864pub enum NameResolver {
865 #[default]
866 Default = crate::bindings::name_resolver_NameResolver_Default,
867 Socket = crate::bindings::name_resolver_NameResolver_Socket,
868}
869
870impl From<u32> for NameResolver {
871 fn from(value: u32) -> Self {
872 match value {
873 crate::bindings::name_resolver_NameResolver_Default => NameResolver::Default,
874 crate::bindings::name_resolver_NameResolver_Socket => NameResolver::Socket,
875 _ => panic!("invalid NameResolver value"),
876 }
877 }
878}
879
880pub fn twz_rt_resolve_name(
881 resolver: NameResolver,
882 name: impl AsRef<str>,
883) -> Result<crate::object::ObjID> {
884 let name = name.as_ref().as_bytes();
885 let res = unsafe {
886 nk!(crate::bindings::twz_rt_resolve_name(
887 resolver as u32,
888 name.as_ptr().cast(),
889 name.len()
890 ))
891 };
892 let r = RawTwzError::new(res.err);
893 if r.is_success() {
894 Ok(res.val.into())
895 } else {
896 Err(r.error())
897 }
898}
899
900pub fn twz_rt_canon_name(
901 resolver: NameResolver,
902 name: impl AsRef<str>,
903 out_name: &mut [u8],
904) -> Result<usize> {
905 let name = name.as_ref().as_bytes();
906 let mut out_len = out_name.len();
907 let res = unsafe {
908 nk!(crate::bindings::twz_rt_canon_name(
909 resolver as u32,
910 name.as_ptr().cast(),
911 name.len(),
912 out_name.as_mut_ptr().cast(),
913 &mut out_len,
914 ))
915 };
916 let r = RawTwzError::new(res);
917 if r.is_success() {
918 Ok(out_len)
919 } else {
920 Err(r.error())
921 }
922}
923
924pub fn twz_rt_socket_names(
925 name: impl AsRef<str>,
926 out_addrs: &mut [SocketAddress],
927) -> Result<usize> {
928 let name = name.as_ref().as_bytes();
929 let mut out_len = out_addrs.len() * size_of::<SocketAddress>();
930 let res = unsafe {
931 nk!(crate::bindings::twz_rt_canon_name(
932 NameResolver::Socket as u32,
933 name.as_ptr().cast(),
934 name.len(),
935 out_addrs.as_mut_ptr().cast(),
936 &mut out_len,
937 ))
938 };
939 let r = RawTwzError::new(res);
940 if r.is_success() {
941 Ok(out_len / size_of::<SocketAddress>())
942 } else {
943 Err(r.error())
944 }
945}