2 use super::data
::{Map, SigAction, Stat, StatVfs, TimeSpec}
;
3 use super::error
::Result
;
10 extern "C" fn restorer() -> ! {
15 /// Change the process's working directory
17 /// This function will attempt to set the process's working directory to `path`, which can be
18 /// either a relative, scheme relative, or absolute path.
20 /// On success, `Ok(0)` will be returned. On error, one of the following errors will be returned.
24 /// * `EACCES` - permission is denied for one of the components of `path`, or `path`
25 /// * `EFAULT` - `path` does not point to the process's addressible memory
26 /// * `EIO` - an I/O error occurred
27 /// * `ENOENT` - `path` does not exit
28 /// * `ENOTDIR` - `path` is not a directory
29 pub fn chdir
<T
: AsRef
<str>>(path
: T
) -> Result
<usize> {
30 unsafe { syscall2(SYS_CHDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
35 note
= "use fchmod instead"
37 pub fn chmod
<T
: AsRef
<str>>(path
: T
, mode
: usize) -> Result
<usize> {
38 unsafe { syscall3(SYS_CHMOD, path.as_ref().as_ptr() as usize, path.as_ref().len(), mode) }
41 /// Produce a fork of the current process, or a new process thread
42 pub unsafe fn clone(flags
: CloneFlags
) -> Result
<usize> {
43 syscall1(SYS_CLONE
, flags
.bits())
47 pub fn close(fd
: usize) -> Result
<usize> {
48 unsafe { syscall1(SYS_CLOSE, fd) }
51 /// Get the current system time
52 pub fn clock_gettime(clock
: usize, tp
: &mut TimeSpec
) -> Result
<usize> {
53 unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) }
56 /// Copy and transform a file descriptor
57 pub fn dup(fd
: usize, buf
: &[u8]) -> Result
<usize> {
58 unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) }
61 /// Copy and transform a file descriptor
62 pub fn dup2(fd
: usize, newfd
: usize, buf
: &[u8]) -> Result
<usize> {
63 unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) }
66 /// Exit the current process
67 pub fn exit(status
: usize) -> Result
<usize> {
68 unsafe { syscall1(SYS_EXIT, status) }
71 /// Change file permissions
72 pub fn fchmod(fd
: usize, mode
: u16) -> Result
<usize> {
73 unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) }
77 /// Change file ownership
78 pub fn fchown(fd
: usize, uid
: u32, gid
: u32) -> Result
<usize> {
79 unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) }
83 /// Change file descriptor flags
84 pub fn fcntl(fd
: usize, cmd
: usize, arg
: usize) -> Result
<usize> {
85 unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
88 /// Replace the current process with a new executable
89 pub fn fexec(fd
: usize, args
: &[[usize; 2]], vars
: &[[usize; 2]]) -> Result
<usize> {
90 unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(), vars.as_ptr() as usize, vars.len()) }
93 /// Map a file into memory, but with the ability to set the address to map into, either as a hint
94 /// or as a requirement of the map.
97 /// `EACCES` - the file descriptor was not open for reading
98 /// `EBADF` - if the file descriptor was invalid
99 /// `ENODEV` - mmapping was not supported
100 /// `EINVAL` - invalid combination of flags
101 /// `EEXIST` - if [`MapFlags::MAP_FIXED`] was set, and the address specified was already in use.
103 pub unsafe fn fmap(fd
: usize, map
: &Map
) -> Result
<usize> {
104 syscall3(SYS_FMAP
, fd
, map
as *const Map
as usize, mem
::size_of
::<Map
>())
107 /// Unmap whole (or partial) continous memory-mapped files
108 pub unsafe fn funmap(addr
: usize, len
: usize) -> Result
<usize> {
109 syscall2(SYS_FUNMAP
, addr
, len
)
112 /// Retrieve the canonical path of a file
113 pub fn fpath(fd
: usize, buf
: &mut [u8]) -> Result
<usize> {
114 unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) }
118 pub fn frename
<T
: AsRef
<str>>(fd
: usize, path
: T
) -> Result
<usize> {
119 unsafe { syscall3(SYS_FRENAME, fd, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
122 /// Get metadata about a file
123 pub fn fstat(fd
: usize, stat
: &mut Stat
) -> Result
<usize> {
124 unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::<Stat>()) }
127 /// Get metadata about a filesystem
128 pub fn fstatvfs(fd
: usize, stat
: &mut StatVfs
) -> Result
<usize> {
129 unsafe { syscall3(SYS_FSTATVFS, fd, stat as *mut StatVfs as usize, mem::size_of::<StatVfs>()) }
132 /// Sync a file descriptor to its underlying medium
133 pub fn fsync(fd
: usize) -> Result
<usize> {
134 unsafe { syscall1(SYS_FSYNC, fd) }
137 /// Truncate or extend a file to a specified length
138 pub fn ftruncate(fd
: usize, len
: usize) -> Result
<usize> {
139 unsafe { syscall2(SYS_FTRUNCATE, fd, len) }
142 // Change modify and/or access times
143 pub fn futimens(fd
: usize, times
: &[TimeSpec
]) -> Result
<usize> {
144 unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize, times.len() * mem::size_of::<TimeSpec>()) }
147 /// Fast userspace mutex
148 pub unsafe fn futex(addr
: *mut i32, op
: usize, val
: i32, val2
: usize, addr2
: *mut i32)
150 syscall5(SYS_FUTEX
, addr
as usize, op
, (val
as isize) as usize, val2
, addr2
as usize)
153 /// Get the current working directory
154 pub fn getcwd(buf
: &mut [u8]) -> Result
<usize> {
155 unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) }
158 /// Get the effective group ID
159 pub fn getegid() -> Result
<usize> {
160 unsafe { syscall0(SYS_GETEGID) }
163 /// Get the effective namespace
164 pub fn getens() -> Result
<usize> {
165 unsafe { syscall0(SYS_GETENS) }
168 /// Get the effective user ID
169 pub fn geteuid() -> Result
<usize> {
170 unsafe { syscall0(SYS_GETEUID) }
173 /// Get the current group ID
174 pub fn getgid() -> Result
<usize> {
175 unsafe { syscall0(SYS_GETGID) }
178 /// Get the current namespace
179 pub fn getns() -> Result
<usize> {
180 unsafe { syscall0(SYS_GETNS) }
183 /// Get the current process ID
184 pub fn getpid() -> Result
<usize> {
185 unsafe { syscall0(SYS_GETPID) }
188 /// Get the process group ID
189 pub fn getpgid(pid
: usize) -> Result
<usize> {
190 unsafe { syscall1(SYS_GETPGID, pid) }
193 /// Get the parent process ID
194 pub fn getppid() -> Result
<usize> {
195 unsafe { syscall0(SYS_GETPPID) }
198 /// Get the current user ID
199 pub fn getuid() -> Result
<usize> {
200 unsafe { syscall0(SYS_GETUID) }
203 /// Set the I/O privilege level
207 /// * `EPERM` - `uid != 0`
208 /// * `EINVAL` - `level > 3`
209 pub unsafe fn iopl(level
: usize) -> Result
<usize> {
210 syscall1(SYS_IOPL
, level
)
213 /// Send a signal `sig` to the process identified by `pid`
214 pub fn kill(pid
: usize, sig
: usize) -> Result
<usize> {
215 unsafe { syscall2(SYS_KILL, pid, sig) }
218 /// Create a link to a file
219 pub unsafe fn link(old
: *const u8, new
: *const u8) -> Result
<usize> {
220 syscall2(SYS_LINK
, old
as usize, new
as usize)
223 /// Seek to `offset` bytes in a file descriptor
224 pub fn lseek(fd
: usize, offset
: isize, whence
: usize) -> Result
<usize> {
225 unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) }
228 /// Make a new scheme namespace
229 pub fn mkns(schemes
: &[[usize; 2]]) -> Result
<usize> {
230 unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) }
233 /// Change mapping flags
234 pub unsafe fn mprotect(addr
: usize, size
: usize, flags
: MapFlags
) -> Result
<usize> {
235 syscall3(SYS_MPROTECT
, addr
, size
, flags
.bits())
238 /// Sleep for the time specified in `req`
239 pub fn nanosleep(req
: &TimeSpec
, rem
: &mut TimeSpec
) -> Result
<usize> {
240 unsafe { syscall2(SYS_NANOSLEEP
, req
as *const TimeSpec
as usize,
241 rem
as *mut TimeSpec
as usize) }
245 pub fn open
<T
: AsRef
<str>>(path
: T
, flags
: usize) -> Result
<usize> {
246 unsafe { syscall3(SYS_OPEN, path.as_ref().as_ptr() as usize, path.as_ref().len(), flags) }
249 /// Allocate frames, linearly in physical memory.
253 /// * `EPERM` - `uid != 0`
254 /// * `ENOMEM` - the system has run out of available memory
255 pub unsafe fn physalloc(size
: usize) -> Result
<usize> {
256 syscall1(SYS_PHYSALLOC
, size
)
259 /// Allocate frames, linearly in physical memory, with an extra set of flags. If the flags contain
260 /// [`PARTIAL_ALLOC`], this will result in `physalloc3` with `min = 1`.
262 /// Refer to the simpler [`physalloc`] and the more complex [`physalloc3`], that this convenience
263 /// function is based on.
267 /// * `EPERM` - `uid != 0`
268 /// * `ENOMEM` - the system has run out of available memory
269 pub unsafe fn physalloc2(size
: usize, flags
: usize) -> Result
<usize> {
270 let mut ret
= 1usize
;
271 physalloc3(size
, flags
, &mut ret
)
274 /// Allocate frames, linearly in physical memory, with an extra set of flags. If the flags contain
275 /// [`PARTIAL_ALLOC`], the `min` parameter specifies the number of frames that have to be allocated
276 /// for this operation to succeed. The return value is the offset of the first frame, and `min` is
277 /// overwritten with the number of frames actually allocated.
279 /// Refer to the simpler [`physalloc`] and the simpler library function [`physalloc2`].
283 /// * `EPERM` - `uid != 0`
284 /// * `ENOMEM` - the system has run out of available memory
285 /// * `EINVAL` - `min = 0`
286 pub unsafe fn physalloc3(size
: usize, flags
: usize, min
: &mut usize) -> Result
<usize> {
287 syscall3(SYS_PHYSALLOC3
, size
, flags
, min
as *mut usize as usize)
290 /// Free physically allocated pages
294 /// * `EPERM` - `uid != 0`
295 pub unsafe fn physfree(physical_address
: usize, size
: usize) -> Result
<usize> {
296 syscall2(SYS_PHYSFREE
, physical_address
, size
)
299 /// Map physical memory to virtual memory
303 /// * `EPERM` - `uid != 0`
304 pub unsafe fn physmap(physical_address
: usize, size
: usize, flags
: PhysmapFlags
) -> Result
<usize> {
305 syscall3(SYS_PHYSMAP
, physical_address
, size
, flags
.bits())
308 /// Unmap previously mapped physical memory
312 /// * `EPERM` - `uid != 0`
313 /// * `EFAULT` - `virtual_address` has not been mapped
314 pub unsafe fn physunmap(virtual_address
: usize) -> Result
<usize> {
315 syscall1(SYS_PHYSUNMAP
, virtual_address
)
318 /// Create a pair of file descriptors referencing the read and write ends of a pipe
319 pub fn pipe2(fds
: &mut [usize; 2], flags
: usize) -> Result
<usize> {
320 unsafe { syscall2(SYS_PIPE2, fds.as_ptr() as usize, flags) }
323 /// Read from a file descriptor into a buffer
324 pub fn read(fd
: usize, buf
: &mut [u8]) -> Result
<usize> {
325 unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) }
328 /// Remove a directory
329 pub fn rmdir
<T
: AsRef
<str>>(path
: T
) -> Result
<usize> {
330 unsafe { syscall2(SYS_RMDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
333 /// Set the process group ID
334 pub fn setpgid(pid
: usize, pgid
: usize) -> Result
<usize> {
335 unsafe { syscall2(SYS_SETPGID, pid, pgid) }
338 /// Set the current process group IDs
339 pub fn setregid(rgid
: usize, egid
: usize) -> Result
<usize> {
340 unsafe { syscall2(SYS_SETREGID, rgid, egid) }
343 /// Make a new scheme namespace
344 pub fn setrens(rns
: usize, ens
: usize) -> Result
<usize> {
345 unsafe { syscall2(SYS_SETRENS, rns, ens) }
348 /// Set the current process user IDs
349 pub fn setreuid(ruid
: usize, euid
: usize) -> Result
<usize> {
350 unsafe { syscall2(SYS_SETREUID, ruid, euid) }
353 /// Set up a signal handler
354 pub fn sigaction(sig
: usize, act
: Option
<&SigAction
>, oldact
: Option
<&mut SigAction
>) -> Result
<usize> {
355 unsafe { syscall4(SYS_SIGACTION
, sig
,
356 act
.map(|x
| x
as *const _
).unwrap_or_else(ptr
::null
) as usize,
357 oldact
.map(|x
| x
as *mut _
).unwrap_or_else(ptr
::null_mut
) as usize,
361 /// Get and/or set signal masks
362 pub fn sigprocmask(how
: usize, set
: Option
<&[u64; 2]>, oldset
: Option
<&mut [u64; 2]>) -> Result
<usize> {
363 unsafe { syscall3(SYS_SIGPROCMASK
, how
,
364 set
.map(|x
| x
as *const _
).unwrap_or_else(ptr
::null
) as usize,
365 oldset
.map(|x
| x
as *mut _
).unwrap_or_else(ptr
::null_mut
) as usize) }
368 // Return from signal handler
369 pub fn sigreturn() -> Result
<usize> {
370 unsafe { syscall0(SYS_SIGRETURN) }
373 /// Set the file mode creation mask
374 pub fn umask(mask
: usize) -> Result
<usize> {
375 unsafe { syscall1(SYS_UMASK, mask) }
379 pub fn unlink
<T
: AsRef
<str>>(path
: T
) -> Result
<usize> {
380 unsafe { syscall2(SYS_UNLINK, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
383 /// Convert a virtual address to a physical one
387 /// * `EPERM` - `uid != 0`
388 pub unsafe fn virttophys(virtual_address
: usize) -> Result
<usize> {
389 syscall1(SYS_VIRTTOPHYS
, virtual_address
)
392 /// Check if a child process has exited or received a signal
393 pub fn waitpid(pid
: usize, status
: &mut usize, options
: WaitFlags
) -> Result
<usize> {
394 unsafe { syscall3(SYS_WAITPID, pid, status as *mut usize as usize, options.bits()) }
397 /// Write a buffer to a file descriptor
399 /// The kernel will attempt to write the bytes in `buf` to the file descriptor `fd`, returning
400 /// either an `Err`, explained below, or `Ok(count)` where `count` is the number of bytes which
405 /// * `EAGAIN` - the file descriptor was opened with `O_NONBLOCK` and writing would block
406 /// * `EBADF` - the file descriptor is not valid or is not open for writing
407 /// * `EFAULT` - `buf` does not point to the process's addressible memory
408 /// * `EIO` - an I/O error occurred
409 /// * `ENOSPC` - the device containing the file descriptor has no room for data
410 /// * `EPIPE` - the file descriptor refers to a pipe or socket whose reading end is closed
411 pub fn write(fd
: usize, buf
: &[u8]) -> Result
<usize> {
412 unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) }
415 /// Yield the process's time slice to the kernel
417 /// This function will return Ok(0) on success
418 pub fn sched_yield() -> Result
<usize> {
419 unsafe { syscall0(SYS_YIELD) }