Auto merge of #24598 - lfairy:impl-debug-for-file, r=alexcrichton
This patch adds a `Debug` impl for `std::fs::File`. On all platforms (Unix and Windows) it shows the file descriptor. On Linux, it displays the path and access mode as well. Ideally we should show the path/mode for all platforms, not just Linux, but this will do for now. cc #24570
This commit is contained in:
commit
77acda1c8e
@ -3296,6 +3296,8 @@ pub mod posix01 {
|
||||
pub const F_GETFL : c_int = 3;
|
||||
pub const F_SETFL : c_int = 4;
|
||||
|
||||
pub const O_ACCMODE : c_int = 3;
|
||||
|
||||
pub const SIGTRAP : c_int = 5;
|
||||
pub const SIG_IGN: size_t = 1;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use fmt;
|
||||
use io::{self, Error, ErrorKind, SeekFrom, Seek, Read, Write};
|
||||
use path::{Path, PathBuf};
|
||||
use sys::fs2 as fs_imp;
|
||||
@ -305,6 +306,12 @@ fn from_inner(f: fs_imp::File) -> File {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for File {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.inner.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Read for File {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
|
@ -13,6 +13,7 @@
|
||||
use os::unix::prelude::*;
|
||||
|
||||
use ffi::{CString, CStr, OsString, OsStr};
|
||||
use fmt;
|
||||
use io::{self, Error, SeekFrom};
|
||||
use libc::{self, c_int, size_t, off_t, c_char, mode_t};
|
||||
use mem;
|
||||
@ -294,6 +295,54 @@ fn from_inner(fd: c_int) -> File {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for File {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
#[cfg(target_os = "linux")]
|
||||
fn get_path(fd: c_int) -> Option<PathBuf> {
|
||||
use string::ToString;
|
||||
let mut p = PathBuf::from("/proc/self/fd");
|
||||
p.push(&fd.to_string());
|
||||
readlink(&p).ok()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn get_path(_fd: c_int) -> Option<PathBuf> {
|
||||
// FIXME(#24570): implement this for other Unix platforms
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn get_mode(_fd: c_int) -> Option<(bool, bool)> {
|
||||
// FIXME(#24570): implement this for other Unix platforms
|
||||
None
|
||||
}
|
||||
|
||||
let fd = self.0.raw();
|
||||
let mut b = f.debug_struct("File").field("fd", &fd);
|
||||
if let Some(path) = get_path(fd) {
|
||||
b = b.field("path", &path);
|
||||
}
|
||||
if let Some((read, write)) = get_mode(fd) {
|
||||
b = b.field("read", &read).field("write", &write);
|
||||
}
|
||||
b.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mkdir(p: &Path) -> io::Result<()> {
|
||||
let p = try!(cstr(p));
|
||||
try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) }));
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
use default::Default;
|
||||
use ffi::{OsString, AsOsStr};
|
||||
use fmt;
|
||||
use io::{self, Error, SeekFrom};
|
||||
use libc::{self, HANDLE};
|
||||
use mem;
|
||||
@ -271,6 +272,15 @@ fn from_inner(handle: libc::HANDLE) -> File {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for File {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// FIXME(#24570): add more info here (e.g. path, mode)
|
||||
f.debug_struct("File")
|
||||
.field("handle", &self.handle.raw())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_utf16(s: &Path) -> Vec<u16> {
|
||||
s.as_os_str().encode_wide().chain(Some(0).into_iter()).collect()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user