mod.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. use libc::syscall;
  2. use std::{
  3. fs::{self, File, OpenOptions},
  4. io::{self, BufRead, BufReader, Read, Write},
  5. print,
  6. string::String,
  7. vec::Vec,
  8. };
  9. use crate::{special_keycode::*, Env};
  10. use command::{BuildInCmd, Command};
  11. pub mod command;
  12. pub struct Shell {
  13. history_commands: Vec<Vec<u8>>,
  14. executed_commands: Vec<Vec<u8>>,
  15. current_dir: String,
  16. }
  17. impl Shell {
  18. pub fn new() -> Shell {
  19. let mut shell = Shell {
  20. history_commands: Vec::new(),
  21. executed_commands: Vec::new(),
  22. current_dir: String::from("/"),
  23. };
  24. shell.read_commands();
  25. shell
  26. }
  27. pub fn current_dir(&self) -> String {
  28. self.current_dir.clone()
  29. }
  30. pub fn set_current_dir(&mut self, new_dir: &String) {
  31. self.current_dir = new_dir.clone();
  32. Env::insert(String::from("PWD"), self.current_dir());
  33. }
  34. pub fn exec(&mut self) {
  35. let mut buf: Vec<u8>;
  36. loop {
  37. buf = Vec::new();
  38. buf.push(b' ');
  39. self.history_commands.push(buf);
  40. Printer::print_prompt(&self.current_dir);
  41. if self.readline(0) == 0 {
  42. Printer::print(&[CR, LF]);
  43. break;
  44. }
  45. let command_bytes = self.history_commands.last().unwrap().clone();
  46. let mut temp = command_bytes.clone();
  47. temp.retain(|byte| *byte != b' ');
  48. if temp.len() == 0 {
  49. self.history_commands.pop().unwrap();
  50. } else {
  51. self.executed_commands.push(command_bytes.clone());
  52. self.exec_command_in_bytes(&command_bytes);
  53. }
  54. }
  55. self.write_commands();
  56. }
  57. fn exec_command_in_bytes(&mut self, command_bytes: &Vec<u8>) {
  58. let commands = Command::from_strings(String::from_utf8(command_bytes.clone()).unwrap());
  59. commands
  60. .iter()
  61. .for_each(|command| self.exec_command(command));
  62. }
  63. fn read_commands(&mut self) {
  64. for line in BufReader::new(match File::open("history_commands.txt") {
  65. Ok(file) => file,
  66. Err(_) => File::create("history_commands.txt").unwrap(),
  67. })
  68. .lines()
  69. {
  70. match line {
  71. Ok(s) => self.history_commands.push(s.into_bytes()),
  72. Err(_) => {
  73. break;
  74. }
  75. }
  76. }
  77. }
  78. fn write_commands(&self) {
  79. let mut file = OpenOptions::new()
  80. .append(true)
  81. .open("history_commands.txt")
  82. .unwrap();
  83. for command_line in &self.executed_commands {
  84. file.write_all(&command_line[..]).unwrap();
  85. file.write_all(&[LF]).unwrap();
  86. }
  87. }
  88. fn read_char(byte: &mut u8) {
  89. let mut c: libc::c_uchar = 0;
  90. unsafe {
  91. let p = &mut c as *mut libc::c_uchar as *mut libc::c_void;
  92. libc::read(0, p, 1);
  93. }
  94. *byte = c;
  95. }
  96. fn readline(&mut self, fd: usize) -> usize {
  97. let mut stdin = std::io::stdin();
  98. let mut stdout = std::io::stdout();
  99. let prompt: String = self.current_dir.clone();
  100. let history_commands = &mut self.history_commands;
  101. let len = history_commands.len() - 1;
  102. let mut key: [u8; 1] = [0];
  103. let mut command_index = len;
  104. let mut buf = history_commands.get_mut(command_index).unwrap();
  105. let mut cursor = 0;
  106. Printer::print_cursor(b' ');
  107. stdout.flush().unwrap();
  108. loop {
  109. Self::read_char(&mut key[0]);
  110. // if stdin.read(&mut key).ok() != Some(1) {
  111. // continue;
  112. // }
  113. if key[0] == 224 {
  114. Self::read_char(&mut key[0]);
  115. // stdin.read(&mut key).unwrap();
  116. if key[0] == b'\x1b' {
  117. panic!();
  118. }
  119. if key[0] == UP || key[0] == DOWN {
  120. if key[0] == UP && command_index > 0 {
  121. command_index -= 1;
  122. }
  123. if key[0] == DOWN && command_index < len {
  124. command_index += 1;
  125. }
  126. let old_length = buf.len();
  127. buf = history_commands.get_mut(command_index).unwrap();
  128. Printer::replace(&buf, old_length);
  129. cursor = buf.len() - 1;
  130. }
  131. if key[0] == LEFT || key[0] == RIGHT {
  132. match key[0] {
  133. LEFT => {
  134. if cursor > 0 {
  135. Printer::set_cursor(buf, cursor, cursor - 1);
  136. cursor -= 1;
  137. }
  138. }
  139. RIGHT => {
  140. if cursor < buf.len() - 1 {
  141. Printer::set_cursor(buf, cursor, cursor + 1);
  142. cursor += 1;
  143. }
  144. }
  145. _ => {}
  146. }
  147. }
  148. } else {
  149. if key[0] == TAB && buf.len() > 1 && buf[cursor - 1] != b' ' {
  150. let command: String = String::from_utf8(buf[..cursor].to_vec()).unwrap();
  151. let mut command_frag = command.split_ascii_whitespace().collect::<Vec<_>>();
  152. let incomplete_frag = command_frag.pop().unwrap();
  153. let mut incomplete_len: usize = incomplete_frag.len();
  154. let candidates = match command_frag.len() {
  155. 0 => Printer::complete_command(incomplete_frag),
  156. 1.. => {
  157. if let Some(index) = incomplete_frag.rfind('/') {
  158. incomplete_len = incomplete_frag.len() - index - 1;
  159. } else {
  160. incomplete_len = incomplete_frag.len();
  161. }
  162. Printer::complete_path(incomplete_frag)
  163. }
  164. _ => Vec::new(),
  165. };
  166. match candidates.len() {
  167. 1 => {
  168. let complete_part = candidates[0][incomplete_len..].as_bytes();
  169. Printer::delete_from_index(cursor, buf.len());
  170. // stdout.write_all(complete_part).unwrap();
  171. Printer::print(complete_part);
  172. Printer::print_cursor(buf[cursor]);
  173. Printer::print(&buf[cursor + 1..]);
  174. buf.splice(cursor..cursor, complete_part.iter().cloned());
  175. cursor += candidates[0].len() - incomplete_len;
  176. }
  177. 2.. => {
  178. Printer::delete_from_index(cursor, buf.len());
  179. Printer::print(&buf[cursor..buf.len()]);
  180. Printer::print(&[CR, LF]);
  181. for candidate in candidates {
  182. print!("{candidate} ");
  183. }
  184. Printer::print(&[CR, LF]);
  185. Printer::print_prompt(&prompt);
  186. Printer::print(&buf[..buf.len() - 1]);
  187. Printer::print_cursor(b' ');
  188. }
  189. _ => {}
  190. }
  191. }
  192. match key[0] {
  193. CR | LF => {
  194. if cursor > 0 {
  195. Printer::set_cursor(buf, cursor, buf.len());
  196. Printer::print(&[CR, LF]);
  197. let mut command = buf.clone();
  198. buf = history_commands.get_mut(len).unwrap();
  199. buf.clear();
  200. buf.append(&mut command);
  201. return 1;
  202. }
  203. }
  204. BS | DL => {
  205. if cursor > 0 {
  206. Printer::delete(cursor, 1, buf);
  207. buf.remove(cursor - 1);
  208. cursor -= 1;
  209. }
  210. }
  211. 1..=31 => {}
  212. c => {
  213. Printer::insert(cursor, &[c], buf);
  214. buf.insert(cursor, c);
  215. cursor += 1;
  216. }
  217. }
  218. }
  219. stdout.flush().unwrap();
  220. }
  221. }
  222. }
  223. struct Printer;
  224. impl Printer {
  225. fn print_prompt(current_dir: &String) {
  226. io::stdout().flush().unwrap();
  227. unsafe {
  228. syscall(100000, "[DragonOS]:\0".as_ptr(), 0x0000ff90, 0x00000000);
  229. syscall(
  230. 100000,
  231. format!("{}\0", current_dir).as_ptr(),
  232. 0x000088ff,
  233. 0x00000000,
  234. );
  235. print!("$ ");
  236. }
  237. }
  238. fn print_cursor(c: u8) {
  239. Self::print_color(&[c], 0x00000000, 0x00ffffff);
  240. }
  241. fn delete_from_index(index: usize, length: usize) {
  242. for _i in 0..length - index {
  243. Printer::print(&[BS, SPACE, BS]);
  244. }
  245. }
  246. fn insert(cursor: usize, bytes: &[u8], buf: &Vec<u8>) {
  247. Printer::delete_from_index(cursor, buf.len());
  248. Printer::print(bytes);
  249. Printer::print_cursor(buf[cursor]);
  250. Printer::print(&buf[cursor + 1..]);
  251. }
  252. fn delete(cursor: usize, length: usize, buf: &Vec<u8>) {
  253. Printer::delete_from_index(cursor - length, buf.len());
  254. Printer::print_cursor(buf[cursor]);
  255. Printer::print(&buf[cursor + 1..]);
  256. }
  257. fn replace(bytes: &[u8], old_length: usize) {
  258. Printer::delete_from_index(0, old_length);
  259. Printer::print(&bytes[0..bytes.len() - 1]);
  260. Printer::print_cursor(b' ');
  261. }
  262. fn print(bytes: &[u8]) {
  263. print!("{}", String::from_utf8(bytes.to_vec()).unwrap());
  264. }
  265. fn print_color(bytes: &[u8], front_color: usize, background_color: usize) {
  266. std::io::stdout().flush().unwrap();
  267. let cstr = std::ffi::CString::new(bytes).unwrap();
  268. unsafe {
  269. dsc::syscall!(SYS_PUT_STRING, cstr.as_ptr(), front_color, background_color);
  270. }
  271. }
  272. fn set_cursor(buf: &mut Vec<u8>, old_index: usize, new_index: usize) {
  273. if new_index < buf.len() {
  274. let index = std::cmp::min(old_index, new_index);
  275. Printer::delete_from_index(index, buf.len());
  276. Printer::print(&buf[index..new_index]);
  277. Printer::print_cursor(buf[new_index]);
  278. Printer::print(&buf[new_index + 1..]);
  279. } else {
  280. Printer::delete_from_index(old_index, buf.len());
  281. Printer::print(&buf[old_index..]);
  282. }
  283. }
  284. fn complete_command(command: &str) -> Vec<String> {
  285. let mut candidates: Vec<String> = Vec::new();
  286. for BuildInCmd(cmd) in BuildInCmd::BUILD_IN_CMD {
  287. if cmd.starts_with(command) {
  288. candidates.push(String::from(*cmd));
  289. }
  290. }
  291. candidates
  292. }
  293. fn complete_path(path: &str) -> Vec<String> {
  294. let mut candidates: Vec<String> = Vec::new();
  295. let dir: &str;
  296. let incomplete_name: &str;
  297. if let Some(index) = path.rfind('/') {
  298. dir = &path[..=index];
  299. if index < path.len() {
  300. incomplete_name = &path[index + 1..];
  301. } else {
  302. incomplete_name = "";
  303. }
  304. } else {
  305. dir = ".";
  306. incomplete_name = &path[..];
  307. }
  308. match fs::read_dir(dir) {
  309. Ok(read_dir) => {
  310. if incomplete_name == "" {
  311. for entry in read_dir {
  312. let entry = entry.unwrap();
  313. let mut file_name = entry.file_name().into_string().unwrap();
  314. if entry.file_type().unwrap().is_dir() {
  315. file_name.push('/');
  316. }
  317. candidates.push(file_name);
  318. }
  319. } else {
  320. for entry in read_dir {
  321. let entry = entry.unwrap();
  322. let mut file_name = entry.file_name().into_string().unwrap();
  323. if file_name.starts_with(incomplete_name) {
  324. if entry.file_type().unwrap().is_dir() {
  325. file_name.push('/');
  326. }
  327. candidates.push(file_name);
  328. }
  329. }
  330. }
  331. }
  332. Err(_) => {}
  333. }
  334. return candidates;
  335. }
  336. }