1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use super::data
::{Stat, StatVfs, TimeSpec}
;
13 use super::error
::Result
;
18 /// Set the end of the process's heap
20 /// When `addr` is `0`, this function will return the current break.
22 /// When `addr` is nonzero, this function will attempt to set the end of the process's
23 /// heap to `addr` and return the new program break. The new program break should be
24 /// checked by the allocator, it may not be exactly `addr`, as it may be aligned to a page
27 /// On error, `Err(ENOMEM)` will be returned indicating that no memory is available
28 pub unsafe fn brk(addr
: usize) -> Result
<usize> {
29 syscall1(SYS_BRK
, addr
)
32 /// Change the process's working directory
34 /// This function will attempt to set the process's working directory to `path`, which can be
35 /// either a relative, scheme relative, or absolute path.
37 /// On success, `Ok(0)` will be returned. On error, one of the following errors will be returned.
41 /// * `EACCES` - permission is denied for one of the components of `path`, or `path`
42 /// * `EFAULT` - `path` does not point to the process's addressible memory
43 /// * `EIO` - an I/O error occurred
44 /// * `ENOENT` - `path` does not exit
45 /// * `ENOTDIR` - `path` is not a directory
46 pub fn chdir(path
: &str) -> Result
<usize> {
47 unsafe { syscall2(SYS_CHDIR, path.as_ptr() as usize, path.len()) }
50 pub fn chmod(path
: &str, mode
: usize) -> Result
<usize> {
51 unsafe { syscall3(SYS_CHMOD, path.as_ptr() as usize, path.len(), mode) }
54 /// Produce a fork of the current process, or a new process thread
55 pub unsafe fn clone(flags
: usize) -> Result
<usize> {
56 syscall1_clobber(SYS_CLONE
, flags
)
60 pub fn close(fd
: usize) -> Result
<usize> {
61 unsafe { syscall1(SYS_CLOSE, fd) }
64 /// Get the current system time
65 pub fn clock_gettime(clock
: usize, tp
: &mut TimeSpec
) -> Result
<usize> {
66 unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) }
69 /// Copy and transform a file descriptor
70 pub fn dup(fd
: usize, buf
: &[u8]) -> Result
<usize> {
71 unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) }
74 /// Copy and transform a file descriptor
75 pub fn dup2(fd
: usize, newfd
: usize, buf
: &[u8]) -> Result
<usize> {
76 unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) }
79 /// Replace the current process with a new executable
80 pub fn execve
<T
: AsRef
<[u8]>>(path
: T
, args
: &[[usize; 2]]) -> Result
<usize> {
81 unsafe { syscall4(SYS_EXECVE
, path
.as_ref().as_ptr() as usize,
82 path
.as_ref().len(), args
.as_ptr() as usize, args
.len()) }
85 /// Exit the current process
86 pub fn exit(status
: usize) -> Result
<usize> {
87 unsafe { syscall1(SYS_EXIT, status) }
90 /// Register a file for event-based I/O
91 pub fn fcntl(fd
: usize, cmd
: usize, arg
: usize) -> Result
<usize> {
92 unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
95 /// Register a file for event-based I/O
96 pub fn fevent(fd
: usize, flags
: usize) -> Result
<usize> {
97 unsafe { syscall2(SYS_FEVENT, fd, flags) }
100 /// Map a file into memory
101 pub unsafe fn fmap(fd
: usize, offset
: usize, size
: usize) -> Result
<usize> {
102 syscall3(SYS_FMAP
, fd
, offset
, size
)
105 /// Unmap a memory-mapped file
106 pub unsafe fn funmap(addr
: usize) -> Result
<usize> {
107 syscall1(SYS_FUNMAP
, addr
)
110 /// Retrieve the canonical path of a file
111 pub fn fpath(fd
: usize, buf
: &mut [u8]) -> Result
<usize> {
112 unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) }
115 /// Get metadata about a file
116 pub fn fstat(fd
: usize, stat
: &mut Stat
) -> Result
<usize> {
117 unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::<Stat>()) }
120 /// Get metadata about a filesystem
121 pub fn fstatvfs(fd
: usize, stat
: &mut StatVfs
) -> Result
<usize> {
122 unsafe { syscall3(SYS_FSTATVFS, fd, stat as *mut StatVfs as usize, mem::size_of::<StatVfs>()) }
125 /// Sync a file descriptor to its underlying medium
126 pub fn fsync(fd
: usize) -> Result
<usize> {
127 unsafe { syscall1(SYS_FSYNC, fd) }
130 /// Truncate or extend a file to a specified length
131 pub fn ftruncate(fd
: usize, len
: usize) -> Result
<usize> {
132 unsafe { syscall2(SYS_FTRUNCATE, fd, len) }
135 /// Fast userspace mutex
136 pub unsafe fn futex(addr
: *mut i32, op
: usize, val
: i32, val2
: usize, addr2
: *mut i32)
138 syscall5(SYS_FUTEX
, addr
as usize, op
, (val
as isize) as usize, val2
, addr2
as usize)
141 /// Get the current working directory
142 pub fn getcwd(buf
: &mut [u8]) -> Result
<usize> {
143 unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) }
146 /// Get the effective group ID
147 pub fn getegid() -> Result
<usize> {
148 unsafe { syscall0(SYS_GETEGID) }
151 /// Get the effective namespace
152 pub fn getens() -> Result
<usize> {
153 unsafe { syscall0(SYS_GETENS) }
156 /// Get the effective user ID
157 pub fn geteuid() -> Result
<usize> {
158 unsafe { syscall0(SYS_GETEUID) }
161 /// Get the current group ID
162 pub fn getgid() -> Result
<usize> {
163 unsafe { syscall0(SYS_GETGID) }
166 /// Get the current namespace
167 pub fn getns() -> Result
<usize> {
168 unsafe { syscall0(SYS_GETNS) }
171 /// Get the current process ID
172 pub fn getpid() -> Result
<usize> {
173 unsafe { syscall0(SYS_GETPID) }
176 /// Get the current user ID
177 pub fn getuid() -> Result
<usize> {
178 unsafe { syscall0(SYS_GETUID) }
181 /// Set the I/O privilege level
182 pub unsafe fn iopl(level
: usize) -> Result
<usize> {
183 syscall1(SYS_IOPL
, level
)
186 /// Send a signal `sig` to the process identified by `pid`
187 pub fn kill(pid
: usize, sig
: usize) -> Result
<usize> {
188 unsafe { syscall2(SYS_KILL, pid, sig) }
191 /// Create a link to a file
192 pub unsafe fn link(old
: *const u8, new
: *const u8) -> Result
<usize> {
193 syscall2(SYS_LINK
, old
as usize, new
as usize)
196 /// Seek to `offset` bytes in a file descriptor
197 pub fn lseek(fd
: usize, offset
: isize, whence
: usize) -> Result
<usize> {
198 unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) }
201 /// Make a new scheme namespace
202 pub fn mkns(schemes
: &[[usize; 2]]) -> Result
<usize> {
203 unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) }
206 /// Sleep for the time specified in `req`
207 pub fn nanosleep(req
: &TimeSpec
, rem
: &mut TimeSpec
) -> Result
<usize> {
208 unsafe { syscall2(SYS_NANOSLEEP
, req
as *const TimeSpec
as usize,
209 rem
as *mut TimeSpec
as usize) }
213 pub fn open(path
: &str, flags
: usize) -> Result
<usize> {
214 unsafe { syscall3(SYS_OPEN, path.as_ptr() as usize, path.len(), flags) }
217 /// Allocate pages, linearly in physical memory
218 pub unsafe fn physalloc(size
: usize) -> Result
<usize> {
219 syscall1(SYS_PHYSALLOC
, size
)
222 /// Free physically allocated pages
223 pub unsafe fn physfree(physical_address
: usize, size
: usize) -> Result
<usize> {
224 syscall2(SYS_PHYSFREE
, physical_address
, size
)
227 /// Map physical memory to virtual memory
228 pub unsafe fn physmap(physical_address
: usize, size
: usize, flags
: usize) -> Result
<usize> {
229 syscall3(SYS_PHYSMAP
, physical_address
, size
, flags
)
232 /// Unmap previously mapped physical memory
233 pub unsafe fn physunmap(virtual_address
: usize) -> Result
<usize> {
234 syscall1(SYS_PHYSUNMAP
, virtual_address
)
237 /// Create a pair of file descriptors referencing the read and write ends of a pipe
238 pub fn pipe2(fds
: &mut [usize; 2], flags
: usize) -> Result
<usize> {
239 unsafe { syscall2(SYS_PIPE2, fds.as_ptr() as usize, flags) }
242 /// Read from a file descriptor into a buffer
243 pub fn read(fd
: usize, buf
: &mut [u8]) -> Result
<usize> {
244 unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) }
247 /// Remove a directory
248 pub fn rmdir(path
: &str) -> Result
<usize> {
249 unsafe { syscall2(SYS_RMDIR, path.as_ptr() as usize, path.len()) }
252 /// Set the current process group IDs
253 pub fn setregid(rgid
: usize, egid
: usize) -> Result
<usize> {
254 unsafe { syscall2(SYS_SETREGID, rgid, egid) }
257 /// Make a new scheme namespace
258 pub fn setrens(rns
: usize, ens
: usize) -> Result
<usize> {
259 unsafe { syscall2(SYS_SETRENS, rns, ens) }
262 /// Set the current process user IDs
263 pub fn setreuid(ruid
: usize, euid
: usize) -> Result
<usize> {
264 unsafe { syscall2(SYS_SETREUID, ruid, euid) }
268 pub fn unlink(path
: &str) -> Result
<usize> {
269 unsafe { syscall2(SYS_UNLINK, path.as_ptr() as usize, path.len()) }
272 /// Convert a virtual address to a physical one
273 pub unsafe fn virttophys(virtual_address
: usize) -> Result
<usize> {
274 syscall1(SYS_VIRTTOPHYS
, virtual_address
)
277 /// Check if a child process has exited or received a signal
278 pub fn waitpid(pid
: usize, status
: &mut usize, options
: usize) -> Result
<usize> {
279 unsafe { syscall3(SYS_WAITPID, pid, status as *mut usize as usize, options) }
282 /// Write a buffer to a file descriptor
284 /// The kernel will attempt to write the bytes in `buf` to the file descriptor `fd`, returning
285 /// either an `Err`, explained below, or `Ok(count)` where `count` is the number of bytes which
290 /// * `EAGAIN` - the file descriptor was opened with `O_NONBLOCK` and writing would block
291 /// * `EBADF` - the file descriptor is not valid or is not open for writing
292 /// * `EFAULT` - `buf` does not point to the process's addressible memory
293 /// * `EIO` - an I/O error occurred
294 /// * `ENOSPC` - the device containing the file descriptor has no room for data
295 /// * `EPIPE` - the file descriptor refers to a pipe or socket whose reading end is closed
296 pub fn write(fd
: usize, buf
: &[u8]) -> Result
<usize> {
297 unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) }
300 /// Yield the process's time slice to the kernel
302 /// This function will return Ok(0) on success
303 pub fn sched_yield() -> Result
<usize> {
304 unsafe { syscall0(SYS_YIELD) }