1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
// Copyright (c) 2020 Alex Chi // // This software is released under the MIT License. // https://opensource.org/licenses/MIT //! All syscalls of core-os //! //! Syscalls of core-os are defined and implemented with Rust //! primitives (e.g. `str`, `[u8]`). This module will transmute //! these Rust primitives into pointers and other machine-specific //! representations before calling functions in `syscall_internal` and //! trapping into kernel. //! //! Usage of syscalls is listed in their corresponding sub-page. use crate::syscall_internal::*; use core::ptr::null; /// Exit current process with exit code `code`. /// /// # Examples /// /// ``` /// use user::syscall::exit; /// exit(0); /// ``` pub fn exit(code: i32) -> ! { unsafe { __exit(code) } } /// Fork current process. /// /// Child process will get return value of 0. /// Parent process (the one calling `fork`) will /// get pid of child process. /// /// # Examples /// /// ``` /// use user::syscall::fork; /// if fork() == 0 { /// println!("subprocess!"); /// } else { /// println!("parent process"); /// } /// ``` pub fn fork() -> i32 { unsafe { __fork() } } pub const EXEC_MAX_ARGS: usize = 10; /// Replace current process image with the new one /// in the filesystem. /// /// This function will not return. /// /// # Examples /// ``` /// use user::syscall::exec; /// exec("/init", &[]); /// ``` pub fn exec(path: &str, args: &[&str]) -> ! { let arg_cnt = args.len(); let mut args_sz = [0; EXEC_MAX_ARGS]; let mut args_ptr = [null(); EXEC_MAX_ARGS]; for i in 0..args.len() { args_sz[i] = args[i].len() as i32; args_ptr[i] = args[i].as_bytes().as_ptr() as *const u8; } unsafe { __exec( path.as_bytes().as_ptr() as *const u8, path.len() as i32, arg_cnt as i32, args_ptr.as_ptr(), args_sz.as_ptr() ) } } /// Write `content` to file descriptor `fd`. /// /// Returns number of characters written. A negative return value means error while writing. /// /// # Examples /// ``` /// use user::syscall::write; /// use user::constant::STDOUT; /// write(STDOUT, "Hello, World!"); /// ``` pub fn write(fd: i32, content: &[u8]) -> i32 { unsafe { __write(fd, content.as_ptr(), content.len() as i32) } } /// Read `content` from file descriptor `fd`. /// /// You may read a maximum of `content.len()` characters from `fd`. /// Returns number of characters read. pub fn read(fd: i32, content: &mut [u8]) -> i32 { unsafe { __read(fd, content.as_mut_ptr(), content.len() as i32) } } /// Open file of `path` with `mode`. /// /// This function returns file descriptor. Negative value means error. /// /// # Examples /// ``` /// use user::syscall::open; /// let fd = open("/console", 0); /// ``` pub fn open(path: &str, mode: i32) -> i32 { unsafe { __open(path.as_ptr(), path.len() as i32, mode) } } /// Close a file with file descriptor `fd`. /// /// # Examples /// ``` /// use user::syscall::close; /// close(0); /// ``` pub fn close(fd: i32) -> i32 { unsafe { __close(fd) } } /// Duplicate file descriptor `fd`. /// /// Returns new file descriptor. /// /// # Examples /// ``` /// use user::syscall::dup; /// use user::constant::STDIN; /// let fd = dup(STDIN); /// ``` pub fn dup(fd: i32) -> i32 { unsafe { __dup(fd) } } pub fn wait(pid: i32) -> i32 { unsafe { __wait(pid) } }