diff options
| -rw-r--r-- | library/std/src/os/vxworks/fs.rs | 15 | ||||
| -rw-r--r-- | library/std/src/os/vxworks/raw.rs | 3 | ||||
| -rw-r--r-- | library/std/src/sys/unix/ext/fs.rs | 7 | ||||
| -rw-r--r-- | library/std/src/sys/unix/fd.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/unix/fs.rs | 56 | ||||
| -rw-r--r-- | library/std/src/sys/vxworks/fd.rs | 201 | ||||
| -rw-r--r-- | library/std/src/sys/vxworks/fs.rs | 624 | ||||
| -rw-r--r-- | library/std/src/sys/vxworks/io.rs | 75 | ||||
| -rw-r--r-- | library/std/src/sys/vxworks/mod.rs | 3 |
9 files changed, 81 insertions, 909 deletions
diff --git a/library/std/src/os/vxworks/fs.rs b/library/std/src/os/vxworks/fs.rs index 5a7e5bcaa76..77e6238ca1f 100644 --- a/library/std/src/os/vxworks/fs.rs +++ b/library/std/src/os/vxworks/fs.rs @@ -26,10 +26,16 @@ pub trait MetadataExt { #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_atime(&self) -> i64; #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_mtime(&self) -> i64; #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_ctime(&self) -> i64; #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_blksize(&self) -> u64; #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_blocks(&self) -> u64; @@ -66,12 +72,21 @@ impl MetadataExt for Metadata { fn st_atime(&self) -> i64 { self.as_inner().as_inner().st_atime as i64 } + fn st_atime_nsec(&self) -> i64 { + 0 + } fn st_mtime(&self) -> i64 { self.as_inner().as_inner().st_mtime as i64 } + fn st_mtime_nsec(&self) -> i64 { + 0 + } fn st_ctime(&self) -> i64 { self.as_inner().as_inner().st_ctime as i64 } + fn st_ctime_nsec(&self) -> i64 { + 0 + } fn st_blksize(&self) -> u64 { self.as_inner().as_inner().st_blksize as u64 } diff --git a/library/std/src/os/vxworks/raw.rs b/library/std/src/os/vxworks/raw.rs index 29a0af5645e..cb41ddfe2a9 100644 --- a/library/std/src/os/vxworks/raw.rs +++ b/library/std/src/os/vxworks/raw.rs @@ -5,3 +5,6 @@ use crate::os::raw::c_ulong; #[stable(feature = "pthread_t", since = "1.8.0")] pub type pthread_t = c_ulong; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub use libc::{blkcnt_t, blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t, time_t}; diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs index 4b9f4ceb29c..66bbc1c5854 100644 --- a/library/std/src/sys/unix/ext/fs.rs +++ b/library/std/src/sys/unix/ext/fs.rs @@ -650,6 +650,9 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn blocks(&self) -> u64; + #[cfg(target_os = "vxworks")] + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn attrib(&self) -> u8; } #[stable(feature = "metadata_ext", since = "1.1.0")] @@ -702,6 +705,10 @@ impl MetadataExt for fs::Metadata { fn blocks(&self) -> u64 { self.st_blocks() } + #[cfg(target_os = "vxworks")] + fn attrib(&self) -> u8 { + self.st_attrib() + } } /// Unix-specific extensions for [`fs::FileType`]. diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 2224a055d6d..d3a279a2355 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -200,7 +200,8 @@ impl FileDesc { target_os = "l4re", target_os = "linux", target_os = "haiku", - target_os = "redox" + target_os = "redox", + target_os = "vxworks" )))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { @@ -217,7 +218,8 @@ impl FileDesc { target_os = "l4re", target_os = "linux", target_os = "haiku", - target_os = "redox" + target_os = "redox", + target_os = "vxworks" ))] pub fn set_cloexec(&self) -> io::Result<()> { unsafe { diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 8184c25afcf..819e8ef1841 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -297,6 +297,7 @@ impl FileAttr { #[cfg(not(target_os = "netbsd"))] impl FileAttr { + #[cfg(not(target_os = "vxworks"))] pub fn modified(&self) -> io::Result<SystemTime> { Ok(SystemTime::from(libc::timespec { tv_sec: self.stat.st_mtime as libc::time_t, @@ -304,6 +305,15 @@ impl FileAttr { })) } + #[cfg(target_os = "vxworks")] + pub fn modified(&self) -> io::Result<SystemTime> { + Ok(SystemTime::from(libc::timespec { + tv_sec: self.stat.st_mtime as libc::time_t, + tv_nsec: 0, + })) + } + + #[cfg(not(target_os = "vxworks"))] pub fn accessed(&self) -> io::Result<SystemTime> { Ok(SystemTime::from(libc::timespec { tv_sec: self.stat.st_atime as libc::time_t, @@ -311,6 +321,14 @@ impl FileAttr { })) } + #[cfg(target_os = "vxworks")] + pub fn accessed(&self) -> io::Result<SystemTime> { + Ok(SystemTime::from(libc::timespec { + tv_sec: self.stat.st_atime as libc::time_t, + tv_nsec: 0, + })) + } + #[cfg(any( target_os = "freebsd", target_os = "openbsd", @@ -535,12 +553,22 @@ impl DirEntry { lstat(&self.path()) } - #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "haiku"))] + #[cfg(any( + target_os = "solaris", + target_os = "illumos", + target_os = "haiku", + target_os = "vxworks" + ))] pub fn file_type(&self) -> io::Result<FileType> { lstat(&self.path()).map(|m| m.file_type()) } - #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "haiku")))] + #[cfg(not(any( + target_os = "solaris", + target_os = "illumos", + target_os = "haiku", + target_os = "vxworks" + )))] pub fn file_type(&self) -> io::Result<FileType> { match self.entry.d_type { libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }), @@ -565,7 +593,8 @@ impl DirEntry { target_os = "haiku", target_os = "l4re", target_os = "fuchsia", - target_os = "redox" + target_os = "redox", + target_os = "vxworks" ))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 @@ -603,7 +632,8 @@ impl DirEntry { target_os = "linux", target_os = "emscripten", target_os = "l4re", - target_os = "haiku" + target_os = "haiku", + target_os = "vxworks" ))] fn name_bytes(&self) -> &[u8] { unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() } @@ -901,13 +931,25 @@ impl fmt::Debug for File { Some(PathBuf::from(OsString::from_vec(buf))) } - #[cfg(not(any(target_os = "linux", target_os = "macos")))] + #[cfg(target_os = "vxworks")] + fn get_path(fd: c_int) -> Option<PathBuf> { + let mut buf = vec![0; libc::PATH_MAX as usize]; + let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) }; + if n == -1 { + return None; + } + let l = buf.iter().position(|&c| c == 0).unwrap(); + buf.truncate(l as usize); + Some(PathBuf::from(OsString::from_vec(buf))) + } + + #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "vxworks")))] fn get_path(_fd: c_int) -> Option<PathBuf> { // FIXME(#24570): implement this for other Unix platforms None } - #[cfg(any(target_os = "linux", target_os = "macos"))] + #[cfg(any(target_os = "linux", target_os = "macos", target_os = "vxworks"))] fn get_mode(fd: c_int) -> Option<(bool, bool)> { let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) }; if mode == -1 { @@ -921,7 +963,7 @@ impl fmt::Debug for File { } } - #[cfg(not(any(target_os = "linux", target_os = "macos")))] + #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "vxworks")))] fn get_mode(_fd: c_int) -> Option<(bool, bool)> { // FIXME(#24570): implement this for other Unix platforms None diff --git a/library/std/src/sys/vxworks/fd.rs b/library/std/src/sys/vxworks/fd.rs deleted file mode 100644 index d58468ad539..00000000000 --- a/library/std/src/sys/vxworks/fd.rs +++ /dev/null @@ -1,201 +0,0 @@ -#![unstable(reason = "not public", issue = "none", feature = "fd")] - -use crate::cmp; -use crate::io::{self, Initializer, IoSlice, IoSliceMut, Read}; -use crate::mem; -use crate::sys::cvt; -use crate::sys_common::AsInner; - -use libc::{self, c_int, c_void, ssize_t}; - -#[derive(Debug)] -pub struct FileDesc { - fd: c_int, -} - -// The maximum read limit on most POSIX-like systems is `SSIZE_MAX`, -// with the man page quoting that if the count of bytes to read is -// greater than `SSIZE_MAX` the result is "unspecified". -const READ_LIMIT: usize = ssize_t::MAX as usize; - -impl FileDesc { - pub fn new(fd: c_int) -> FileDesc { - FileDesc { fd: fd } - } - - pub fn raw(&self) -> c_int { - self.fd - } - - /// Extracts the actual file descriptor without closing it. - pub fn into_raw(self) -> c_int { - let fd = self.fd; - mem::forget(self); - fd - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let ret = cvt(unsafe { - libc::read(self.fd, buf.as_mut_ptr() as *mut c_void, cmp::min(buf.len(), READ_LIMIT)) - })?; - Ok(ret as usize) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - let ret = cvt(unsafe { - libc::readv( - self.fd, - bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::MAX as usize) as c_int, - ) - })?; - Ok(ret as usize) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - true - } - - pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> { - let mut me = self; - (&mut me).read_to_end(buf) - } - - pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> { - unsafe fn cvt_pread( - fd: c_int, - buf: *mut c_void, - count: usize, - offset: i64, - ) -> io::Result<isize> { - use libc::pread; - cvt(pread(fd, buf, count, offset)) - } - - unsafe { - cvt_pread( - self.fd, - buf.as_mut_ptr() as *mut c_void, - cmp::min(buf.len(), READ_LIMIT), - offset as i64, - ) - .map(|n| n as usize) - } - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - let ret = cvt(unsafe { - libc::write(self.fd, buf.as_ptr() as *const c_void, cmp::min(buf.len(), READ_LIMIT)) - })?; - Ok(ret as usize) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let ret = cvt(unsafe { - libc::writev( - self.fd, - bufs.as_ptr() as *const libc::iovec, - cmp::min(bufs.len(), c_int::MAX as usize) as c_int, - ) - })?; - Ok(ret as usize) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> { - unsafe fn cvt_pwrite( - fd: c_int, - buf: *const c_void, - count: usize, - offset: i64, - ) -> io::Result<isize> { - use libc::pwrite; - cvt(pwrite(fd, buf, count, offset)) - } - - unsafe { - cvt_pwrite( - self.fd, - buf.as_ptr() as *const c_void, - cmp::min(buf.len(), READ_LIMIT), - offset as i64, - ) - .map(|n| n as usize) - } - } - - pub fn get_cloexec(&self) -> io::Result<bool> { - unsafe { Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) } - } - - pub fn set_cloexec(&self) -> io::Result<()> { - unsafe { - let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?; - let new = previous | libc::FD_CLOEXEC; - if new != previous { - cvt(libc::fcntl(self.fd, libc::F_SETFD, new))?; - } - Ok(()) - } - } - - pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - unsafe { - let v = nonblocking as c_int; - cvt(libc::ioctl(self.fd, libc::FIONBIO, &v))?; - Ok(()) - } - } - - // refer to pxPipeDrv library documentation. - // VxWorks uses fcntl to set O_NONBLOCK to the pipes - pub fn set_nonblocking_pipe(&self, nonblocking: bool) -> io::Result<()> { - unsafe { - let mut flags = cvt(libc::fcntl(self.fd, libc::F_GETFL, 0))?; - flags = if nonblocking { flags | libc::O_NONBLOCK } else { flags & !libc::O_NONBLOCK }; - cvt(libc::fcntl(self.fd, libc::F_SETFL, flags))?; - Ok(()) - } - } - - pub fn duplicate(&self) -> io::Result<FileDesc> { - let fd = self.raw(); - match cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, 0) }) { - Ok(newfd) => Ok(FileDesc::new(newfd)), - Err(e) => return Err(e), - } - } -} - -impl<'a> Read for &'a FileDesc { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - (**self).read(buf) - } - - #[inline] - unsafe fn initializer(&self) -> Initializer { - Initializer::nop() - } -} - -impl AsInner<c_int> for FileDesc { - fn as_inner(&self) -> &c_int { - &self.fd - } -} - -impl Drop for FileDesc { - fn drop(&mut self) { - // Note that errors are ignored when closing a file descriptor. The - // reason for this is that if an error occurs we don't actually know if - // the file descriptor was closed or not, and if we retried (for - // something like EINTR), we might close another valid file descriptor - // (opened after we closed ours. - let _ = unsafe { libc::close(self.fd) }; - } -} diff --git a/library/std/src/sys/vxworks/fs.rs b/library/std/src/sys/vxworks/fs.rs deleted file mode 100644 index cb761af1a25..00000000000 --- a/library/std/src/sys/vxworks/fs.rs +++ /dev/null @@ -1,624 +0,0 @@ -// copies from linuxx -use crate::ffi::{CStr, CString, OsStr, OsString}; -use crate::fmt; -use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; -use crate::mem; -use crate::path::{Path, PathBuf}; -use crate::ptr; -use crate::sync::Arc; -use crate::sys::fd::FileDesc; -use crate::sys::time::SystemTime; -use crate::sys::vxworks::ext::ffi::OsStrExt; -use crate::sys::vxworks::ext::ffi::OsStringExt; -use crate::sys::{cvt, cvt_r}; -use crate::sys_common::{AsInner, FromInner}; -use libc::{self, c_int, mode_t, off_t, stat64}; -use libc::{dirent, ftruncate, lseek, open, readdir_r as readdir64_r}; -pub struct File(FileDesc); - -#[derive(Clone)] -pub struct FileAttr { - stat: stat64, -} - -// all DirEntry's will have a reference to this struct -struct InnerReadDir { - dirp: Dir, - root: PathBuf, -} - -pub struct ReadDir { - inner: Arc<InnerReadDir>, - end_of_stream: bool, -} - -struct Dir(*mut libc::DIR); - -unsafe impl Send for Dir {} -unsafe impl Sync for Dir {} - -pub struct DirEntry { - entry: dirent, - dir: Arc<InnerReadDir>, -} - -#[derive(Clone, Debug)] -pub struct OpenOptions { - // generic - read: bool, - write: bool, - append: bool, - truncate: bool, - create: bool, - create_new: bool, - // system-specific - custom_flags: i32, - mode: mode_t, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct FilePermissions { - mode: mode_t, -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct FileType { - mode: mode_t, -} - -#[derive(Debug)] -pub struct DirBuilder { - mode: mode_t, -} - -impl FileAttr { - pub fn size(&self) -> u64 { - self.stat.st_size as u64 - } - pub fn perm(&self) -> FilePermissions { - FilePermissions { mode: (self.stat.st_mode as mode_t) } - } - - pub fn file_type(&self) -> FileType { - FileType { mode: self.stat.st_mode as mode_t } - } - - pub fn modified(&self) -> io::Result<SystemTime> { - Ok(SystemTime::from(libc::timespec { - tv_sec: self.stat.st_mtime as libc::time_t, - tv_nsec: 0, // hack 2.0; - })) - } - - pub fn accessed(&self) -> io::Result<SystemTime> { - Ok(SystemTime::from(libc::timespec { - tv_sec: self.stat.st_atime as libc::time_t, - tv_nsec: 0, // hack - a proper fix would be better - })) - } - - pub fn created(&self) -> io::Result<SystemTime> { - Err(io::Error::new( - io::ErrorKind::Other, - "creation time is not available on this platform currently", - )) - } -} - -impl AsInner<stat64> for FileAttr { - fn as_inner(&self) -> &stat64 { - &self.stat - } -} - -impl FilePermissions { - pub fn readonly(&self) -> bool { - // check if any class (owner, group, others) has write permission - self.mode & 0o222 == 0 - } - - pub fn set_readonly(&mut self, readonly: bool) { - if readonly { - // remove write permission for all classes; equivalent to `chmod a-w <file>` - self.mode &= !0o222; - } else { - // add write permission for all classes; equivalent to `chmod a+w <file>` - self.mode |= 0o222; - } - } - pub fn mode(&self) -> u32 { - self.mode as u32 - } -} - -impl FileType { - pub fn is_dir(&self) -> bool { - self.is(libc::S_IFDIR) - } - pub fn is_file(&self) -> bool { - self.is(libc::S_IFREG) - } - pub fn is_symlink(&self) -> bool { - self.is(libc::S_IFLNK) - } - - pub fn is(&self, mode: mode_t) -> bool { - self.mode & libc::S_IFMT == mode - } -} - -impl FromInner<u32> for FilePermissions { - fn from_inner(mode: u32) -> FilePermissions { - FilePermissions { mode: mode as mode_t } - } -} - -impl fmt::Debug for ReadDir { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame. - // Thus the result will be e g 'ReadDir("/home")' - fmt::Debug::fmt(&*self.inner.root, f) - } -} - -impl Iterator for ReadDir { - type Item = io::Result<DirEntry>; - fn next(&mut self) -> Option<io::Result<DirEntry>> { - if self.end_of_stream { - return None; - } - - unsafe { - let mut ret = DirEntry { entry: mem::zeroed(), dir: Arc::clone(&self.inner) }; - let mut entry_ptr = ptr::null_mut(); - loop { - if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 { - if entry_ptr.is_null() { - // We encountered an error (which will be returned in this iteration), but - // we also reached the end of the directory stream. The `end_of_stream` - // flag is enabled to make sure that we return `None` in the next iteration - // (instead of looping forever) - self.end_of_stream = true; - } - return Some(Err(Error::last_os_error())); - } - if entry_ptr.is_null() { - return None; - } - if ret.name_bytes() != b"." && ret.name_bytes() != b".." { - return Some(Ok(ret)); - } - } - } - } -} - -impl Drop for Dir { - fn drop(&mut self) { - let r = unsafe { libc::closedir(self.0) }; - debug_assert_eq!(r, 0); - } -} - -impl DirEntry { - pub fn path(&self) -> PathBuf { - use crate::sys::vxworks::ext::ffi::OsStrExt; - self.dir.root.join(OsStr::from_bytes(self.name_bytes())) - } - - pub fn file_name(&self) -> OsString { - OsStr::from_bytes(self.name_bytes()).to_os_string() - } - - pub fn metadata(&self) -> io::Result<FileAttr> { - lstat(&self.path()) - } - - pub fn file_type(&self) -> io::Result<FileType> { - lstat(&self.path()).map(|m| m.file_type()) - } - - pub fn ino(&self) -> u64 { - self.entry.d_ino as u64 - } - - fn name_bytes(&self) -> &[u8] { - unsafe { - //&*self.name - CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() - } - } -} - -impl OpenOptions { - pub fn new() -> OpenOptions { - OpenOptions { - // generic - read: false, - write: false, - append: false, - truncate: false, - create: false, - create_new: false, - // system-specific - custom_flags: 0, - mode: 0o666, - } - } - - pub fn read(&mut self, read: bool) { - self.read = read; - } - pub fn write(&mut self, write: bool) { - self.write = write; - } - pub fn append(&mut self, append: bool) { - self.append = append; - } - pub fn truncate(&mut self, truncate: bool) { - self.truncate = truncate; - } - pub fn create(&mut self, create: bool) { - self.create = create; - } - pub fn create_new(&mut self, create_new: bool) { - self.create_new = create_new; - } - pub fn mode(&mut self, mode: u32) { - self.mode = mode as mode_t; - } - - fn get_access_mode(&self) -> io::Result<c_int> { - match (self.read, self.write, self.append) { - (true, false, false) => Ok(libc::O_RDONLY), - (false, true, false) => Ok(libc::O_WRONLY), - (true, true, false) => Ok(libc::O_RDWR), - (false, _, true) => Ok(libc::O_WRONLY | libc::O_APPEND), - (true, _, true) => Ok(libc::O_RDWR | libc::O_APPEND), - (false, false, false) => Err(Error::from_raw_os_error(libc::EINVAL)), - } - } - - fn get_creation_mode(&self) -> io::Result<c_int> { - match (self.write, self.append) { - (true, false) => {} - (false, false) => { - if self.truncate || self.create || self.create_new { - return Err(Error::from_raw_os_error(libc::EINVAL)); - } - } - (_, true) => { - if self.truncate && !self.create_new { - return Err(Error::from_raw_os_error(libc::EINVAL)); - } - } - } - - Ok(match (self.create, self.truncate, self.create_new) { - (false, false, false) => 0, - (true, false, false) => libc::O_CREAT, - (false, true, false) => libc::O_TRUNC, - (true, true, false) => libc::O_CREAT | libc::O_TRUNC, - (_, _, true) => libc::O_CREAT | libc::O_EXCL, - }) - } -} - -impl File { - pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> { - let path = cstr(path)?; - File::open_c(&path, opts) - } - - pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> { - let flags = libc::O_CLOEXEC - | opts.get_access_mode()? - | opts.get_creation_mode()? - | (opts.custom_flags as c_int & !libc::O_ACCMODE); - let fd = cvt_r(|| unsafe { open(path.as_ptr(), flags, opts.mode as c_int) })?; - Ok(File(FileDesc::new(fd))) - } - - pub fn file_attr(&self) -> io::Result<FileAttr> { - let mut stat: stat64 = unsafe { mem::zeroed() }; - cvt(unsafe { ::libc::fstat(self.0.raw(), &mut stat) })?; - Ok(FileAttr { stat: stat }) - } - - pub fn fsync(&self) -> io::Result<()> { - cvt_r(|| unsafe { libc::fsync(self.0.raw()) })?; - Ok(()) - } - - pub fn datasync(&self) -> io::Result<()> { - cvt_r(|| unsafe { os_datasync(self.0.raw()) })?; - return Ok(()); - unsafe fn os_datasync(fd: c_int) -> c_int { - libc::fsync(fd) - } //not supported - } - - pub fn truncate(&self, size: u64) -> io::Result<()> { - return cvt_r(|| unsafe { ftruncate(self.0.raw(), size as off_t) }).map(drop); - } - - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - self.0.read(buf) - } - - pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - self.0.read_vectored(bufs) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - - pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> { - self.0.read_at(buf, offset) - } - - pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - self.0.write(buf) - } - - pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - self.0.write_vectored(bufs) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } - - pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> { - self.0.write_at(buf, offset) - } - - pub fn flush(&self) -> io::Result<()> { - Ok(()) - } - - pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> { - let (whence, pos) = match pos { - // Casting to `i64` is fine, too large values will end up as - // negative which will cause an error in `"lseek64"`. - SeekFrom::Start(off) => (libc::SEEK_SET, off as i64), - SeekFrom::End(off) => (libc::SEEK_END, off), - SeekFrom::Current(off) => (libc::SEEK_CUR, off), - }; - let n = cvt(unsafe { lseek(self.0.raw(), pos, whence) })?; - Ok(n as u64) - } - - pub fn duplicate(&self) -> io::Result<File> { - self.0.duplicate().map(File) - } - - pub fn fd(&self) -> &FileDesc { - &self.0 - } - - pub fn into_fd(self) -> FileDesc { - self.0 - } - - pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { - cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?; - Ok(()) - } - - pub fn diverge(&self) -> ! { - panic!() - } -} - -impl DirBuilder { - pub fn new() -> DirBuilder { - DirBuilder { mode: 0o777 } - } - - pub fn mkdir(&self, p: &Path) -> io::Result<()> { - let p = cstr(p)?; - cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) })?; - Ok(()) - } - - pub fn set_mode(&mut self, mode: u32) { - self.mode = mode as mode_t; - } -} - -fn cstr(path: &Path) -> io::Result<CString> { - use crate::sys::vxworks::ext::ffi::OsStrExt; - Ok(CString::new(path.as_os_str().as_bytes())?) -} - -impl FromInner<c_int> for File { - fn from_inner(fd: c_int) -> File { - File(FileDesc::new(fd)) - } -} - -impl fmt::Debug for File { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fn get_path(fd: c_int) -> Option<PathBuf> { - let mut buf = vec![0; libc::PATH_MAX as usize]; - let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) }; - if n == -1 { - return None; - } - let l = buf.iter().position(|&c| c == 0).unwrap(); - buf.truncate(l as usize); - Some(PathBuf::from(OsString::from_vec(buf))) - } - fn get_mode(fd: c_int) -> Option<(bool, bool)> { - let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) }; - if mode == -1 { - return None; - } - match mode & libc::O_ACCMODE { - libc::O_RDONLY => Some((true, false)), - libc::O_RDWR => Some((true, true)), - libc::O_WRONLY => Some((false, true)), - _ => None, - } - } - - let fd = self.0.raw(); - let mut b = f.debug_struct("File"); - b.field("fd", &fd); - if let Some(path) = get_path(fd) { - b.field("path", &path); - } - if let Some((read, write)) = get_mode(fd) { - b.field("read", &read).field("write", &write); - } - b.finish() - } -} - -pub fn readdir(p: &Path) -> io::Result<ReadDir> { - let root = p.to_path_buf(); - let p = cstr(p)?; - unsafe { - let ptr = libc::opendir(p.as_ptr()); - if ptr.is_null() { - Err(Error::last_os_error()) - } else { - let inner = InnerReadDir { dirp: Dir(ptr), root }; - Ok(ReadDir { inner: Arc::new(inner), end_of_stream: false }) - } - } -} - -pub fn unlink(p: &Path) -> io::Result<()> { - let p = cstr(p)?; - cvt(unsafe { libc::unlink(p.as_ptr()) })?; - Ok(()) -} - -pub fn rename(old: &Path, new: &Path) -> io::Result<()> { - let old = cstr(old)?; - let new = cstr(new)?; - cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })?; - Ok(()) -} - -pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { - let p = cstr(p)?; - cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })?; - Ok(()) -} - -pub fn rmdir(p: &Path) -> io::Result<()> { - let p = cstr(p)?; - cvt(unsafe { libc::rmdir(p.as_ptr()) })?; - Ok(()) -} - -pub fn remove_dir_all(path: &Path) -> io::Result<()> { - let filetype = lstat(path)?.file_type(); - if filetype.is_symlink() { unlink(path) } else { remove_dir_all_recursive(path) } -} - -fn remove_dir_all_recursive(path: &Path) -> io::Result<()> { - for child in readdir(path)? { - let child = child?; - if child.file_type()?.is_dir() { - remove_dir_all_recursive(&child.path())?; - } else { - unlink(&child.path())?; - } - } - rmdir(path) -} - -pub fn readlink(p: &Path) -> io::Result<PathBuf> { - let c_path = cstr(p)?; - let p = c_path.as_ptr(); - - let mut buf = Vec::with_capacity(256); - - loop { - let buf_read = - cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize; - - unsafe { - buf.set_len(buf_read); - } - - if buf_read != buf.capacity() { - buf.shrink_to_fit(); - - return Ok(PathBuf::from(OsString::from_vec(buf))); - } - - // Trigger the internal buffer resizing logic of `Vec` by requiring - // more space than the current capacity. The length is guaranteed to be - // the same as the capacity due to the if statement above. - buf.reserve(1); - } -} - -pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { - let src = cstr(src)?; - let dst = cstr(dst)?; - cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })?; - Ok(()) -} - -pub fn link(src: &Path, dst: &Path) -> io::Result<()> { - let src = cstr(src)?; - let dst = cstr(dst)?; - cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?; - Ok(()) -} - -pub fn stat(p: &Path) -> io::Result<FileAttr> { - let p = cstr(p)?; - let mut stat: stat64 = unsafe { mem::zeroed() }; - cvt(unsafe { libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _) })?; - Ok(FileAttr { stat }) -} - -pub fn lstat(p: &Path) -> io::Result<FileAttr> { - let p = cstr(p)?; - let mut stat: stat64 = unsafe { mem::zeroed() }; - cvt(unsafe { ::libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _) })?; - Ok(FileAttr { stat }) -} - -pub fn canonicalize(p: &Path) -> io::Result<PathBuf> { - use crate::sys::vxworks::ext::ffi::OsStrExt; - let path = CString::new(p.as_os_str().as_bytes())?; - let buf; - unsafe { - let r = libc::realpath(path.as_ptr(), ptr::null_mut()); - if r.is_null() { - return Err(io::Error::last_os_error()); - } - buf = CStr::from_ptr(r).to_bytes().to_vec(); - libc::free(r as *mut _); - } - Ok(PathBuf::from(OsString::from_vec(buf))) -} - -pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { - use crate::fs::File; - if !from.is_file() { - return Err(Error::new( - ErrorKind::InvalidInput, - "the source path is not an existing regular file", - )); - } - - let mut reader = File::open(from)?; - let mut writer = File::create(to)?; - let perm = reader.metadata()?.permissions(); - - let ret = io::copy(&mut reader, &mut writer)?; - writer.set_permissions(perm)?; - Ok(ret) -} diff --git a/library/std/src/sys/vxworks/io.rs b/library/std/src/sys/vxworks/io.rs deleted file mode 100644 index 0f68ebf8da9..00000000000 --- a/library/std/src/sys/vxworks/io.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::marker::PhantomData; -use crate::slice; - -use libc::{c_void, iovec}; - -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: iovec, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - IoSlice { - vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - self.vec.iov_len -= n; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } -} - -pub struct IoSliceMut<'a> { - vec: iovec, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - IoSliceMut { - vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n { - panic!("advancing IoSliceMut beyond its length"); - } - - unsafe { - self.vec.iov_len -= n; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } - - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } -} diff --git a/library/std/src/sys/vxworks/mod.rs b/library/std/src/sys/vxworks/mod.rs index 2d25efbd7e3..fb90f4b0c1a 100644 --- a/library/std/src/sys/vxworks/mod.rs +++ b/library/std/src/sys/vxworks/mod.rs @@ -22,8 +22,11 @@ pub mod condvar; pub mod env; #[path = "../unix/ext/mod.rs"] pub mod ext; +#[path = "../unix/fd.rs"] pub mod fd; +#[path = "../unix/fs.rs"] pub mod fs; +#[path = "../unix/io.rs"] pub mod io; #[path = "../unix/memchr.rs"] pub mod memchr; |
