redox_syscall-0.1.40/.gitignore010064400017500001750000000000221320022572600146510ustar0000000000000000Cargo.lock target redox_syscall-0.1.40/Cargo.toml.orig010064400017500001750000000004611330354263000155570ustar0000000000000000[package] name = "redox_syscall" version = "0.1.40" description = "A Rust library to access raw Redox system calls" license = "MIT" authors = ["Jeremy Soller "] repository = "https://github.com/redox-os/syscall" documentation = "https://docs.rs/redox_syscall" [lib] name = "syscall" redox_syscall-0.1.40/Cargo.toml0000644000000014750000000000000120350ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "redox_syscall" version = "0.1.40" authors = ["Jeremy Soller "] description = "A Rust library to access raw Redox system calls" documentation = "https://docs.rs/redox_syscall" license = "MIT" repository = "https://github.com/redox-os/syscall" [lib] name = "syscall" redox_syscall-0.1.40/LICENSE010064400017500001750000000020641320022572600136760ustar0000000000000000Copyright (c) 2017 Redox OS Developers MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. redox_syscall-0.1.40/README.md010064400017500001750000000001741320022572600141500ustar0000000000000000[Redox OS][1]'s syscall API [Documentation][2] [1]: https://github.com/redox-os/redox [2]: https://docs.rs/redox_syscall redox_syscall-0.1.40/rust-toolchain010064400017500001750000000000101322401270100155450ustar0000000000000000nightly redox_syscall-0.1.40/src/arch/arm.rs010064400017500001750000000033301320022572600155170ustar0000000000000000use super::error::{Error, Result}; pub unsafe fn syscall0(mut a: usize) -> Result { asm!("swi $$0" : "={r0}"(a) : "{r7}"(a) : "memory" : "volatile"); Error::demux(a) } pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { asm!("swi $$0" : "={r0}"(a) : "{r7}"(a), "{r0}"(b) : "memory" : "volatile"); Error::demux(a) } // Clobbers all registers - special for clone pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { asm!("swi $$0" : "={r0}"(a) : "{r7}"(a), "{r0}"(b) : "memory", "r0", "r1", "r2", "r3", "r4" : "volatile"); Error::demux(a) } pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { asm!("swi $$0" : "={r0}"(a) : "{r7}"(a), "{r0}"(b), "{r1}"(c) : "memory" : "volatile"); Error::demux(a) } pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { asm!("swi $$0" : "={r0}"(a) : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d) : "memory" : "volatile"); Error::demux(a) } pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { asm!("swi $$0" : "={r0}"(a) : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e) : "memory" : "volatile"); Error::demux(a) } pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> Result { asm!("swi $$0" : "={r0}"(a) : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e), "{r4}"(f) : "memory" : "volatile"); Error::demux(a) } redox_syscall-0.1.40/src/arch/x86.rs010064400017500001750000000035011320022572600153650ustar0000000000000000use super::error::{Error, Result}; pub unsafe fn syscall0(mut a: usize) -> Result { asm!("int 0x80" : "={eax}"(a) : "{eax}"(a) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { asm!("int 0x80" : "={eax}"(a) : "{eax}"(a), "{ebx}"(b) : "memory" : "intel", "volatile"); Error::demux(a) } // Clobbers all registers - special for clone pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { asm!("int 0x80" : "={eax}"(a) : "{eax}"(a), "{ebx}"(b) : "memory", "ebx", "ecx", "edx", "esi", "edi" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { asm!("int 0x80" : "={eax}"(a) : "{eax}"(a), "{ebx}"(b), "{ecx}"(c) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { asm!("int 0x80" : "={eax}"(a) : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { asm!("int 0x80" : "={eax}"(a) : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> Result { asm!("int 0x80" : "={eax}"(a) : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e), "{edi}"(f) : "memory" : "intel", "volatile"); Error::demux(a) } redox_syscall-0.1.40/src/arch/x86_64.rs010064400017500001750000000036011320022572600156770ustar0000000000000000use super::error::{Error, Result}; pub unsafe fn syscall0(mut a: usize) -> Result { asm!("int 0x80" : "={rax}"(a) : "{rax}"(a) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall1(mut a: usize, b: usize) -> Result { asm!("int 0x80" : "={rax}"(a) : "{rax}"(a), "{rbx}"(b) : "memory" : "intel", "volatile"); Error::demux(a) } // Clobbers all registers - special for clone pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result { asm!("int 0x80" : "={rax}"(a) : "{rax}"(a), "{rbx}"(b) : "memory", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result { asm!("int 0x80" : "={rax}"(a) : "{rax}"(a), "{rbx}"(b), "{rcx}"(c) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result { asm!("int 0x80" : "={rax}"(a) : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result { asm!("int 0x80" : "={rax}"(a) : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e) : "memory" : "intel", "volatile"); Error::demux(a) } pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> Result { asm!("int 0x80" : "={rax}"(a) : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e), "{rdi}"(f) : "memory" : "intel", "volatile"); Error::demux(a) } redox_syscall-0.1.40/src/call.rs010064400017500001750000000262611330037275600147550ustar0000000000000000use super::arch::*; use super::data::{SigAction, Stat, StatVfs, TimeSpec}; use super::error::Result; use super::number::*; use core::{mem, ptr}; // Signal restorer extern "C" fn restorer() -> ! { sigreturn().unwrap(); unreachable!(); } /// Set the end of the process's heap /// /// When `addr` is `0`, this function will return the current break. /// /// When `addr` is nonzero, this function will attempt to set the end of the process's /// heap to `addr` and return the new program break. The new program break should be /// checked by the allocator, it may not be exactly `addr`, as it may be aligned to a page /// boundary. /// /// On error, `Err(ENOMEM)` will be returned indicating that no memory is available pub unsafe fn brk(addr: usize) -> Result { syscall1(SYS_BRK, addr) } /// Change the process's working directory /// /// This function will attempt to set the process's working directory to `path`, which can be /// either a relative, scheme relative, or absolute path. /// /// On success, `Ok(0)` will be returned. On error, one of the following errors will be returned. /// /// # Errors /// /// * `EACCES` - permission is denied for one of the components of `path`, or `path` /// * `EFAULT` - `path` does not point to the process's addressible memory /// * `EIO` - an I/O error occurred /// * `ENOENT` - `path` does not exit /// * `ENOTDIR` - `path` is not a directory pub fn chdir>(path: T) -> Result { unsafe { syscall2(SYS_CHDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } pub fn chmod>(path: T, mode: usize) -> Result { unsafe { syscall3(SYS_CHMOD, path.as_ref().as_ptr() as usize, path.as_ref().len(), mode) } } /// Produce a fork of the current process, or a new process thread pub unsafe fn clone(flags: usize) -> Result { syscall1_clobber(SYS_CLONE, flags) } /// Close a file pub fn close(fd: usize) -> Result { unsafe { syscall1(SYS_CLOSE, fd) } } /// Get the current system time pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result { unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) } } /// Copy and transform a file descriptor pub fn dup(fd: usize, buf: &[u8]) -> Result { unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) } } /// Copy and transform a file descriptor pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result { unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) } } /// Replace the current process with a new executable pub fn execve>(path: T, args: &[[usize; 2]]) -> Result { unsafe { syscall4(SYS_EXECVE, path.as_ref().as_ptr() as usize, path.as_ref().len(), args.as_ptr() as usize, args.len()) } } /// Exit the current process pub fn exit(status: usize) -> Result { unsafe { syscall1(SYS_EXIT, status) } } /// Change file permissions pub fn fchmod(fd: usize, mode: u16) -> Result { unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) } } /// Change file ownership pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result { unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) } } /// Change file descriptor flags pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result { unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) } } /// Map a file into memory pub unsafe fn fmap(fd: usize, offset: usize, size: usize) -> Result { syscall3(SYS_FMAP, fd, offset, size) } /// Unmap a memory-mapped file pub unsafe fn funmap(addr: usize) -> Result { syscall1(SYS_FUNMAP, addr) } /// Retrieve the canonical path of a file pub fn fpath(fd: usize, buf: &mut [u8]) -> Result { unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) } } /// Rename a file pub fn frename>(fd: usize, path: T) -> Result { unsafe { syscall3(SYS_FRENAME, fd, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } /// Get metadata about a file pub fn fstat(fd: usize, stat: &mut Stat) -> Result { unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::()) } } /// Get metadata about a filesystem pub fn fstatvfs(fd: usize, stat: &mut StatVfs) -> Result { unsafe { syscall3(SYS_FSTATVFS, fd, stat as *mut StatVfs as usize, mem::size_of::()) } } /// Sync a file descriptor to its underlying medium pub fn fsync(fd: usize) -> Result { unsafe { syscall1(SYS_FSYNC, fd) } } /// Truncate or extend a file to a specified length pub fn ftruncate(fd: usize, len: usize) -> Result { unsafe { syscall2(SYS_FTRUNCATE, fd, len) } } // Change modify and/or access times pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result { unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, times.len() * mem::size_of::()) } } /// Fast userspace mutex pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32) -> Result { syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize) } /// Get the current working directory pub fn getcwd(buf: &mut [u8]) -> Result { unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) } } /// Get the effective group ID pub fn getegid() -> Result { unsafe { syscall0(SYS_GETEGID) } } /// Get the effective namespace pub fn getens() -> Result { unsafe { syscall0(SYS_GETENS) } } /// Get the effective user ID pub fn geteuid() -> Result { unsafe { syscall0(SYS_GETEUID) } } /// Get the current group ID pub fn getgid() -> Result { unsafe { syscall0(SYS_GETGID) } } /// Get the current namespace pub fn getns() -> Result { unsafe { syscall0(SYS_GETNS) } } /// Get the current process ID pub fn getpid() -> Result { unsafe { syscall0(SYS_GETPID) } } /// Get the process group ID pub fn getpgid(pid: usize) -> Result { unsafe { syscall1(SYS_GETPGID, pid) } } /// Get the parent process ID pub fn getppid() -> Result { unsafe { syscall0(SYS_GETPPID) } } /// Get the current user ID pub fn getuid() -> Result { unsafe { syscall0(SYS_GETUID) } } /// Set the I/O privilege level pub unsafe fn iopl(level: usize) -> Result { syscall1(SYS_IOPL, level) } /// Send a signal `sig` to the process identified by `pid` pub fn kill(pid: usize, sig: usize) -> Result { unsafe { syscall2(SYS_KILL, pid, sig) } } /// Create a link to a file pub unsafe fn link(old: *const u8, new: *const u8) -> Result { syscall2(SYS_LINK, old as usize, new as usize) } /// Seek to `offset` bytes in a file descriptor pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result { unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) } } /// Make a new scheme namespace pub fn mkns(schemes: &[[usize; 2]]) -> Result { unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) } } /// Sleep for the time specified in `req` pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result { unsafe { syscall2(SYS_NANOSLEEP, req as *const TimeSpec as usize, rem as *mut TimeSpec as usize) } } /// Open a file pub fn open>(path: T, flags: usize) -> Result { unsafe { syscall3(SYS_OPEN, path.as_ref().as_ptr() as usize, path.as_ref().len(), flags) } } /// Allocate pages, linearly in physical memory pub unsafe fn physalloc(size: usize) -> Result { syscall1(SYS_PHYSALLOC, size) } /// Free physically allocated pages pub unsafe fn physfree(physical_address: usize, size: usize) -> Result { syscall2(SYS_PHYSFREE, physical_address, size) } /// Map physical memory to virtual memory pub unsafe fn physmap(physical_address: usize, size: usize, flags: usize) -> Result { syscall3(SYS_PHYSMAP, physical_address, size, flags) } /// Unmap previously mapped physical memory pub unsafe fn physunmap(virtual_address: usize) -> Result { syscall1(SYS_PHYSUNMAP, virtual_address) } /// Create a pair of file descriptors referencing the read and write ends of a pipe pub fn pipe2(fds: &mut [usize; 2], flags: usize) -> Result { unsafe { syscall2(SYS_PIPE2, fds.as_ptr() as usize, flags) } } /// Read from a file descriptor into a buffer pub fn read(fd: usize, buf: &mut [u8]) -> Result { unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) } } /// Remove a directory pub fn rmdir>(path: T) -> Result { unsafe { syscall2(SYS_RMDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } /// Set the process group ID pub fn setpgid(pid: usize, pgid: usize) -> Result { unsafe { syscall2(SYS_SETPGID, pid, pgid) } } /// Set the current process group IDs pub fn setregid(rgid: usize, egid: usize) -> Result { unsafe { syscall2(SYS_SETREGID, rgid, egid) } } /// Make a new scheme namespace pub fn setrens(rns: usize, ens: usize) -> Result { unsafe { syscall2(SYS_SETRENS, rns, ens) } } /// Set the current process user IDs pub fn setreuid(ruid: usize, euid: usize) -> Result { unsafe { syscall2(SYS_SETREUID, ruid, euid) } } /// Set up a signal handler pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>) -> Result { unsafe { syscall4(SYS_SIGACTION, sig, act.map(|x| x as *const _).unwrap_or_else(ptr::null) as usize, oldact.map(|x| x as *mut _).unwrap_or_else(ptr::null_mut) as usize, restorer as usize) } } // Return from signal handler pub fn sigreturn() -> Result { unsafe { syscall0(SYS_SIGRETURN) } } /// Remove a file pub fn unlink>(path: T) -> Result { unsafe { syscall2(SYS_UNLINK, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } /// Convert a virtual address to a physical one pub unsafe fn virttophys(virtual_address: usize) -> Result { syscall1(SYS_VIRTTOPHYS, virtual_address) } /// Check if a child process has exited or received a signal pub fn waitpid(pid: usize, status: &mut usize, options: usize) -> Result { unsafe { syscall3(SYS_WAITPID, pid, status as *mut usize as usize, options) } } /// Write a buffer to a file descriptor /// /// The kernel will attempt to write the bytes in `buf` to the file descriptor `fd`, returning /// either an `Err`, explained below, or `Ok(count)` where `count` is the number of bytes which /// were written. /// /// # Errors /// /// * `EAGAIN` - the file descriptor was opened with `O_NONBLOCK` and writing would block /// * `EBADF` - the file descriptor is not valid or is not open for writing /// * `EFAULT` - `buf` does not point to the process's addressible memory /// * `EIO` - an I/O error occurred /// * `ENOSPC` - the device containing the file descriptor has no room for data /// * `EPIPE` - the file descriptor refers to a pipe or socket whose reading end is closed pub fn write(fd: usize, buf: &[u8]) -> Result { unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) } } /// Yield the process's time slice to the kernel /// /// This function will return Ok(0) on success pub fn sched_yield() -> Result { unsafe { syscall0(SYS_YIELD) } } redox_syscall-0.1.40/src/data.rs010064400017500001750000000074221320022572600147420ustar0000000000000000use core::ops::{Deref, DerefMut}; use core::{mem, slice}; #[derive(Copy, Clone, Debug, Default)] pub struct Event { pub id: usize, pub flags: usize, pub data: usize } impl Deref for Event { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) as &[u8] } } } impl DerefMut for Event { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) as &mut [u8] } } } #[derive(Copy, Clone, Debug, Default)] #[repr(C)] pub struct Packet { pub id: u64, pub pid: usize, pub uid: u32, pub gid: u32, pub a: usize, pub b: usize, pub c: usize, pub d: usize } impl Deref for Packet { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::()) as &[u8] } } } impl DerefMut for Packet { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::()) as &mut [u8] } } } #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct SigAction { pub sa_handler: extern "C" fn(usize), pub sa_mask: [u64; 2], pub sa_flags: usize, } impl Default for SigAction { fn default() -> Self { Self { sa_handler: unsafe { mem::transmute(0usize) }, sa_mask: [0; 2], sa_flags: 0, } } } #[derive(Copy, Clone, Debug, Default)] #[repr(C)] pub struct Stat { pub st_dev: u64, pub st_ino: u64, pub st_mode: u16, pub st_nlink: u32, pub st_uid: u32, pub st_gid: u32, pub st_size: u64, pub st_blksize: u32, pub st_blocks: u64, pub st_mtime: u64, pub st_mtime_nsec: u32, pub st_atime: u64, pub st_atime_nsec: u32, pub st_ctime: u64, pub st_ctime_nsec: u32, } impl Deref for Stat { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const Stat as *const u8, mem::size_of::()) as &[u8] } } } impl DerefMut for Stat { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut Stat as *mut u8, mem::size_of::()) as &mut [u8] } } } #[derive(Copy, Clone, Debug, Default)] #[repr(C)] pub struct StatVfs { pub f_bsize: u32, pub f_blocks: u64, pub f_bfree: u64, pub f_bavail: u64, } impl Deref for StatVfs { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const StatVfs as *const u8, mem::size_of::()) as &[u8] } } } impl DerefMut for StatVfs { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut StatVfs as *mut u8, mem::size_of::()) as &mut [u8] } } } #[derive(Copy, Clone, Debug, Default)] #[repr(C)] pub struct TimeSpec { pub tv_sec: i64, pub tv_nsec: i32, } impl Deref for TimeSpec { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const TimeSpec as *const u8, mem::size_of::()) as &[u8] } } } impl DerefMut for TimeSpec { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8, mem::size_of::()) as &mut [u8] } } } redox_syscall-0.1.40/src/error.rs010064400017500001750000000436101330353044100151560ustar0000000000000000use core::{fmt, result}; #[derive(Eq, PartialEq)] pub struct Error { pub errno: i32, } pub type Result = result::Result; impl Error { pub fn new(errno: i32) -> Error { Error { errno: errno } } pub fn mux(result: Result) -> usize { match result { Ok(value) => value, Err(error) => -error.errno as usize, } } pub fn demux(value: usize) -> Result { let errno = -(value as i32); if errno >= 1 && errno < STR_ERROR.len() as i32 { Err(Error::new(errno)) } else { Ok(value) } } pub fn text(&self) -> &str { if let Some(description) = STR_ERROR.get(self.errno as usize) { description } else { "Unknown Error" } } } impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { f.write_str(self.text()) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { f.write_str(self.text()) } } pub const EPERM: i32 = 1; /* Operation not permitted */ pub const ENOENT: i32 = 2; /* No such file or directory */ pub const ESRCH: i32 = 3; /* No such process */ pub const EINTR: i32 = 4; /* Interrupted system call */ pub const EIO: i32 = 5; /* I/O error */ pub const ENXIO: i32 = 6; /* No such device or address */ pub const E2BIG: i32 = 7; /* Argument list too long */ pub const ENOEXEC: i32 = 8; /* Exec format error */ pub const EBADF: i32 = 9; /* Bad file number */ pub const ECHILD: i32 = 10; /* No child processes */ pub const EAGAIN: i32 = 11; /* Try again */ pub const ENOMEM: i32 = 12; /* Out of memory */ pub const EACCES: i32 = 13; /* Permission denied */ pub const EFAULT: i32 = 14; /* Bad address */ pub const ENOTBLK: i32 = 15; /* Block device required */ pub const EBUSY: i32 = 16; /* Device or resource busy */ pub const EEXIST: i32 = 17; /* File exists */ pub const EXDEV: i32 = 18; /* Cross-device link */ pub const ENODEV: i32 = 19; /* No such device */ pub const ENOTDIR: i32 = 20; /* Not a directory */ pub const EISDIR: i32 = 21; /* Is a directory */ pub const EINVAL: i32 = 22; /* Invalid argument */ pub const ENFILE: i32 = 23; /* File table overflow */ pub const EMFILE: i32 = 24; /* Too many open files */ pub const ENOTTY: i32 = 25; /* Not a typewriter */ pub const ETXTBSY: i32 = 26; /* Text file busy */ pub const EFBIG: i32 = 27; /* File too large */ pub const ENOSPC: i32 = 28; /* No space left on device */ pub const ESPIPE: i32 = 29; /* Illegal seek */ pub const EROFS: i32 = 30; /* Read-only file system */ pub const EMLINK: i32 = 31; /* Too many links */ pub const EPIPE: i32 = 32; /* Broken pipe */ pub const EDOM: i32 = 33; /* Math argument out of domain of func */ pub const ERANGE: i32 = 34; /* Math result not representable */ pub const EDEADLK: i32 = 35; /* Resource deadlock would occur */ pub const ENAMETOOLONG: i32 = 36; /* File name too long */ pub const ENOLCK: i32 = 37; /* No record locks available */ pub const ENOSYS: i32 = 38; /* Function not implemented */ pub const ENOTEMPTY: i32 = 39; /* Directory not empty */ pub const ELOOP: i32 = 40; /* Too many symbolic links encountered */ pub const EWOULDBLOCK: i32 = 41; /* Operation would block */ pub const ENOMSG: i32 = 42; /* No message of desired type */ pub const EIDRM: i32 = 43; /* Identifier removed */ pub const ECHRNG: i32 = 44; /* Channel number out of range */ pub const EL2NSYNC: i32 = 45; /* Level 2 not synchronized */ pub const EL3HLT: i32 = 46; /* Level 3 halted */ pub const EL3RST: i32 = 47; /* Level 3 reset */ pub const ELNRNG: i32 = 48; /* Link number out of range */ pub const EUNATCH: i32 = 49; /* Protocol driver not attached */ pub const ENOCSI: i32 = 50; /* No CSI structure available */ pub const EL2HLT: i32 = 51; /* Level 2 halted */ pub const EBADE: i32 = 52; /* Invalid exchange */ pub const EBADR: i32 = 53; /* Invalid request descriptor */ pub const EXFULL: i32 = 54; /* Exchange full */ pub const ENOANO: i32 = 55; /* No anode */ pub const EBADRQC: i32 = 56; /* Invalid request code */ pub const EBADSLT: i32 = 57; /* Invalid slot */ pub const EDEADLOCK: i32 = 58; /* Resource deadlock would occur */ pub const EBFONT: i32 = 59; /* Bad font file format */ pub const ENOSTR: i32 = 60; /* Device not a stream */ pub const ENODATA: i32 = 61; /* No data available */ pub const ETIME: i32 = 62; /* Timer expired */ pub const ENOSR: i32 = 63; /* Out of streams resources */ pub const ENONET: i32 = 64; /* Machine is not on the network */ pub const ENOPKG: i32 = 65; /* Package not installed */ pub const EREMOTE: i32 = 66; /* Object is remote */ pub const ENOLINK: i32 = 67; /* Link has been severed */ pub const EADV: i32 = 68; /* Advertise error */ pub const ESRMNT: i32 = 69; /* Srmount error */ pub const ECOMM: i32 = 70; /* Communication error on send */ pub const EPROTO: i32 = 71; /* Protocol error */ pub const EMULTIHOP: i32 = 72; /* Multihop attempted */ pub const EDOTDOT: i32 = 73; /* RFS specific error */ pub const EBADMSG: i32 = 74; /* Not a data message */ pub const EOVERFLOW: i32 = 75; /* Value too large for defined data type */ pub const ENOTUNIQ: i32 = 76; /* Name not unique on network */ pub const EBADFD: i32 = 77; /* File descriptor in bad state */ pub const EREMCHG: i32 = 78; /* Remote address changed */ pub const ELIBACC: i32 = 79; /* Can not access a needed shared library */ pub const ELIBBAD: i32 = 80; /* Accessing a corrupted shared library */ pub const ELIBSCN: i32 = 81; /* .lib section in a.out corrupted */ pub const ELIBMAX: i32 = 82; /* Attempting to link in too many shared libraries */ pub const ELIBEXEC: i32 = 83; /* Cannot exec a shared library directly */ pub const EILSEQ: i32 = 84; /* Illegal byte sequence */ pub const ERESTART: i32 = 85; /* Interrupted system call should be restarted */ pub const ESTRPIPE: i32 = 86; /* Streams pipe error */ pub const EUSERS: i32 = 87; /* Too many users */ pub const ENOTSOCK: i32 = 88; /* Socket operation on non-socket */ pub const EDESTADDRREQ: i32 = 89; /* Destination address required */ pub const EMSGSIZE: i32 = 90; /* Message too long */ pub const EPROTOTYPE: i32 = 91; /* Protocol wrong type for socket */ pub const ENOPROTOOPT: i32 = 92; /* Protocol not available */ pub const EPROTONOSUPPORT: i32 = 93; /* Protocol not supported */ pub const ESOCKTNOSUPPORT: i32 = 94; /* Socket type not supported */ pub const EOPNOTSUPP: i32 = 95; /* Operation not supported on transport endpoint */ pub const EPFNOSUPPORT: i32 = 96; /* Protocol family not supported */ pub const EAFNOSUPPORT: i32 = 97; /* Address family not supported by protocol */ pub const EADDRINUSE: i32 = 98; /* Address already in use */ pub const EADDRNOTAVAIL: i32 = 99; /* Cannot assign requested address */ pub const ENETDOWN: i32 = 100; /* Network is down */ pub const ENETUNREACH: i32 = 101; /* Network is unreachable */ pub const ENETRESET: i32 = 102; /* Network dropped connection because of reset */ pub const ECONNABORTED: i32 = 103; /* Software caused connection abort */ pub const ECONNRESET: i32 = 104; /* Connection reset by peer */ pub const ENOBUFS: i32 = 105; /* No buffer space available */ pub const EISCONN: i32 = 106; /* Transport endpoint is already connected */ pub const ENOTCONN: i32 = 107; /* Transport endpoint is not connected */ pub const ESHUTDOWN: i32 = 108; /* Cannot send after transport endpoint shutdown */ pub const ETOOMANYREFS: i32 = 109; /* Too many references: cannot splice */ pub const ETIMEDOUT: i32 = 110; /* Connection timed out */ pub const ECONNREFUSED: i32 = 111; /* Connection refused */ pub const EHOSTDOWN: i32 = 112; /* Host is down */ pub const EHOSTUNREACH: i32 = 113; /* No route to host */ pub const EALREADY: i32 = 114; /* Operation already in progress */ pub const EINPROGRESS: i32 = 115; /* Operation now in progress */ pub const ESTALE: i32 = 116; /* Stale NFS file handle */ pub const EUCLEAN: i32 = 117; /* Structure needs cleaning */ pub const ENOTNAM: i32 = 118; /* Not a XENIX named type file */ pub const ENAVAIL: i32 = 119; /* No XENIX semaphores available */ pub const EISNAM: i32 = 120; /* Is a named type file */ pub const EREMOTEIO: i32 = 121; /* Remote I/O error */ pub const EDQUOT: i32 = 122; /* Quota exceeded */ pub const ENOMEDIUM: i32 = 123; /* No medium found */ pub const EMEDIUMTYPE: i32 = 124; /* Wrong medium type */ pub const ECANCELED: i32 = 125; /* Operation Canceled */ pub const ENOKEY: i32 = 126; /* Required key not available */ pub const EKEYEXPIRED: i32 = 127; /* Key has expired */ pub const EKEYREVOKED: i32 = 128; /* Key has been revoked */ pub const EKEYREJECTED: i32 = 129; /* Key was rejected by service */ pub const EOWNERDEAD: i32 = 130; /* Owner died */ pub const ENOTRECOVERABLE: i32 = 131; /* State not recoverable */ pub static STR_ERROR: [&'static str; 132] = ["Success", "Operation not permitted", "No such file or directory", "No such process", "Interrupted system call", "I/O error", "No such device or address", "Argument list too long", "Exec format error", "Bad file number", "No child processes", "Try again", "Out of memory", "Permission denied", "Bad address", "Block device required", "Device or resource busy", "File exists", "Cross-device link", "No such device", "Not a directory", "Is a directory", "Invalid argument", "File table overflow", "Too many open files", "Not a typewriter", "Text file busy", "File too large", "No space left on device", "Illegal seek", "Read-only file system", "Too many links", "Broken pipe", "Math argument out of domain of func", "Math result not representable", "Resource deadlock would occur", "File name too long", "No record locks available", "Function not implemented", "Directory not empty", "Too many symbolic links encountered", "Operation would block", "No message of desired type", "Identifier removed", "Channel number out of range", "Level 2 not synchronized", "Level 3 halted", "Level 3 reset", "Link number out of range", "Protocol driver not attached", "No CSI structure available", "Level 2 halted", "Invalid exchange", "Invalid request descriptor", "Exchange full", "No anode", "Invalid request code", "Invalid slot", "Resource deadlock would occur", "Bad font file format", "Device not a stream", "No data available", "Timer expired", "Out of streams resources", "Machine is not on the network", "Package not installed", "Object is remote", "Link has been severed", "Advertise error", "Srmount error", "Communication error on send", "Protocol error", "Multihop attempted", "RFS specific error", "Not a data message", "Value too large for defined data type", "Name not unique on network", "File descriptor in bad state", "Remote address changed", "Can not access a needed shared library", "Accessing a corrupted shared library", ".lib section in a.out corrupted", "Attempting to link in too many shared libraries", "Cannot exec a shared library directly", "Illegal byte sequence", "Interrupted system call should be restarted", "Streams pipe error", "Too many users", "Socket operation on non-socket", "Destination address required", "Message too long", "Protocol wrong type for socket", "Protocol not available", "Protocol not supported", "Socket type not supported", "Operation not supported on transport endpoint", "Protocol family not supported", "Address family not supported by protocol", "Address already in use", "Cannot assign requested address", "Network is down", "Network is unreachable", "Network dropped connection because of reset", "Software caused connection abort", "Connection reset by peer", "No buffer space available", "Transport endpoint is already connected", "Transport endpoint is not connected", "Cannot send after transport endpoint shutdown", "Too many references: cannot splice", "Connection timed out", "Connection refused", "Host is down", "No route to host", "Operation already in progress", "Operation now in progress", "Stale NFS file handle", "Structure needs cleaning", "Not a XENIX named type file", "No XENIX semaphores available", "Is a named type file", "Remote I/O error", "Quota exceeded", "No medium found", "Wrong medium type", "Operation Canceled", "Required key not available", "Key has expired", "Key has been revoked", "Key was rejected by service", "Owner died", "State not recoverable"]; redox_syscall-0.1.40/src/flag.rs010064400017500001750000000106051322401636400147410ustar0000000000000000pub const CLONE_VM: usize = 0x100; pub const CLONE_FS: usize = 0x200; pub const CLONE_FILES: usize = 0x400; pub const CLONE_SIGHAND: usize = 0x800; pub const CLONE_VFORK: usize = 0x4000; pub const CLONE_THREAD: usize = 0x10000; pub const CLOCK_REALTIME: usize = 1; pub const CLOCK_MONOTONIC: usize = 4; pub const EVENT_NONE: usize = 0; pub const EVENT_READ: usize = 1; pub const EVENT_WRITE: usize = 2; pub const F_DUPFD: usize = 0; pub const F_GETFD: usize = 1; pub const F_SETFD: usize = 2; pub const F_GETFL: usize = 3; pub const F_SETFL: usize = 4; pub const FUTEX_WAIT: usize = 0; pub const FUTEX_WAKE: usize = 1; pub const FUTEX_REQUEUE: usize = 2; pub const MAP_WRITE: usize = 1; pub const MAP_WRITE_COMBINE: usize = 2; pub const MODE_TYPE: u16 = 0xF000; pub const MODE_DIR: u16 = 0x4000; pub const MODE_FILE: u16 = 0x8000; pub const MODE_SYMLINK: u16 = 0xA000; pub const MODE_FIFO: u16 = 0x1000; pub const MODE_CHR: u16 = 0x2000; pub const MODE_PERM: u16 = 0x0FFF; pub const MODE_SETUID: u16 = 0o4000; pub const MODE_SETGID: u16 = 0o2000; pub const O_RDONLY: usize = 0x0001_0000; pub const O_WRONLY: usize = 0x0002_0000; pub const O_RDWR: usize = 0x0003_0000; pub const O_NONBLOCK: usize = 0x0004_0000; pub const O_APPEND: usize = 0x0008_0000; pub const O_SHLOCK: usize = 0x0010_0000; pub const O_EXLOCK: usize = 0x0020_0000; pub const O_ASYNC: usize = 0x0040_0000; pub const O_FSYNC: usize = 0x0080_0000; pub const O_CLOEXEC: usize = 0x0100_0000; pub const O_CREAT: usize = 0x0200_0000; pub const O_TRUNC: usize = 0x0400_0000; pub const O_EXCL: usize = 0x0800_0000; pub const O_DIRECTORY: usize = 0x1000_0000; pub const O_STAT: usize = 0x2000_0000; pub const O_SYMLINK: usize = 0x4000_0000; pub const O_NOFOLLOW: usize = 0x8000_0000; pub const O_ACCMODE: usize = O_RDONLY | O_WRONLY | O_RDWR; pub const SEEK_SET: usize = 0; pub const SEEK_CUR: usize = 1; pub const SEEK_END: usize = 2; pub const SIGHUP: usize = 1; pub const SIGINT: usize = 2; pub const SIGQUIT: usize = 3; pub const SIGILL: usize = 4; pub const SIGTRAP: usize = 5; pub const SIGABRT: usize = 6; pub const SIGBUS: usize = 7; pub const SIGFPE: usize = 8; pub const SIGKILL: usize = 9; pub const SIGUSR1: usize = 10; pub const SIGSEGV: usize = 11; pub const SIGUSR2: usize = 12; pub const SIGPIPE: usize = 13; pub const SIGALRM: usize = 14; pub const SIGTERM: usize = 15; pub const SIGSTKFLT: usize= 16; pub const SIGCHLD: usize = 17; pub const SIGCONT: usize = 18; pub const SIGSTOP: usize = 19; pub const SIGTSTP: usize = 20; pub const SIGTTIN: usize = 21; pub const SIGTTOU: usize = 22; pub const SIGURG: usize = 23; pub const SIGXCPU: usize = 24; pub const SIGXFSZ: usize = 25; pub const SIGVTALRM: usize= 26; pub const SIGPROF: usize = 27; pub const SIGWINCH: usize = 28; pub const SIGIO: usize = 29; pub const SIGPWR: usize = 30; pub const SIGSYS: usize = 31; pub const SIG_DFL: usize = 0; pub const SIG_IGN: usize = 1; pub const SA_NOCLDSTOP: usize = 0x00000001; pub const SA_NOCLDWAIT: usize = 0x00000002; pub const SA_SIGINFO: usize = 0x00000004; pub const SA_RESTORER: usize = 0x04000000; pub const SA_ONSTACK: usize = 0x08000000; pub const SA_RESTART: usize = 0x10000000; pub const SA_NODEFER: usize = 0x40000000; pub const SA_RESETHAND: usize = 0x80000000; pub const WNOHANG: usize = 0x01; pub const WUNTRACED: usize = 0x02; pub const WCONTINUED: usize = 0x08; /// True if status indicates the child is stopped. pub fn wifstopped(status: usize) -> bool { (status & 0xff) == 0x7f } /// If wifstopped(status), the signal that stopped the child. pub fn wstopsig(status: usize) -> usize { (status >> 8) & 0xff } /// True if status indicates the child continued after a stop. pub fn wifcontinued(status: usize) -> bool { status == 0xffff } /// True if STATUS indicates termination by a signal. pub fn wifsignaled(status: usize) -> bool { ((status & 0x7f) + 1) as i8 >= 2 } /// If wifsignaled(status), the terminating signal. pub fn wtermsig(status: usize) -> usize { status & 0x7f } /// True if status indicates normal termination. pub fn wifexited(status: usize) -> bool { wtermsig(status) == 0 } /// If wifexited(status), the exit status. pub fn wexitstatus(status: usize) -> usize { (status >> 8) & 0xff } /// True if status indicates a core dump was created. pub fn wcoredump(status: usize) -> bool { (status & 0x80) != 0 } redox_syscall-0.1.40/src/io/dma.rs010064400017500001750000000031631320022572600151770ustar0000000000000000use core::{mem, ptr}; use core::ops::{Deref, DerefMut}; use Result; struct PhysBox { address: usize, size: usize } impl PhysBox { fn new(size: usize) -> Result { let address = unsafe { ::physalloc(size)? }; Ok(PhysBox { address: address, size: size }) } } impl Drop for PhysBox { fn drop(&mut self) { let _ = unsafe { ::physfree(self.address, self.size) }; } } pub struct Dma { phys: PhysBox, virt: *mut T } impl Dma { pub fn new(value: T) -> Result> { let phys = PhysBox::new(mem::size_of::())?; let virt = unsafe { ::physmap(phys.address, phys.size, ::MAP_WRITE)? } as *mut T; unsafe { ptr::write(virt, value); } Ok(Dma { phys: phys, virt: virt }) } pub fn zeroed() -> Result> { let phys = PhysBox::new(mem::size_of::())?; let virt = unsafe { ::physmap(phys.address, phys.size, ::MAP_WRITE)? } as *mut T; unsafe { ptr::write_bytes(virt as *mut u8, 0, phys.size); } Ok(Dma { phys: phys, virt: virt }) } pub fn physical(&self) -> usize { self.phys.address } } impl Deref for Dma { type Target = T; fn deref(&self) -> &T { unsafe { &*self.virt } } } impl DerefMut for Dma { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.virt } } } impl Drop for Dma { fn drop(&mut self) { unsafe { drop(ptr::read(self.virt)); } let _ = unsafe { ::physunmap(self.virt as usize) }; } } redox_syscall-0.1.40/src/io/io.rs010064400017500001750000000027131320022572600150450ustar0000000000000000use core::cmp::PartialEq; use core::ops::{BitAnd, BitOr, Not}; pub trait Io { type Value: Copy + PartialEq + BitAnd + BitOr + Not; fn read(&self) -> Self::Value; fn write(&mut self, value: Self::Value); #[inline(always)] fn readf(&self, flags: Self::Value) -> bool { (self.read() & flags) as Self::Value == flags } #[inline(always)] fn writef(&mut self, flags: Self::Value, value: bool) { let tmp: Self::Value = match value { true => self.read() | flags, false => self.read() & !flags, }; self.write(tmp); } } pub struct ReadOnly { inner: I } impl ReadOnly { pub const fn new(inner: I) -> ReadOnly { ReadOnly { inner: inner } } #[inline(always)] pub fn read(&self) -> I::Value { self.inner.read() } #[inline(always)] pub fn readf(&self, flags: I::Value) -> bool { self.inner.readf(flags) } } pub struct WriteOnly { inner: I } impl WriteOnly { pub const fn new(inner: I) -> WriteOnly { WriteOnly { inner: inner } } #[inline(always)] pub fn write(&mut self, value: I::Value) { self.inner.write(value) } #[inline(always)] pub fn writef(&mut self, flags: I::Value, value: bool) { self.inner.writef(flags, value) } } redox_syscall-0.1.40/src/io/mmio.rs010064400017500001750000000012431330037273100153740ustar0000000000000000use core::ptr::{read_volatile, write_volatile}; use core::mem::uninitialized; use core::ops::{BitAnd, BitOr, Not}; use super::io::Io; #[repr(packed)] pub struct Mmio { value: T, } impl Mmio { /// Create a new Mmio without initializing pub fn new() -> Self { Mmio { value: unsafe { uninitialized() } } } } impl Io for Mmio where T: Copy + PartialEq + BitAnd + BitOr + Not { type Value = T; fn read(&self) -> T { unsafe { read_volatile(&self.value) } } fn write(&mut self, value: T) { unsafe { write_volatile(&mut self.value, value) }; } } redox_syscall-0.1.40/src/io/mod.rs010064400017500001750000000002201320022572600152040ustar0000000000000000//! I/O functions pub use self::dma::*; pub use self::io::*; pub use self::mmio::*; pub use self::pio::*; mod dma; mod io; mod mmio; mod pio; redox_syscall-0.1.40/src/io/pio.rs010064400017500001750000000035741320022572600152330ustar0000000000000000use core::marker::PhantomData; use super::io::Io; /// Generic PIO #[derive(Copy, Clone)] pub struct Pio { port: u16, value: PhantomData, } impl Pio { /// Create a PIO from a given port pub const fn new(port: u16) -> Self { Pio:: { port: port, value: PhantomData, } } } /// Read/Write for byte PIO impl Io for Pio { type Value = u8; /// Read #[inline(always)] fn read(&self) -> u8 { let value: u8; unsafe { asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); } value } /// Write #[inline(always)] fn write(&mut self, value: u8) { unsafe { asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); } } } /// Read/Write for word PIO impl Io for Pio { type Value = u16; /// Read #[inline(always)] fn read(&self) -> u16 { let value: u16; unsafe { asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); } value } /// Write #[inline(always)] fn write(&mut self, value: u16) { unsafe { asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); } } } /// Read/Write for doubleword PIO impl Io for Pio { type Value = u32; /// Read #[inline(always)] fn read(&self) -> u32 { let value: u32; unsafe { asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); } value } /// Write #[inline(always)] fn write(&mut self, value: u32) { unsafe { asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); } } } redox_syscall-0.1.40/src/lib.rs010064400017500001750000000016031330354260400145730ustar0000000000000000#![deny(warnings)] #![feature(asm)] #![feature(const_fn)] #![feature(transpose_result)] #![no_std] pub use self::arch::*; pub use self::call::*; pub use self::data::*; pub use self::error::*; pub use self::flag::*; pub use self::io::*; pub use self::number::*; pub use self::scheme::*; #[cfg(target_arch = "arm")] #[path="arch/arm.rs"] mod arch; #[cfg(target_arch = "x86")] #[path="arch/x86.rs"] mod arch; #[cfg(target_arch = "x86_64")] #[path="arch/x86_64.rs"] mod arch; /// Function definitions pub mod call; /// Complex structures that are used for some system calls pub mod data; /// All errors that can be generated by a system call pub mod error; /// Flags used as an argument to many system calls pub mod flag; /// Functions for low level hardware control pub mod io; /// Call numbers used by each system call pub mod number; /// A trait useful for scheme handlers pub mod scheme; redox_syscall-0.1.40/src/number.rs010064400017500001750000000061121322105654400153170ustar0000000000000000pub const SYS_CLASS: usize = 0xF000_0000; pub const SYS_CLASS_PATH: usize=0x1000_0000; pub const SYS_CLASS_FILE: usize=0x2000_0000; pub const SYS_ARG: usize = 0x0F00_0000; pub const SYS_ARG_SLICE: usize =0x0100_0000; pub const SYS_ARG_MSLICE: usize=0x0200_0000; pub const SYS_ARG_PATH: usize = 0x0300_0000; pub const SYS_RET: usize = 0x00F0_0000; pub const SYS_RET_FILE: usize = 0x0010_0000; pub const SYS_LINK: usize = SYS_CLASS_PATH | SYS_ARG_PATH | 9; pub const SYS_OPEN: usize = SYS_CLASS_PATH | SYS_RET_FILE | 5; pub const SYS_CHMOD: usize = SYS_CLASS_PATH | 15; pub const SYS_RMDIR: usize = SYS_CLASS_PATH | 84; pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10; pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6; pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41; pub const SYS_DUP2: usize = SYS_CLASS_FILE | SYS_RET_FILE | 63; pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3; pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4; pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19; pub const SYS_FCHMOD: usize = SYS_CLASS_FILE | 94; pub const SYS_FCHOWN: usize = SYS_CLASS_FILE | 207; pub const SYS_FCNTL: usize = SYS_CLASS_FILE | 55; pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927; pub const SYS_FMAP: usize = SYS_CLASS_FILE | 90; pub const SYS_FUNMAP: usize = SYS_CLASS_FILE | 91; pub const SYS_FPATH: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 928; pub const SYS_FRENAME: usize = SYS_CLASS_FILE | SYS_ARG_PATH | 38; pub const SYS_FSTAT: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 28; pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100; pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118; pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93; pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320; pub const SYS_BRK: usize = 45; pub const SYS_CHDIR: usize = 12; pub const SYS_CLOCK_GETTIME: usize = 265; pub const SYS_CLONE: usize = 120; pub const SYS_EXECVE: usize = 11; pub const SYS_EXIT: usize = 1; pub const SYS_FUTEX: usize = 240; pub const SYS_GETCWD: usize = 183; pub const SYS_GETEGID: usize = 202; pub const SYS_GETENS: usize = 951; pub const SYS_GETEUID: usize = 201; pub const SYS_GETGID: usize = 200; pub const SYS_GETNS: usize = 950; pub const SYS_GETPID: usize = 20; pub const SYS_GETPGID: usize = 132; pub const SYS_GETPPID: usize = 64; pub const SYS_GETUID: usize = 199; pub const SYS_IOPL: usize = 110; pub const SYS_KILL: usize = 37; pub const SYS_MKNS: usize = 984; pub const SYS_NANOSLEEP: usize =162; pub const SYS_PHYSALLOC: usize =945; pub const SYS_PHYSFREE: usize = 946; pub const SYS_PHYSMAP: usize = 947; pub const SYS_PHYSUNMAP: usize =948; pub const SYS_VIRTTOPHYS: usize=949; pub const SYS_PIPE2: usize = 331; pub const SYS_SETPGID: usize = 57; pub const SYS_SETREGID: usize = 204; pub const SYS_SETRENS: usize = 952; pub const SYS_SETREUID: usize = 203; pub const SYS_SIGACTION: usize =67; pub const SYS_SIGRETURN: usize =119; pub const SYS_WAITPID: usize = 7; pub const SYS_YIELD: usize = 158; redox_syscall-0.1.40/src/scheme/generate.sh010075500017500001750000000012501330354172500170550ustar0000000000000000#!/usr/bin/env bash set -e echo "Generating SchemeMut from Scheme" sed 's/trait Scheme/trait SchemeMut/' scheme.rs \ | sed 's/\&self/\&mut self/g' \ > scheme_mut.rs echo "Generating SchemeBlock from Scheme" sed 's/trait Scheme/trait SchemeBlock/' scheme.rs \ | sed 's/fn handle(\&self, packet: \&mut Packet)/fn handle(\&self, packet: \&Packet) -> Option/' \ | sed 's/packet.a = Error::mux(res);/res.transpose().map(Error::mux)/' \ | sed 's/Result/Result>/g' \ > scheme_block.rs echo "Generating SchemeBlockMut from SchemeBlock" sed 's/trait SchemeBlock/trait SchemeBlockMut/' scheme_block.rs \ | sed 's/\&self/\&mut self/g' \ > scheme_block_mut.rs redox_syscall-0.1.40/src/scheme/mod.rs010064400017500001750000000003411330353516200160470ustar0000000000000000pub use self::scheme::Scheme; pub use self::scheme_mut::SchemeMut; pub use self::scheme_block::SchemeBlock; pub use self::scheme_block_mut::SchemeBlockMut; mod scheme; mod scheme_mut; mod scheme_block; mod scheme_block_mut; redox_syscall-0.1.40/src/scheme/scheme.rs010064400017500001750000000130551330353726400165470ustar0000000000000000use core::{mem, slice}; use data::*; use error::*; use number::*; pub trait Scheme { fn handle(&self, packet: &mut Packet) { let res = match packet.a { SYS_OPEN => self.open(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d, packet.uid, packet.gid), SYS_CHMOD => self.chmod(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d as u16, packet.uid, packet.gid), SYS_RMDIR => self.rmdir(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_UNLINK => self.unlink(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_LSEEK => self.seek(packet.b, packet.c, packet.d), SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16), SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32), SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d), SYS_FEVENT => self.fevent(packet.b, packet.c), SYS_FMAP => self.fmap(packet.b, packet.c, packet.d), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) } else { Err(Error::new(EFAULT)) }, SYS_FSTATVFS => if packet.d >= mem::size_of::() { self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) } else { Err(Error::new(EFAULT)) }, SYS_FSYNC => self.fsync(packet.b), SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c), SYS_FUTIMENS => if packet.d >= mem::size_of::() { self.futimens(packet.b, unsafe { slice::from_raw_parts(packet.c as *const TimeSpec, packet.d / mem::size_of::()) }) } else { Err(Error::new(EFAULT)) }, SYS_CLOSE => self.close(packet.b), _ => Err(Error::new(ENOSYS)) }; packet.a = Error::mux(res); } /* Scheme operations */ #[allow(unused_variables)] fn open(&self, path: &[u8], flags: usize, uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn chmod(&self, path: &[u8], mode: u16, uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn rmdir(&self, path: &[u8], uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn unlink(&self, path: &[u8], uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } /* Resource operations */ #[allow(unused_variables)] fn dup(&self, old_id: usize, buf: &[u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn read(&self, id: usize, buf: &mut [u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn write(&self, id: usize, buf: &[u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchmod(&self, id: usize, mode: u16) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchown(&self, id: usize, uid: u32, gid: u32) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fevent(&self, id: usize, flags: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fmap(&self, id: usize, offset: usize, size: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fpath(&self, id: usize, buf: &mut [u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn frename(&self, id: usize, path: &[u8], uid: u32, gid: u32) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstat(&self, id: usize, stat: &mut Stat) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstatvfs(&self, id: usize, stat: &mut StatVfs) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fsync(&self, id: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn ftruncate(&self, id: usize, len: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn futimens(&self, id: usize, times: &[TimeSpec]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn close(&self, id: usize) -> Result { Err(Error::new(EBADF)) } } redox_syscall-0.1.40/src/scheme/scheme_block.rs010064400017500001750000000133531330354176400177220ustar0000000000000000use core::{mem, slice}; use data::*; use error::*; use number::*; pub trait SchemeBlock { fn handle(&self, packet: &Packet) -> Option { let res = match packet.a { SYS_OPEN => self.open(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d, packet.uid, packet.gid), SYS_CHMOD => self.chmod(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d as u16, packet.uid, packet.gid), SYS_RMDIR => self.rmdir(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_UNLINK => self.unlink(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_LSEEK => self.seek(packet.b, packet.c, packet.d), SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16), SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32), SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d), SYS_FEVENT => self.fevent(packet.b, packet.c), SYS_FMAP => self.fmap(packet.b, packet.c, packet.d), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) } else { Err(Error::new(EFAULT)) }, SYS_FSTATVFS => if packet.d >= mem::size_of::() { self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) } else { Err(Error::new(EFAULT)) }, SYS_FSYNC => self.fsync(packet.b), SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c), SYS_FUTIMENS => if packet.d >= mem::size_of::() { self.futimens(packet.b, unsafe { slice::from_raw_parts(packet.c as *const TimeSpec, packet.d / mem::size_of::()) }) } else { Err(Error::new(EFAULT)) }, SYS_CLOSE => self.close(packet.b), _ => Err(Error::new(ENOSYS)) }; res.transpose().map(Error::mux) } /* Scheme operations */ #[allow(unused_variables)] fn open(&self, path: &[u8], flags: usize, uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn chmod(&self, path: &[u8], mode: u16, uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn rmdir(&self, path: &[u8], uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn unlink(&self, path: &[u8], uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } /* Resource operations */ #[allow(unused_variables)] fn dup(&self, old_id: usize, buf: &[u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn read(&self, id: usize, buf: &mut [u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn write(&self, id: usize, buf: &[u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn seek(&self, id: usize, pos: usize, whence: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchmod(&self, id: usize, mode: u16) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchown(&self, id: usize, uid: u32, gid: u32) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fevent(&self, id: usize, flags: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fmap(&self, id: usize, offset: usize, size: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fpath(&self, id: usize, buf: &mut [u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn frename(&self, id: usize, path: &[u8], uid: u32, gid: u32) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstat(&self, id: usize, stat: &mut Stat) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstatvfs(&self, id: usize, stat: &mut StatVfs) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fsync(&self, id: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn ftruncate(&self, id: usize, len: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn futimens(&self, id: usize, times: &[TimeSpec]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn close(&self, id: usize) -> Result> { Err(Error::new(EBADF)) } } redox_syscall-0.1.40/src/scheme/scheme_block_mut.rs010064400017500001750000000135061330354176400206070ustar0000000000000000use core::{mem, slice}; use data::*; use error::*; use number::*; pub trait SchemeBlockMut { fn handle(&mut self, packet: &Packet) -> Option { let res = match packet.a { SYS_OPEN => self.open(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d, packet.uid, packet.gid), SYS_CHMOD => self.chmod(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d as u16, packet.uid, packet.gid), SYS_RMDIR => self.rmdir(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_UNLINK => self.unlink(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_LSEEK => self.seek(packet.b, packet.c, packet.d), SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16), SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32), SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d), SYS_FEVENT => self.fevent(packet.b, packet.c), SYS_FMAP => self.fmap(packet.b, packet.c, packet.d), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) } else { Err(Error::new(EFAULT)) }, SYS_FSTATVFS => if packet.d >= mem::size_of::() { self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) } else { Err(Error::new(EFAULT)) }, SYS_FSYNC => self.fsync(packet.b), SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c), SYS_FUTIMENS => if packet.d >= mem::size_of::() { self.futimens(packet.b, unsafe { slice::from_raw_parts(packet.c as *const TimeSpec, packet.d / mem::size_of::()) }) } else { Err(Error::new(EFAULT)) }, SYS_CLOSE => self.close(packet.b), _ => Err(Error::new(ENOSYS)) }; res.transpose().map(Error::mux) } /* Scheme operations */ #[allow(unused_variables)] fn open(&mut self, path: &[u8], flags: usize, uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn chmod(&mut self, path: &[u8], mode: u16, uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn rmdir(&mut self, path: &[u8], uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn unlink(&mut self, path: &[u8], uid: u32, gid: u32) -> Result> { Err(Error::new(ENOENT)) } /* Resource operations */ #[allow(unused_variables)] fn dup(&mut self, old_id: usize, buf: &[u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn write(&mut self, id: usize, buf: &[u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchmod(&mut self, id: usize, mode: u16) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchown(&mut self, id: usize, uid: u32, gid: u32) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fcntl(&mut self, id: usize, cmd: usize, arg: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fevent(&mut self, id: usize, flags: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fmap(&mut self, id: usize, offset: usize, size: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn frename(&mut self, id: usize, path: &[u8], uid: u32, gid: u32) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstatvfs(&mut self, id: usize, stat: &mut StatVfs) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fsync(&mut self, id: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn ftruncate(&mut self, id: usize, len: usize) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn futimens(&mut self, id: usize, times: &[TimeSpec]) -> Result> { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn close(&mut self, id: usize) -> Result> { Err(Error::new(EBADF)) } } redox_syscall-0.1.40/src/scheme/scheme_mut.rs010064400017500001750000000132101330354176400174250ustar0000000000000000use core::{mem, slice}; use data::*; use error::*; use number::*; pub trait SchemeMut { fn handle(&mut self, packet: &mut Packet) { let res = match packet.a { SYS_OPEN => self.open(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d, packet.uid, packet.gid), SYS_CHMOD => self.chmod(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d as u16, packet.uid, packet.gid), SYS_RMDIR => self.rmdir(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_UNLINK => self.unlink(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.uid, packet.gid), SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), SYS_LSEEK => self.seek(packet.b, packet.c, packet.d), SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16), SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32), SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d), SYS_FEVENT => self.fevent(packet.b, packet.c), SYS_FMAP => self.fmap(packet.b, packet.c, packet.d), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }) } else { Err(Error::new(EFAULT)) }, SYS_FSTATVFS => if packet.d >= mem::size_of::() { self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) }) } else { Err(Error::new(EFAULT)) }, SYS_FSYNC => self.fsync(packet.b), SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c), SYS_FUTIMENS => if packet.d >= mem::size_of::() { self.futimens(packet.b, unsafe { slice::from_raw_parts(packet.c as *const TimeSpec, packet.d / mem::size_of::()) }) } else { Err(Error::new(EFAULT)) }, SYS_CLOSE => self.close(packet.b), _ => Err(Error::new(ENOSYS)) }; packet.a = Error::mux(res); } /* Scheme operations */ #[allow(unused_variables)] fn open(&mut self, path: &[u8], flags: usize, uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn chmod(&mut self, path: &[u8], mode: u16, uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn rmdir(&mut self, path: &[u8], uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } #[allow(unused_variables)] fn unlink(&mut self, path: &[u8], uid: u32, gid: u32) -> Result { Err(Error::new(ENOENT)) } /* Resource operations */ #[allow(unused_variables)] fn dup(&mut self, old_id: usize, buf: &[u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn read(&mut self, id: usize, buf: &mut [u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn write(&mut self, id: usize, buf: &[u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchmod(&mut self, id: usize, mode: u16) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fchown(&mut self, id: usize, uid: u32, gid: u32) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fcntl(&mut self, id: usize, cmd: usize, arg: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fevent(&mut self, id: usize, flags: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fmap(&mut self, id: usize, offset: usize, size: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn frename(&mut self, id: usize, path: &[u8], uid: u32, gid: u32) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fstatvfs(&mut self, id: usize, stat: &mut StatVfs) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn fsync(&mut self, id: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn ftruncate(&mut self, id: usize, len: usize) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn futimens(&mut self, id: usize, times: &[TimeSpec]) -> Result { Err(Error::new(EBADF)) } #[allow(unused_variables)] fn close(&mut self, id: usize) -> Result { Err(Error::new(EBADF)) } }