1 use super::prelude::*;
2 use crate::arch::Arch;
3 use crate::protocol::commands::ext::HostIo;
4 use crate::target::ext::host_io::HostIoError;
5 use crate::target::ext::host_io::HostIoStat;
6 
7 impl<T: Target, C: Connection> GdbStubImpl<T, C> {
handle_host_io( &mut self, res: &mut ResponseWriter<'_, C>, target: &mut T, command: HostIo<'_>, ) -> Result<HandlerStatus, Error<T::Error, C::Error>>8     pub(crate) fn handle_host_io(
9         &mut self,
10         res: &mut ResponseWriter<'_, C>,
11         target: &mut T,
12         command: HostIo<'_>,
13     ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
14         let ops = match target.support_host_io() {
15             Some(ops) => ops,
16             None => return Ok(HandlerStatus::Handled),
17         };
18 
19         crate::__dead_code_marker!("host_io", "impl");
20 
21         macro_rules! handle_hostio_result {
22             ( if let Ok($val:pat) = $ret:expr => $callback:block ) => {{
23                 match $ret {
24                     Ok($val) => $callback,
25                     Err(HostIoError::Errno(errno)) => {
26                         res.write_str("F-1,")?;
27                         res.write_num(errno as u32)?;
28                     }
29                     Err(HostIoError::Fatal(e)) => return Err(Error::TargetError(e)),
30                 }
31             }};
32         }
33 
34         let handler_status = match command {
35             HostIo::vFileOpen(cmd) if ops.support_open().is_some() => {
36                 let ops = ops.support_open().unwrap();
37                 handle_hostio_result! {
38                     if let Ok(fd) = ops.open(cmd.filename, cmd.flags, cmd.mode) => {
39                         res.write_str("F")?;
40                         res.write_num(fd)?;
41                     }
42                 }
43                 HandlerStatus::Handled
44             }
45             HostIo::vFileClose(cmd) if ops.support_close().is_some() => {
46                 let ops = ops.support_close().unwrap();
47                 handle_hostio_result! {
48                     if let Ok(()) = ops.close(cmd.fd) => {
49                         res.write_str("F0")?;
50                     }
51                 }
52                 HandlerStatus::Handled
53             }
54             HostIo::vFilePread(cmd) if ops.support_pread().is_some() => {
55                 let ops = ops.support_pread().unwrap();
56                 handle_hostio_result! {
57                     if let Ok(ret) = ops.pread(cmd.fd, cmd.count, cmd.offset, cmd.buf) => {
58                         res.write_str("F")?;
59                         res.write_num(ret)?;
60                         res.write_str(";")?;
61                         res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;
62                     }
63                 };
64 
65                 HandlerStatus::Handled
66             }
67             HostIo::vFilePwrite(cmd) if ops.support_pwrite().is_some() => {
68                 let offset = <T::Arch as Arch>::Usize::from_be_bytes(cmd.offset)
69                     .ok_or(Error::TargetMismatch)?;
70                 let ops = ops.support_pwrite().unwrap();
71                 handle_hostio_result! {
72                     if let Ok(ret) = ops.pwrite(cmd.fd, offset, cmd.data) => {
73                         res.write_str("F")?;
74                         res.write_num(ret)?;
75                     }
76                 };
77                 HandlerStatus::Handled
78             }
79             HostIo::vFileFstat(cmd) if ops.support_fstat().is_some() => {
80                 let ops = ops.support_fstat().unwrap();
81                 handle_hostio_result! {
82                     if let Ok(stat) = ops.fstat(cmd.fd) => {
83                         let size = core::mem::size_of::<HostIoStat>();
84                         res.write_str("F")?;
85                         res.write_num(size)?;
86                         res.write_str(";")?;
87                         res.write_binary(&stat.st_dev.to_be_bytes())?;
88                         res.write_binary(&stat.st_ino.to_be_bytes())?;
89                         res.write_binary(&(stat.st_mode.bits()).to_be_bytes())?;
90                         res.write_binary(&stat.st_nlink.to_be_bytes())?;
91                         res.write_binary(&stat.st_uid.to_be_bytes())?;
92                         res.write_binary(&stat.st_gid.to_be_bytes())?;
93                         res.write_binary(&stat.st_rdev.to_be_bytes())?;
94                         res.write_binary(&stat.st_size.to_be_bytes())?;
95                         res.write_binary(&stat.st_blksize.to_be_bytes())?;
96                         res.write_binary(&stat.st_blocks.to_be_bytes())?;
97                         res.write_binary(&stat.st_atime.to_be_bytes())?;
98                         res.write_binary(&stat.st_mtime.to_be_bytes())?;
99                         res.write_binary(&stat.st_ctime.to_be_bytes())?;
100                     }
101                 };
102                 HandlerStatus::Handled
103             }
104             HostIo::vFileUnlink(cmd) if ops.support_unlink().is_some() => {
105                 let ops = ops.support_unlink().unwrap();
106                 handle_hostio_result! {
107                     if let Ok(()) = ops.unlink(cmd.filename) => {
108                         res.write_str("F0")?;
109                     }
110                 };
111                 HandlerStatus::Handled
112             }
113             HostIo::vFileReadlink(cmd) if ops.support_readlink().is_some() => {
114                 let ops = ops.support_readlink().unwrap();
115                 handle_hostio_result! {
116                     if let Ok(ret) = ops.readlink(cmd.filename, cmd.buf) => {
117                         res.write_str("F")?;
118                         res.write_num(ret)?;
119                         res.write_str(";")?;
120                         res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;
121                     }
122                 };
123 
124                 HandlerStatus::Handled
125             }
126             HostIo::vFileSetfs(cmd) if ops.support_setfs().is_some() => {
127                 let ops = ops.support_setfs().unwrap();
128                 handle_hostio_result! {
129                     if let Ok(()) = ops.setfs(cmd.fs) => {
130                         res.write_str("F0")?;
131                     }
132                 };
133                 HandlerStatus::Handled
134             }
135             _ => HandlerStatus::Handled,
136         };
137 
138         Ok(handler_status)
139     }
140 }
141