diff options
Diffstat (limited to 'src/libstd/sys')
33 files changed, 240 insertions, 232 deletions
diff --git a/src/libstd/sys/cloudabi/abi/cloudabi.rs b/src/libstd/sys/cloudabi/abi/cloudabi.rs index 0bf8c2d5998..83d45b3547b 100644 --- a/src/libstd/sys/cloudabi/abi/cloudabi.rs +++ b/src/libstd/sys/cloudabi/abi/cloudabi.rs @@ -673,11 +673,11 @@ bitflags! { /// Methods of synchronizing memory with physical storage. #[repr(C)] pub struct msflags: u8 { - /// Perform asynchronous writes. + /// Performs asynchronous writes. const ASYNC = 0x01; - /// Invalidate cached data. + /// Invalidates cached data. const INVALIDATE = 0x02; - /// Perform synchronous writes. + /// Performs synchronous writes. const SYNC = 0x04; } } @@ -1750,11 +1750,9 @@ fn tcb_layout_test_64() { /// Entry point for additionally created threads. /// -/// **tid**: -/// Thread ID of the current thread. +/// `tid`: thread ID of the current thread. /// -/// **aux**: -/// Copy of the value stored in +/// `aux`: copy of the value stored in /// [`threadattr.argument`](struct.threadattr.html#structfield.argument). pub type threadentry = unsafe extern "C" fn( tid: tid, @@ -2590,7 +2588,7 @@ pub unsafe fn mem_map(addr_: *mut (), len_: usize, prot_: mprot, flags_: mflags, cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_) } -/// Change the protection of a memory mapping. +/// Changes the protection of a memory mapping. /// /// ## Parameters /// @@ -2604,7 +2602,7 @@ pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno { cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_) } -/// Synchronize a region of memory with its physical storage. +/// Synchronizes a region of memory with its physical storage. /// /// ## Parameters /// diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 99ef74179c2..0a56f4fad6d 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -1,4 +1,4 @@ -//! Platform-dependent platform abstraction +//! Platform-dependent platform abstraction. //! //! The `std::sys` module is the abstracted interface through which //! `std` talks to the underlying operating system. It has different diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs index 04edfd6851d..8b81273f201 100644 --- a/src/libstd/sys/redox/ext/fs.rs +++ b/src/libstd/sys/redox/ext/fs.rs @@ -117,7 +117,7 @@ pub trait OpenOptionsExt { #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&mut self, mode: u32) -> &mut Self; - /// Pass custom flags to the `flags` argument of `open`. + /// Passes custom flags to the `flags` argument of `open`. /// /// The bits that define the access mode are masked out with `O_ACCMODE`, to /// ensure they do not interfere with the access mode set by Rusts options. @@ -287,9 +287,9 @@ impl FileTypeExt for fs::FileType { /// # Note /// /// On Windows, you must specify whether a symbolic link points to a file -/// or directory. Use `os::windows::fs::symlink_file` to create a +/// or directory. Use `os::windows::fs::symlink_file` to create a /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a -/// symbolic link to a directory. Additionally, the process must have +/// symbolic link to a directory. Additionally, the process must have /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a /// symbolic link. /// diff --git a/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs index 76c68829b7f..7411b8e068f 100644 --- a/src/libstd/sys/redox/ext/net.rs +++ b/src/libstd/sys/redox/ext/net.rs @@ -60,7 +60,7 @@ impl SocketAddr { None } - /// Returns true if and only if the address is unnamed. + /// Returns `true` if the address is unnamed. /// /// # Examples /// @@ -374,7 +374,7 @@ impl UnixStream { /// ``` /// /// # Platform specific - /// On Redox this always returns None. + /// On Redox this always returns `None`. #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn take_error(&self) -> io::Result<Option<io::Error>> { Ok(None) @@ -635,7 +635,7 @@ impl UnixListener { /// ``` /// /// # Platform specific - /// On Redox this always returns None. + /// On Redox this always returns `None`. #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn take_error(&self) -> io::Result<Option<io::Error>> { Ok(None) diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs index 941fba8755b..1dcc1169510 100644 --- a/src/libstd/sys/redox/ext/process.rs +++ b/src/libstd/sys/redox/ext/process.rs @@ -13,13 +13,13 @@ use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; /// [`process::Command`]: ../../../../std/process/struct.Command.html #[stable(feature = "rust1", since = "1.0.0")] pub trait CommandExt { - /// Sets the child process's user id. This translates to a + /// Sets the child process's user ID. This translates to a /// `setuid` call in the child process. Failure in the `setuid` /// call will cause the spawn to fail. #[stable(feature = "rust1", since = "1.0.0")] fn uid(&mut self, id: u32) -> &mut process::Command; - /// Similar to `uid`, but sets the group id of the child process. This has + /// Similar to `uid`, but sets the group ID of the child process. This has /// the same semantics as the `uid` field. #[stable(feature = "rust1", since = "1.0.0")] fn gid(&mut self, id: u32) -> &mut process::Command; diff --git a/src/libstd/sys/redox/mutex.rs b/src/libstd/sys/redox/mutex.rs index 42424da858f..bf39cc48591 100644 --- a/src/libstd/sys/redox/mutex.rs +++ b/src/libstd/sys/redox/mutex.rs @@ -50,7 +50,7 @@ pub struct Mutex { } impl Mutex { - /// Create a new mutex. + /// Creates a new mutex. pub const fn new() -> Self { Mutex { lock: UnsafeCell::new(0), diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 4199ab98cf1..9e23c537f22 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -561,7 +561,7 @@ impl ExitCode { } } -/// The unique id of the process (this should never be negative). +/// The unique ID of the process (this should never be negative). pub struct Process { pid: usize, status: Option<ExitStatus>, diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs index b9e2b476cec..b9abb48a8d3 100644 --- a/src/libstd/sys/redox/syscall/call.rs +++ b/src/libstd/sys/redox/syscall/call.rs @@ -25,7 +25,7 @@ pub unsafe fn brk(addr: usize) -> Result<usize> { syscall1(SYS_BRK, addr) } -/// Change the process's working directory +/// Changes 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. @@ -47,90 +47,90 @@ pub fn chmod<T: AsRef<[u8]>>(path: T, mode: usize) -> Result<usize> { 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 +/// Produces a fork of the current process, or a new process thread. pub unsafe fn clone(flags: usize) -> Result<usize> { syscall1_clobber(SYS_CLONE, flags) } -/// Close a file +/// Closes a file. pub fn close(fd: usize) -> Result<usize> { unsafe { syscall1(SYS_CLOSE, fd) } } -/// Get the current system time +/// Gets the current system time. pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result<usize> { unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) } } -/// Copy and transform a file descriptor +/// Copies and transforms a file descriptor. pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> { unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) } } -/// Copy and transform a file descriptor +/// Copies and transforms a file descriptor. pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result<usize> { unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) } } -/// Exit the current process +/// Exits the current process. pub fn exit(status: usize) -> Result<usize> { unsafe { syscall1(SYS_EXIT, status) } } -/// Change file permissions +/// Changes file permissions. pub fn fchmod(fd: usize, mode: u16) -> Result<usize> { unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) } } -/// Change file ownership +/// Changes file ownership. pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result<usize> { unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) } } -/// Change file descriptor flags +/// Changes file descriptor flags. pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result<usize> { unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) } } -/// Replace the current process with a new executable +/// Replaces the current process with a new executable. pub fn fexec(fd: usize, args: &[[usize; 2]], vars: &[[usize; 2]]) -> Result<usize> { unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(), vars.as_ptr() as usize, vars.len()) } } -/// Map a file into memory +/// Maps a file into memory. pub unsafe fn fmap(fd: usize, offset: usize, size: usize) -> Result<usize> { syscall3(SYS_FMAP, fd, offset, size) } -/// Unmap a memory-mapped file +/// Unmaps a memory-mapped file. pub unsafe fn funmap(addr: usize) -> Result<usize> { syscall1(SYS_FUNMAP, addr) } -/// Retrieve the canonical path of a file +/// Retrieves the canonical path of a file. pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> { unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) } } -/// Rename a file +/// Renames a file. pub fn frename<T: AsRef<[u8]>>(fd: usize, path: T) -> Result<usize> { unsafe { syscall3(SYS_FRENAME, fd, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } -/// Get metadata about a file +/// Gets metadata about a file. pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> { unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::<Stat>()) } } -/// Get metadata about a filesystem +/// Gets metadata about a filesystem. pub fn fstatvfs(fd: usize, stat: &mut StatVfs) -> Result<usize> { unsafe { syscall3(SYS_FSTATVFS, fd, stat as *mut StatVfs as usize, mem::size_of::<StatVfs>()) } } -/// Sync a file descriptor to its underlying medium +/// Syncs a file descriptor to its underlying medium. pub fn fsync(fd: usize) -> Result<usize> { unsafe { syscall1(SYS_FSYNC, fd) } } @@ -152,113 +152,113 @@ pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mu syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize) } -/// Get the current working directory +/// Gets the current working directory. pub fn getcwd(buf: &mut [u8]) -> Result<usize> { unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) } } -/// Get the effective group ID +/// Gets the effective group ID. pub fn getegid() -> Result<usize> { unsafe { syscall0(SYS_GETEGID) } } -/// Get the effective namespace +/// Gets the effective namespace. pub fn getens() -> Result<usize> { unsafe { syscall0(SYS_GETENS) } } -/// Get the effective user ID +/// Gets the effective user ID. pub fn geteuid() -> Result<usize> { unsafe { syscall0(SYS_GETEUID) } } -/// Get the current group ID +/// Gets the current group ID. pub fn getgid() -> Result<usize> { unsafe { syscall0(SYS_GETGID) } } -/// Get the current namespace +/// Gets the current namespace. pub fn getns() -> Result<usize> { unsafe { syscall0(SYS_GETNS) } } -/// Get the current process ID +/// Gets the current process ID. pub fn getpid() -> Result<usize> { unsafe { syscall0(SYS_GETPID) } } -/// Get the process group ID +/// Gets the process group ID. pub fn getpgid(pid: usize) -> Result<usize> { unsafe { syscall1(SYS_GETPGID, pid) } } -/// Get the parent process ID +/// Gets the parent process ID. pub fn getppid() -> Result<usize> { unsafe { syscall0(SYS_GETPPID) } } -/// Get the current user ID +/// Gets the current user ID. pub fn getuid() -> Result<usize> { unsafe { syscall0(SYS_GETUID) } } -/// Set the I/O privilege level +/// Sets the I/O privilege level pub unsafe fn iopl(level: usize) -> Result<usize> { syscall1(SYS_IOPL, level) } -/// Send a signal `sig` to the process identified by `pid` +/// Sends a signal `sig` to the process identified by `pid`. pub fn kill(pid: usize, sig: usize) -> Result<usize> { unsafe { syscall2(SYS_KILL, pid, sig) } } -/// Create a link to a file +/// Creates a link to a file. pub unsafe fn link(old: *const u8, new: *const u8) -> Result<usize> { syscall2(SYS_LINK, old as usize, new as usize) } -/// Seek to `offset` bytes in a file descriptor +/// Seeks to `offset` bytes in a file descriptor. pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result<usize> { unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) } } -/// Make a new scheme namespace +/// Makes a new scheme namespace. pub fn mkns(schemes: &[[usize; 2]]) -> Result<usize> { unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) } } -/// Sleep for the time specified in `req` +/// Sleeps for the time specified in `req`. pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result<usize> { unsafe { syscall2(SYS_NANOSLEEP, req as *const TimeSpec as usize, rem as *mut TimeSpec as usize) } } -/// Open a file +/// Opens a file. pub fn open<T: AsRef<[u8]>>(path: T, flags: usize) -> Result<usize> { unsafe { syscall3(SYS_OPEN, path.as_ref().as_ptr() as usize, path.as_ref().len(), flags) } } -/// Allocate pages, linearly in physical memory +/// Allocates pages, linearly in physical memory. pub unsafe fn physalloc(size: usize) -> Result<usize> { syscall1(SYS_PHYSALLOC, size) } -/// Free physically allocated pages +/// Frees physically allocated pages. pub unsafe fn physfree(physical_address: usize, size: usize) -> Result<usize> { syscall2(SYS_PHYSFREE, physical_address, size) } -/// Map physical memory to virtual memory +/// Maps physical memory to virtual memory. pub unsafe fn physmap(physical_address: usize, size: usize, flags: usize) -> Result<usize> { syscall3(SYS_PHYSMAP, physical_address, size, flags) } -/// Unmap previously mapped physical memory +/// Unmaps previously mapped physical memory. pub unsafe fn physunmap(virtual_address: usize) -> Result<usize> { syscall1(SYS_PHYSUNMAP, virtual_address) } -/// Create a pair of file descriptors referencing the read and write ends of a pipe +/// Creates a pair of file descriptors referencing the read and write ends of a pipe. pub fn pipe2(fds: &mut [usize; 2], flags: usize) -> Result<usize> { unsafe { syscall2(SYS_PIPE2, fds.as_ptr() as usize, flags) } } @@ -268,32 +268,32 @@ pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> { unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) } } -/// Remove a directory +/// Removes a directory. pub fn rmdir<T: AsRef<[u8]>>(path: T) -> Result<usize> { unsafe { syscall2(SYS_RMDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } -/// Set the process group ID +/// Sets the process group ID. pub fn setpgid(pid: usize, pgid: usize) -> Result<usize> { unsafe { syscall2(SYS_SETPGID, pid, pgid) } } -/// Set the current process group IDs +/// Sets the current process group IDs. pub fn setregid(rgid: usize, egid: usize) -> Result<usize> { unsafe { syscall2(SYS_SETREGID, rgid, egid) } } -/// Make a new scheme namespace +/// Makes a new scheme namespace. pub fn setrens(rns: usize, ens: usize) -> Result<usize> { unsafe { syscall2(SYS_SETRENS, rns, ens) } } -/// Set the current process user IDs +/// Sets the current process user IDs. pub fn setreuid(ruid: usize, euid: usize) -> Result<usize> { unsafe { syscall2(SYS_SETREUID, ruid, euid) } } -/// Set up a signal handler +/// Sets up a signal handler. pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>) -> Result<usize> { unsafe { syscall4(SYS_SIGACTION, sig, @@ -302,27 +302,27 @@ pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAct restorer as usize) } } -// Return from signal handler +/// Returns from signal handler. pub fn sigreturn() -> Result<usize> { unsafe { syscall0(SYS_SIGRETURN) } } -/// Remove a file +/// Removes a file. pub fn unlink<T: AsRef<[u8]>>(path: T) -> Result<usize> { unsafe { syscall2(SYS_UNLINK, path.as_ref().as_ptr() as usize, path.as_ref().len()) } } -/// Convert a virtual address to a physical one +/// Converts a virtual address to a physical one. pub unsafe fn virttophys(virtual_address: usize) -> Result<usize> { syscall1(SYS_VIRTTOPHYS, virtual_address) } -/// Check if a child process has exited or received a signal +/// Checks if a child process has exited or received a signal. pub fn waitpid(pid: usize, status: &mut usize, options: usize) -> Result<usize> { unsafe { syscall3(SYS_WAITPID, pid, status as *mut usize as usize, options) } } -/// Write a buffer to a file descriptor +/// Writes 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 @@ -340,7 +340,7 @@ pub fn write(fd: usize, buf: &[u8]) -> Result<usize> { unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) } } -/// Yield the process's time slice to the kernel +/// Yields the process's time slice to the kernel. /// /// This function will return Ok(0) on success pub fn sched_yield() -> Result<usize> { diff --git a/src/libstd/sys/redox/syscall/flag.rs b/src/libstd/sys/redox/syscall/flag.rs index a41bc6d4a8b..5820f1ad03a 100644 --- a/src/libstd/sys/redox/syscall/flag.rs +++ b/src/libstd/sys/redox/syscall/flag.rs @@ -107,42 +107,42 @@ pub const WNOHANG: usize = 0x01; pub const WUNTRACED: usize = 0x02; pub const WCONTINUED: usize = 0x08; -/// True if status indicates the child is stopped. +/// Returns `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. +/// If wifstopped(status), returns 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. +/// Returns `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. +/// Returns `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. +/// If wifsignaled(status), returns the terminating signal. pub fn wtermsig(status: usize) -> usize { status & 0x7f } -/// True if status indicates normal termination. +/// Returns `true` if status indicates normal termination. pub fn wifexited(status: usize) -> bool { wtermsig(status) == 0 } -/// If wifexited(status), the exit status. +/// If wifexited(status), returns the exit status. pub fn wexitstatus(status: usize) -> usize { (status >> 8) & 0xff } -/// True if status indicates a core dump was created. +/// Returns `true` if status indicates a core dump was created. pub fn wcoredump(status: usize) -> bool { (status & 0x80) != 0 } diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index 9b46c2180d9..c03e3869aa3 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -69,10 +69,6 @@ IMAGE_BASE: .asciz "Re-entered aborted enclave!" .Lreentry_panic_msg_end: -.Lusercall_panic_msg: - .asciz "Invalid usercall#!" -.Lusercall_panic_msg_end: - .org .Lxsave_clear+512 .Lxsave_header: .int 0, 0 /* XSTATE_BV */ @@ -219,13 +215,21 @@ sgx_entry: orq $8,%rsp jmp panic_msg -.Lusercall_panic: - lea .Lusercall_panic_msg(%rip),%rdi - mov $.Lusercall_panic_msg_end-.Lusercall_panic_msg,%esi - orq $8,%rsp - jmp panic_msg - -.macro push_callee_saved_registers +/* This *MUST* be called with 6 parameters, otherwise register information */ +/* might leak! */ +.global usercall +usercall: + test %rcx,%rcx /* check `abort` function argument */ + jnz .Lusercall_abort /* abort is set, jump to abort code (unlikely forward conditional) */ + jmp .Lusercall_save_state /* non-aborting usercall */ +.Lusercall_abort: +/* set aborted bit */ + movb $1,.Laborted(%rip) +/* save registers in DEBUG mode, so that debugger can reconstruct the stack */ + testb $0xff,DEBUG(%rip) + jz .Lusercall_noreturn +.Lusercall_save_state: +/* save callee-saved state */ push %r15 push %r14 push %r13 @@ -235,33 +239,8 @@ sgx_entry: sub $8, %rsp fstcw 4(%rsp) stmxcsr (%rsp) -.endm - -.global usercall_exit -usercall_exit: -/* save registers in DEBUG mode, so that debugger can reconstruct the stack */ - testb $0xff,DEBUG(%rip) - jz .Lskip_save_registers - push_callee_saved_registers - movq %rsp,%gs:tcsls_panic_last_rsp -.Lskip_save_registers: -/* set aborted bit */ - movb $1,.Laborted(%rip) -/* call usercall exit(true) */ - /* NOP: mov %rsi,%rsi */ /* RSI = usercall() argument: panic */ - xor %rdx,%rdx /* RDX cleared */ - movq $usercall_nr_exit,%rdi /* RDI = usercall exit */ - jmp .Lexit - -/* This *MUST* be called with 6 parameters, otherwise register information */ -/* might leak! */ -.global usercall -usercall: - test %rdi,%rdi - jle .Lusercall_panic -/* save callee-saved state */ - push_callee_saved_registers movq %rsp,%gs:tcsls_last_rsp +.Lusercall_noreturn: /* clear general purpose register state */ /* RAX overwritten by ENCLU */ /* RBX set by sgx_exit */ @@ -281,7 +260,7 @@ usercall: jmp .Lsgx_exit .Lusercall_ret: movq $0,%gs:tcsls_last_rsp -/* restore callee-saved state, cf. push_callee_saved_registers */ +/* restore callee-saved state, cf. "save" above */ mov %r11,%rsp ldmxcsr (%rsp) fldcw 4(%rsp) diff --git a/src/libstd/sys/sgx/abi/mod.rs b/src/libstd/sys/sgx/abi/mod.rs index 5ef069aa81c..509a1990d97 100644 --- a/src/libstd/sys/sgx/abi/mod.rs +++ b/src/libstd/sys/sgx/abi/mod.rs @@ -12,7 +12,7 @@ pub mod tls; #[macro_use] pub mod usercalls; -global_asm!(concat!(usercalls_asm!(), include_str!("entry.S"))); +global_asm!(include_str!("entry.S")); #[no_mangle] unsafe extern "C" fn tcs_init(secondary: bool) { diff --git a/src/libstd/sys/sgx/abi/panic.rs b/src/libstd/sys/sgx/abi/panic.rs index d23fa9a9ec6..b2afacc70b8 100644 --- a/src/libstd/sys/sgx/abi/panic.rs +++ b/src/libstd/sys/sgx/abi/panic.rs @@ -1,4 +1,4 @@ -use super::usercalls::alloc::UserRef; +use super::usercalls::{alloc::UserRef, self}; use cmp; use io::{self, Write}; use mem; @@ -52,7 +52,5 @@ impl Write for SgxPanicOutput { #[no_mangle] pub extern "C" fn panic_msg(msg: &str) -> ! { let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes())); - unsafe { usercall_exit(true); } + usercalls::exit(true) } - -extern "C" { pub fn usercall_exit(panic: bool) -> !; } diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs index 588fbcd9d43..86fe09d0035 100644 --- a/src/libstd/sys/sgx/abi/thread.rs +++ b/src/libstd/sys/sgx/abi/thread.rs @@ -1,6 +1,6 @@ use fortanix_sgx_abi::Tcs; -/// Get the ID for the current thread. The ID is guaranteed to be unique among +/// Gets the ID for the current thread. The ID is guaranteed to be unique among /// all currently running threads in the enclave, and it is guaranteed to be /// constant for the lifetime of the thread. More specifically for SGX, there /// is a one-to-one correspondence of the ID to the address of the TCS. diff --git a/src/libstd/sys/sgx/abi/tls.rs b/src/libstd/sys/sgx/abi/tls.rs index b8e09d58deb..e1fc3696845 100644 --- a/src/libstd/sys/sgx/abi/tls.rs +++ b/src/libstd/sys/sgx/abi/tls.rs @@ -182,7 +182,7 @@ mod sync_bitset { self.0[hi].fetch_and(!lo, Ordering::Relaxed); } - /// Set any unset bit. Not atomic. Returns `None` if all bits were + /// Sets any unset bit. Not atomic. Returns `None` if all bits were /// observed to be set. pub fn set(&self) -> Option<usize> { 'elems: for (idx, elem) in self.0.iter().enumerate() { diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs index 8d0013a235a..0ccbbbc6501 100644 --- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs +++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs @@ -63,44 +63,49 @@ pub unsafe trait UserSafe { /// Construct a pointer to `Self` given a memory range in user space. /// - /// NB. This takes a size, not a length! + /// N.B., this takes a size, not a length! /// /// # Safety + /// /// The caller must ensure the memory range is in user memory, is the /// correct size and is correctly aligned and points to the right type. unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self; /// Construct a pointer to `Self` given a memory range. /// - /// NB. This takes a size, not a length! + /// N.B., this takes a size, not a length! /// /// # Safety + /// /// The caller must ensure the memory range points to the correct type. /// /// # Panics + /// /// This function panics if: /// - /// * The pointer is not aligned - /// * The pointer is null - /// * The pointed-to range is not in user memory + /// * the pointer is not aligned. + /// * the pointer is null. + /// * the pointed-to range is not in user memory. unsafe fn from_raw_sized(ptr: *mut u8, size: usize) -> NonNull<Self> { let ret = Self::from_raw_sized_unchecked(ptr, size); Self::check_ptr(ret); NonNull::new_unchecked(ret as _) } - /// Check if a pointer may point to Self in user memory. + /// Checks if a pointer may point to `Self` in user memory. /// /// # Safety + /// /// The caller must ensure the memory range points to the correct type and /// length (if this is a slice). /// /// # Panics + /// /// This function panics if: /// - /// * The pointer is not aligned - /// * The pointer is null - /// * The pointed-to range is not in user memory + /// * the pointer is not aligned. + /// * the pointer is null. + /// * the pointed-to range is not in user memory. unsafe fn check_ptr(ptr: *const Self) { let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) @@ -188,7 +193,7 @@ impl<T: ?Sized> User<T> where T: UserSafe { } } - /// Copy `val` into freshly allocated space in user memory. + /// Copies `val` into freshly allocated space in user memory. pub fn new_from_enclave(val: &T) -> Self { unsafe { let ret = Self::new_uninit_bytes(mem::size_of_val(val)); @@ -201,7 +206,7 @@ impl<T: ?Sized> User<T> where T: UserSafe { } } - /// Create an owned `User<T>` from a raw pointer. + /// Creates an owned `User<T>` from a raw pointer. /// /// # Safety /// The caller must ensure `ptr` points to `T`, is freeable with the `free` @@ -218,7 +223,7 @@ impl<T: ?Sized> User<T> where T: UserSafe { User(NonNull::new_userref(ptr)) } - /// Convert this value into a raw pointer. The value will no longer be + /// Converts this value into a raw pointer. The value will no longer be /// automatically freed. pub fn into_raw(self) -> *mut T { let ret = self.0; @@ -242,7 +247,7 @@ impl<T> User<[T]> where [T]: UserSafe { Self::new_uninit_bytes(n * mem::size_of::<T>()) } - /// Create an owned `User<[T]>` from a raw thin pointer and a slice length. + /// Creates an owned `User<[T]>` from a raw thin pointer and a slice length. /// /// # Safety /// The caller must ensure `ptr` points to `len` elements of `T`, is @@ -262,7 +267,7 @@ impl<T> User<[T]> where [T]: UserSafe { #[unstable(feature = "sgx_platform", issue = "56975")] impl<T: ?Sized> UserRef<T> where T: UserSafe { - /// Create a `&UserRef<[T]>` from a raw pointer. + /// Creates a `&UserRef<[T]>` from a raw pointer. /// /// # Safety /// The caller must ensure `ptr` points to `T`. @@ -278,7 +283,7 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { &*(ptr as *const Self) } - /// Create a `&mut UserRef<[T]>` from a raw pointer. See the struct + /// Creates a `&mut UserRef<[T]>` from a raw pointer. See the struct /// documentation for the nuances regarding a `&mut UserRef<T>`. /// /// # Safety @@ -295,7 +300,7 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { &mut*(ptr as *mut Self) } - /// Copy `val` into user memory. + /// Copies `val` into user memory. /// /// # Panics /// This function panics if the destination doesn't have the same size as @@ -311,7 +316,7 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { } } - /// Copy the value from user memory and place it into `dest`. + /// Copies the value from user memory and place it into `dest`. /// /// # Panics /// This function panics if the destination doesn't have the same size as @@ -340,7 +345,7 @@ impl<T: ?Sized> UserRef<T> where T: UserSafe { #[unstable(feature = "sgx_platform", issue = "56975")] impl<T> UserRef<T> where T: UserSafe { - /// Copy the value from user memory into enclave memory. + /// Copies the value from user memory into enclave memory. pub fn to_enclave(&self) -> T { unsafe { ptr::read(self.0.get()) } } @@ -348,7 +353,7 @@ impl<T> UserRef<T> where T: UserSafe { #[unstable(feature = "sgx_platform", issue = "56975")] impl<T> UserRef<[T]> where [T]: UserSafe { - /// Create a `&UserRef<[T]>` from a raw thin pointer and a slice length. + /// Creates a `&UserRef<[T]>` from a raw thin pointer and a slice length. /// /// # Safety /// The caller must ensure `ptr` points to `n` elements of `T`. @@ -363,7 +368,7 @@ impl<T> UserRef<[T]> where [T]: UserSafe { &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self) } - /// Create a `&mut UserRef<[T]>` from a raw thin pointer and a slice length. + /// Creates a `&mut UserRef<[T]>` from a raw thin pointer and a slice length. /// See the struct documentation for the nuances regarding a /// `&mut UserRef<T>`. /// @@ -395,7 +400,7 @@ impl<T> UserRef<[T]> where [T]: UserSafe { unsafe { (*self.0.get()).len() } } - /// Copy the value from user memory and place it into `dest`. Afterwards, + /// Copies the value from user memory and place it into `dest`. Afterwards, /// `dest` will contain exactly `self.len()` elements. /// /// # Panics @@ -411,7 +416,7 @@ impl<T> UserRef<[T]> where [T]: UserSafe { } } - /// Copy the value from user memory into a vector in enclave memory. + /// Copies the value from user memory into a vector in enclave memory. pub fn to_enclave(&self) -> Vec<T> { let mut ret = Vec::with_capacity(self.len()); self.copy_to_enclave_vec(&mut ret); @@ -526,7 +531,7 @@ impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I: #[unstable(feature = "sgx_platform", issue = "56975")] impl UserRef<super::raw::ByteBuffer> { - /// Copy the user memory range pointed to by the user `ByteBuffer` to + /// Copies the user memory range pointed to by the user `ByteBuffer` to /// enclave memory. /// /// # Panics @@ -537,7 +542,12 @@ impl UserRef<super::raw::ByteBuffer> { pub fn copy_user_buffer(&self) -> Vec<u8> { unsafe { let buf = self.to_enclave(); - User::from_raw_parts(buf.data as _, buf.len).to_enclave() + if buf.len > 0 { + User::from_raw_parts(buf.data as _, buf.len).to_enclave() + } else { + // Mustn't look at `data` or call `free` if `len` is `0`. + Vec::with_capacity(0) + } } } } diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index 4e889c172ef..511d6e9e927 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -22,7 +22,8 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> { #[unstable(feature = "sgx_platform", issue = "56975")] pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> { unsafe { - let mut userbuf = alloc::User::<ByteBuffer>::uninitialized(); + let userbuf = ByteBuffer { data: ::ptr::null_mut(), len: 0 }; + let mut userbuf = alloc::User::new_from_enclave(&userbuf); raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?; Ok(userbuf.copy_user_buffer()) } @@ -119,7 +120,7 @@ pub unsafe fn launch_thread() -> IoResult<()> { /// Usercall `exit`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn exit(panic: bool) -> ! { - unsafe { super::panic::usercall_exit(panic) } + unsafe { raw::exit(panic) } } /// Usercall `wait`. See the ABI documentation for more information. diff --git a/src/libstd/sys/sgx/abi/usercalls/raw.rs b/src/libstd/sys/sgx/abi/usercalls/raw.rs index 27f780ca224..447f20584f8 100644 --- a/src/libstd/sys/sgx/abi/usercalls/raw.rs +++ b/src/libstd/sys/sgx/abi/usercalls/raw.rs @@ -4,26 +4,31 @@ pub use fortanix_sgx_abi::*; use ptr::NonNull; +use num::NonZeroU64; #[repr(C)] struct UsercallReturn(u64, u64); extern "C" { - fn usercall(nr: u64, p1: u64, p2: u64, _ignore: u64, p3: u64, p4: u64) -> UsercallReturn; + fn usercall(nr: NonZeroU64, p1: u64, p2: u64, abort: u64, p3: u64, p4: u64) -> UsercallReturn; } -/// Perform the raw usercall operation as defined in the ABI calling convention. +/// Performs the raw usercall operation as defined in the ABI calling convention. /// /// # Safety +/// /// The caller must ensure to pass parameters appropriate for the usercall `nr` /// and to observe all requirements specified in the ABI. /// /// # Panics -/// Panics if `nr` is 0. +/// +/// Panics if `nr` is `0`. #[unstable(feature = "sgx_platform", issue = "56975")] -pub unsafe fn do_usercall(nr: u64, p1: u64, p2: u64, p3: u64, p4: u64) -> (u64, u64) { - if nr==0 { panic!("Invalid usercall number {}",nr) } - let UsercallReturn(a, b) = usercall(nr,p1,p2,0,p3,p4); +#[inline] +pub unsafe fn do_usercall(nr: NonZeroU64, p1: u64, p2: u64, p3: u64, p4: u64, abort: bool) + -> (u64, u64) +{ + let UsercallReturn(a, b) = usercall(nr, p1, p2, abort as _, p3, p4); (a, b) } @@ -39,7 +44,6 @@ trait ReturnValue { } macro_rules! define_usercalls { - // Using `$r:tt` because `$r:ty` doesn't match ! in `clobber_diverging` ($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:tt)*; )*) => { /// Usercall numbers as per the ABI. #[repr(u64)] @@ -57,22 +61,6 @@ macro_rules! define_usercalls { }; } -macro_rules! define_usercalls_asm { - ($(fn $f:ident($($n:ident: $t:ty),*) $(-> $r:ty)*; )*) => { - macro_rules! usercalls_asm { - () => { - concat!( - ".equ usercall_nr_LAST, 0\n", - $( - ".equ usercall_nr_", stringify!($f), ", usercall_nr_LAST+1\n", - ".equ usercall_nr_LAST, usercall_nr_", stringify!($f), "\n" - ),* - ) - } - } - }; -} - macro_rules! define_ra { (< $i:ident > $t:ty) => { impl<$i> RegisterArgument for $t { @@ -171,74 +159,90 @@ impl<T: RegisterArgument, U: RegisterArgument> ReturnValue for (T, U) { } } +macro_rules! return_type_is_abort { + (!) => { true }; + ($r:ty) => { false }; +} + +// In this macro: using `$r:tt` because `$r:ty` doesn't match ! in `return_type_is_abort` macro_rules! enclave_usercalls_internal_define_usercalls { (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, - $n3:ident: $t3:ty, $n4:ident: $t4:ty) -> $r:ty) => ( + $n3:ident: $t3:ty, $n4:ident: $t4:ty) -> $r:tt) => ( /// This is the raw function definition, see the ABI documentation for /// more information. #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( - Usercalls::$f as Register, + NonZeroU64::new(Usercalls::$f as Register) + .expect("Usercall number must be non-zero"), RegisterArgument::into_register($n1), RegisterArgument::into_register($n2), RegisterArgument::into_register($n3), RegisterArgument::into_register($n4), + return_type_is_abort!($r) )) } ); - (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty) -> $r:ty) => ( + (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty) -> $r:tt) => ( /// This is the raw function definition, see the ABI documentation for /// more information. #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( - Usercalls::$f as Register, + NonZeroU64::new(Usercalls::$f as Register) + .expect("Usercall number must be non-zero"), RegisterArgument::into_register($n1), RegisterArgument::into_register($n2), RegisterArgument::into_register($n3), - 0 + 0, + return_type_is_abort!($r) )) } ); - (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty) -> $r:ty) => ( + (def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty) -> $r:tt) => ( /// This is the raw function definition, see the ABI documentation for /// more information. #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( - Usercalls::$f as Register, + NonZeroU64::new(Usercalls::$f as Register) + .expect("Usercall number must be non-zero"), RegisterArgument::into_register($n1), RegisterArgument::into_register($n2), - 0,0 + 0,0, + return_type_is_abort!($r) )) } ); - (def fn $f:ident($n1:ident: $t1:ty) -> $r:ty) => ( + (def fn $f:ident($n1:ident: $t1:ty) -> $r:tt) => ( /// This is the raw function definition, see the ABI documentation for /// more information. #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1) -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( - Usercalls::$f as Register, + NonZeroU64::new(Usercalls::$f as Register) + .expect("Usercall number must be non-zero"), RegisterArgument::into_register($n1), - 0,0,0 + 0,0,0, + return_type_is_abort!($r) )) } ); - (def fn $f:ident() -> $r:ty) => ( + (def fn $f:ident() -> $r:tt) => ( /// This is the raw function definition, see the ABI documentation for /// more information. #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f() -> $r { ReturnValue::from_registers(stringify!($f), do_usercall( - Usercalls::$f as Register, - 0,0,0,0 + NonZeroU64::new(Usercalls::$f as Register) + .expect("Usercall number must be non-zero"), + 0,0,0,0, + return_type_is_abort!($r) )) } ); @@ -248,4 +252,3 @@ macro_rules! enclave_usercalls_internal_define_usercalls { } invoke_with_usercalls!(define_usercalls); -invoke_with_usercalls!(define_usercalls_asm); diff --git a/src/libstd/sys/sgx/ext/arch.rs b/src/libstd/sys/sgx/ext/arch.rs index 3bd87b5d265..97f7d9181a5 100644 --- a/src/libstd/sys/sgx/ext/arch.rs +++ b/src/libstd/sys/sgx/ext/arch.rs @@ -41,7 +41,7 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32> ); match error { - 0 => Ok(out.into_inner()), + 0 => Ok(out.into_initialized()), err => Err(err), } } @@ -69,6 +69,6 @@ pub fn ereport( "{rdx}"(report.as_mut_ptr()) ); - report.into_inner() + report.into_initialized() } } diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index f2593c35bed..4225ecbb206 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -125,7 +125,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize { } pub unsafe fn abort_internal() -> ! { - abi::panic::usercall_exit(true) + abi::usercalls::exit(true) } pub fn hashmap_random_keys() -> (u64, u64) { diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 43ceae7d33b..33163a556c1 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -19,9 +19,6 @@ unsafe fn rw_lock_size_assert(r: RWLock) { mem::transmute::<RWLock, [u8; 128]>(r); } -//unsafe impl Send for RWLock {} -//unsafe impl Sync for RWLock {} // FIXME - impl RWLock { pub const fn new() -> RWLock { RWLock { diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs index 51c00a1433e..aec643b3175 100644 --- a/src/libstd/sys/sgx/waitqueue.rs +++ b/src/libstd/sys/sgx/waitqueue.rs @@ -3,7 +3,7 @@ /// This queue is used to implement condition variable and mutexes. /// /// Users of this API are expected to use the `WaitVariable<T>` type. Since -/// that type is not `Sync`, it needs to be protected by e.g. a `SpinMutex` to +/// that type is not `Sync`, it needs to be protected by e.g., a `SpinMutex` to /// allow shared access. /// /// Since userspace may send spurious wake-ups, the wakeup event state is @@ -136,7 +136,7 @@ impl WaitQueue { self.inner.is_empty() } - /// Add the calling thread to the WaitVariable's wait queue, then wait + /// Adds the calling thread to the `WaitVariable`'s wait queue, then wait /// until a wakeup event. /// /// This function does not return until this thread has been awoken. diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index e962d09e274..abcce3ab829 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -684,7 +684,7 @@ impl MetadataExt for fs::Metadata { /// [`FileType`]: ../../../../std/fs/struct.FileType.html #[stable(feature = "file_type_ext", since = "1.5.0")] pub trait FileTypeExt { - /// Returns whether this file type is a block device. + /// Returns `true` if this file type is a block device. /// /// # Examples /// @@ -702,7 +702,7 @@ pub trait FileTypeExt { /// ``` #[stable(feature = "file_type_ext", since = "1.5.0")] fn is_block_device(&self) -> bool; - /// Returns whether this file type is a char device. + /// Returns `true` if this file type is a char device. /// /// # Examples /// @@ -720,7 +720,7 @@ pub trait FileTypeExt { /// ``` #[stable(feature = "file_type_ext", since = "1.5.0")] fn is_char_device(&self) -> bool; - /// Returns whether this file type is a fifo. + /// Returns `true` if this file type is a fifo. /// /// # Examples /// @@ -738,7 +738,7 @@ pub trait FileTypeExt { /// ``` #[stable(feature = "file_type_ext", since = "1.5.0")] fn is_fifo(&self) -> bool; - /// Returns whether this file type is a socket. + /// Returns `true` if this file type is a socket. /// /// # Examples /// @@ -805,9 +805,9 @@ impl DirEntryExt for fs::DirEntry { /// # Note /// /// On Windows, you must specify whether a symbolic link points to a file -/// or directory. Use `os::windows::fs::symlink_file` to create a +/// or directory. Use `os::windows::fs::symlink_file` to create a /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a -/// symbolic link to a directory. Additionally, the process must have +/// symbolic link to a directory. Additionally, the process must have /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a /// symbolic link. /// diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs index 36e9370b713..ccbac1a3e4b 100644 --- a/src/libstd/sys/unix/ext/mod.rs +++ b/src/libstd/sys/unix/ext/mod.rs @@ -1,4 +1,4 @@ -//! Experimental extensions to `std` for Unix platforms. +//! Platform-specific extensions to `std` for Unix platforms. //! //! Provides access to platform-level information on Unix platforms, and //! exposes Unix-specific functions that would otherwise be inappropriate as diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index a3ae5943f60..acc064acfcd 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -134,7 +134,7 @@ impl SocketAddr { }) } - /// Returns true if and only if the address is unnamed. + /// Returns `true` if the address is unnamed. /// /// # Examples /// @@ -516,7 +516,7 @@ impl UnixStream { /// ``` /// /// # Platform specific - /// On Redox this always returns None. + /// On Redox this always returns `None`. #[stable(feature = "unix_socket", since = "1.10.0")] pub fn take_error(&self) -> io::Result<Option<io::Error>> { self.0.take_error() @@ -841,7 +841,7 @@ impl UnixListener { /// ``` /// /// # Platform specific - /// On Redox this always returns None. + /// On Redox this always returns `None`. #[stable(feature = "unix_socket", since = "1.10.0")] pub fn take_error(&self) -> io::Result<Option<io::Error>> { self.0.take_error() @@ -1047,7 +1047,7 @@ impl UnixDatagram { Ok(UnixDatagram(inner)) } - /// Create an unnamed pair of connected sockets. + /// Creates an unnamed pair of connected sockets. /// /// Returns two `UnixDatagrams`s which are connected to each other. /// diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 0282aaae909..2c5943fdac3 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -13,13 +13,13 @@ use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; /// [`process::Command`]: ../../../../std/process/struct.Command.html #[stable(feature = "rust1", since = "1.0.0")] pub trait CommandExt { - /// Sets the child process's user id. This translates to a + /// Sets the child process's user ID. This translates to a /// `setuid` call in the child process. Failure in the `setuid` /// call will cause the spawn to fail. #[stable(feature = "rust1", since = "1.0.0")] fn uid(&mut self, id: u32) -> &mut process::Command; - /// Similar to `uid`, but sets the group id of the child process. This has + /// Similar to `uid`, but sets the group ID of the child process. This has /// the same semantics as the `uid` field. #[stable(feature = "rust1", since = "1.0.0")] fn gid(&mut self, id: u32) -> &mut process::Command; diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index f0f8032b4b5..6fbbbb349b1 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -281,8 +281,7 @@ impl Command { use mem; use sys; - if self.get_cwd().is_some() || - self.get_gid().is_some() || + if self.get_gid().is_some() || self.get_uid().is_some() || self.env_saw_path() || self.get_closures().len() != 0 { @@ -301,6 +300,24 @@ impl Command { } } + // Solaris and glibc 2.29+ can set a new working directory, and maybe + // others will gain this non-POSIX function too. We'll check for this + // weak symbol as soon as it's needed, so we can return early otherwise + // to do a manual chdir before exec. + weak! { + fn posix_spawn_file_actions_addchdir_np( + *mut libc::posix_spawn_file_actions_t, + *const libc::c_char + ) -> libc::c_int + } + let addchdir = match self.get_cwd() { + Some(cwd) => match posix_spawn_file_actions_addchdir_np.get() { + Some(f) => Some((f, cwd)), + None => return Ok(None), + }, + None => None, + }; + let mut p = Process { pid: 0, status: None }; struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t); @@ -345,6 +362,9 @@ impl Command { fd, libc::STDERR_FILENO))?; } + if let Some((f, cwd)) = addchdir { + cvt(f(&mut file_actions.0, cwd.as_ptr()))?; + } let mut set: libc::sigset_t = mem::uninitialized(); cvt(libc::sigemptyset(&mut set))?; @@ -383,7 +403,7 @@ impl Command { // Processes //////////////////////////////////////////////////////////////////////////////// -/// The unique id of the process (this should never be negative). +/// The unique ID of the process (this should never be negative). pub struct Process { pid: pid_t, status: Option<ExitStatus>, diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs index 8a6b7b5f876..715f2eafb2d 100644 --- a/src/libstd/sys/unix/stdio.rs +++ b/src/libstd/sys/unix/stdio.rs @@ -12,7 +12,7 @@ impl Stdin { pub fn read(&self, data: &mut [u8]) -> io::Result<usize> { let fd = FileDesc::new(libc::STDIN_FILENO); let ret = fd.read(data); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } } @@ -23,7 +23,7 @@ impl Stdout { pub fn write(&self, data: &[u8]) -> io::Result<usize> { let fd = FileDesc::new(libc::STDOUT_FILENO); let ret = fd.write(data); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } @@ -38,7 +38,7 @@ impl Stderr { pub fn write(&self, data: &[u8]) -> io::Result<usize> { let fd = FileDesc::new(libc::STDERR_FILENO); let ret = fd.write(data); - fd.into_raw(); + fd.into_raw(); // do not close this FD ret } diff --git a/src/libstd/sys/windows/ext/ffi.rs b/src/libstd/sys/windows/ext/ffi.rs index eb278919307..6508c0cf447 100644 --- a/src/libstd/sys/windows/ext/ffi.rs +++ b/src/libstd/sys/windows/ext/ffi.rs @@ -3,19 +3,19 @@ //! # Overview //! //! For historical reasons, the Windows API uses a form of potentially -//! ill-formed UTF-16 encoding for strings. Specifically, the 16-bit +//! ill-formed UTF-16 encoding for strings. Specifically, the 16-bit //! code units in Windows strings may contain [isolated surrogate code -//! points which are not paired together][ill-formed-utf-16]. The +//! points which are not paired together][ill-formed-utf-16]. The //! Unicode standard requires that surrogate code points (those in the //! range U+D800 to U+DFFF) always be *paired*, because in the UTF-16 //! encoding a *surrogate code unit pair* is used to encode a single -//! character. For compatibility with code that does not enforce +//! character. For compatibility with code that does not enforce //! these pairings, Windows does not enforce them, either. //! //! While it is not always possible to convert such a string losslessly into //! a valid UTF-16 string (or even UTF-8), it is often desirable to be //! able to round-trip such a string from and to Windows APIs -//! losslessly. For example, some Rust code may be "bridging" some +//! losslessly. For example, some Rust code may be "bridging" some //! Windows APIs together, just passing `WCHAR` strings among those //! APIs without ever really looking into the strings. //! @@ -28,16 +28,16 @@ //! # `OsStringExt` and `OsStrExt` //! //! [`OsString`] is the Rust wrapper for owned strings in the -//! preferred representation of the operating system. On Windows, +//! preferred representation of the operating system. On Windows, //! this struct gets augmented with an implementation of the -//! [`OsStringExt`] trait, which has a [`from_wide`] method. This +//! [`OsStringExt`] trait, which has a [`from_wide`] method. This //! lets you create an [`OsString`] from a `&[u16]` slice; presumably //! you get such a slice out of a `WCHAR` Windows API. //! //! Similarly, [`OsStr`] is the Rust wrapper for borrowed strings from -//! preferred representation of the operating system. On Windows, the +//! preferred representation of the operating system. On Windows, the //! [`OsStrExt`] trait provides the [`encode_wide`] method, which -//! outputs an [`EncodeWide`] iterator. You can [`collect`] this +//! outputs an [`EncodeWide`] iterator. You can [`collect`] this //! iterator, for example, to obtain a `Vec<u16>`; you can later get a //! pointer to this vector's contents and feed it to Windows APIs. //! diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 6342af46daf..89038da6295 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -441,10 +441,10 @@ impl MetadataExt for Metadata { /// [`FileType`]: ../../../../std/fs/struct.FileType.html #[unstable(feature = "windows_file_type_ext", issue = "0")] pub trait FileTypeExt { - /// Returns whether this file type is a symbolic link that is also a directory. + /// Returns `true` if this file type is a symbolic link that is also a directory. #[unstable(feature = "windows_file_type_ext", issue = "0")] fn is_symlink_dir(&self) -> bool; - /// Returns whether this file type is a symbolic link that is also a file. + /// Returns `true` if this file type is a symbolic link that is also a file. #[unstable(feature = "windows_file_type_ext", issue = "0")] fn is_symlink_file(&self) -> bool; } diff --git a/src/libstd/sys/windows/ext/io.rs b/src/libstd/sys/windows/ext/io.rs index 76143dee464..fbe0426ce5a 100644 --- a/src/libstd/sys/windows/ext/io.rs +++ b/src/libstd/sys/windows/ext/io.rs @@ -16,7 +16,7 @@ pub type RawHandle = raw::HANDLE; #[stable(feature = "rust1", since = "1.0.0")] pub type RawSocket = raw::SOCKET; -/// Extract raw handles. +/// Extracts raw handles. #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRawHandle { /// Extracts the raw handle, without taking any ownership. @@ -98,7 +98,7 @@ impl IntoRawHandle for fs::File { } } -/// Extract raw sockets. +/// Extracts raw sockets. #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRawSocket { /// Extracts the underlying raw socket from this object. @@ -106,7 +106,7 @@ pub trait AsRawSocket { fn as_raw_socket(&self) -> RawSocket; } -/// Create I/O objects from raw sockets. +/// Creates I/O objects from raw sockets. #[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawSocket { /// Creates a new I/O object from the given raw socket. diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 5f478827b43..7399dd41a41 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -1,4 +1,4 @@ -//! Implementation of `std::os` functionality for Windows +//! Implementation of `std::os` functionality for Windows. #![allow(nonstandard_style)] diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 0d9195a5c97..d3b102268f6 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -282,7 +282,7 @@ impl<'a> AsyncPipe<'a> { /// Takes a parameter `wait` which indicates if this pipe is currently being /// read whether the function should block waiting for the read to complete. /// - /// Return values: + /// Returns values: /// /// * `true` - finished any pending read and the pipe is not at EOF (keep /// going) diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs index a4f4bd22cd9..0ea19a85525 100644 --- a/src/libstd/sys/windows/stdio.rs +++ b/src/libstd/sys/windows/stdio.rs @@ -188,7 +188,9 @@ impl Output { } fn invalid_encoding() -> io::Error { - io::Error::new(io::ErrorKind::InvalidData, "text was not valid unicode") + io::Error::new(io::ErrorKind::InvalidData, + "Windows stdio in console mode does not support non-UTF-8 byte sequences; \ + see https://github.com/rust-lang/rust/issues/23344") } fn readconsole_input_control(wakeup_mask: c::ULONG) -> c::CONSOLE_READCONSOLE_CONTROL { |
