Implement ttyname by adding fpath function to Sys. Remove realpath function and use fpath internally
This commit is contained in:
+21
-11
@@ -7,6 +7,7 @@ use rand::rngs::JitterRng;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
use c_str::CStr;
|
||||
use fs::File;
|
||||
use header::errno::*;
|
||||
use header::fcntl::*;
|
||||
use header::limits;
|
||||
@@ -611,22 +612,31 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn realpath(pathname: *const c_char, resolved: *mut c_char) -> *mut c_char {
|
||||
let mut path = [0; limits::PATH_MAX];
|
||||
let ptr = if resolved.is_null() {
|
||||
malloc(limits::PATH_MAX) as *mut c_char
|
||||
} else {
|
||||
resolved
|
||||
};
|
||||
|
||||
let mut out = slice::from_raw_parts_mut(ptr as *mut u8, limits::PATH_MAX);
|
||||
{
|
||||
let slice = if resolved.is_null() {
|
||||
&mut path
|
||||
} else {
|
||||
slice::from_raw_parts_mut(resolved as *mut u8, 4096)
|
||||
let file = match File::open(&CStr::from_ptr(pathname), O_PATH | O_CLOEXEC) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return ptr::null_mut(),
|
||||
};
|
||||
if Sys::realpath(CStr::from_ptr(pathname), slice) < 0 {
|
||||
|
||||
let len = out.len();
|
||||
let read = Sys::fpath(
|
||||
*file,
|
||||
&mut out[..len - 1],
|
||||
);
|
||||
if read < 0 {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
out[read as usize] = 0;
|
||||
}
|
||||
if !resolved.is_null() {
|
||||
resolved
|
||||
} else {
|
||||
strdup(path.as_ptr() as *const i8)
|
||||
}
|
||||
|
||||
ptr
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
|
||||
@@ -594,14 +594,30 @@ pub extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn ttyname(fildes: c_int) -> *mut c_char {
|
||||
unimplemented!();
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ttyname(fildes: c_int) -> *mut c_char {
|
||||
static mut TTYNAME: [c_char; 4096] = [0; 4096];
|
||||
if ttyname_r(fildes, TTYNAME.as_mut_ptr(), TTYNAME.len()) == 0 {
|
||||
TTYNAME.as_mut_ptr()
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ttyname_r(fildes: c_int, name: *mut c_char, namesize: size_t) -> c_int {
|
||||
unimplemented!();
|
||||
let name = unsafe { slice::from_raw_parts_mut(name as *mut u8, namesize) };
|
||||
if name.is_empty() {
|
||||
return errno::ERANGE;
|
||||
}
|
||||
|
||||
let len = Sys::fpath(fildes, &mut name[..namesize - 1]);
|
||||
if len < 0 {
|
||||
return unsafe { -platform::errno };
|
||||
}
|
||||
name[len as usize] = 0;
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
+11
-34
@@ -4,9 +4,7 @@ use core_io::Write;
|
||||
use super::types::*;
|
||||
use super::{errno, Pal};
|
||||
use c_str::CStr;
|
||||
use fs::File;
|
||||
use header::dirent::dirent;
|
||||
use header::fcntl;
|
||||
use header::poll::{nfds_t, pollfd};
|
||||
use header::signal::SIGCHLD;
|
||||
// use header::sys_resource::rusage;
|
||||
@@ -189,6 +187,17 @@ impl Pal for Sys {
|
||||
e(unsafe { syscall!(CLONE, SIGCHLD, 0, 0, 0, 0) }) as pid_t
|
||||
}
|
||||
|
||||
fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t {
|
||||
let mut proc_path = b"/proc/self/fd/".to_vec();
|
||||
write!(proc_path, "{}", fildes).unwrap();
|
||||
proc_path.push(0);
|
||||
|
||||
Self::readlink(
|
||||
CStr::from_bytes_with_nul(&proc_path).unwrap(),
|
||||
out
|
||||
)
|
||||
}
|
||||
|
||||
fn fsync(fildes: c_int) -> c_int {
|
||||
e(unsafe { syscall!(FSYNC, fildes) }) as c_int
|
||||
}
|
||||
@@ -346,38 +355,6 @@ impl Pal for Sys {
|
||||
}) as ssize_t
|
||||
}
|
||||
|
||||
fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int {
|
||||
let file = match File::open(pathname, fcntl::O_PATH) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
if out.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let mut proc_path = b"/proc/self/fd/".to_vec();
|
||||
write!(proc_path, "{}", *file).unwrap();
|
||||
proc_path.push(0);
|
||||
|
||||
let len = out.len();
|
||||
let read = Self::readlink(
|
||||
CStr::from_bytes_with_nul(&proc_path).unwrap(),
|
||||
&mut out[..len - 1],
|
||||
);
|
||||
if read < 0 {
|
||||
return -1;
|
||||
}
|
||||
out[read as usize] = 0;
|
||||
|
||||
// TODO: Should these checks from musl be ported?
|
||||
// https://gitlab.com/bminor/musl/blob/master/src/misc/realpath.c#L33-38
|
||||
// I'm not exactly sure what they're checking...
|
||||
// Seems to be a sanity check whether or not it's still the same file?
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn rename(old: &CStr, new: &CStr) -> c_int {
|
||||
e(unsafe { syscall!(RENAMEAT, AT_FDCWD, old.as_ptr(), AT_FDCWD, new.as_ptr()) }) as c_int
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ pub trait Pal {
|
||||
|
||||
fn fork() -> pid_t;
|
||||
|
||||
fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t;
|
||||
|
||||
fn fsync(fildes: c_int) -> c_int;
|
||||
|
||||
fn ftruncate(fildes: c_int, length: off_t) -> c_int;
|
||||
@@ -121,8 +123,6 @@ pub trait Pal {
|
||||
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t;
|
||||
|
||||
fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int;
|
||||
|
||||
fn rename(old: &CStr, new: &CStr) -> c_int;
|
||||
|
||||
fn rmdir(path: &CStr) -> c_int;
|
||||
|
||||
@@ -830,6 +830,10 @@ impl Pal for Sys {
|
||||
e(syscall::read(fd as usize, buf)) as ssize_t
|
||||
}
|
||||
|
||||
fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t {
|
||||
e(syscall::fpath(fildes as usize, out)) as ssize_t
|
||||
}
|
||||
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
|
||||
let file = match File::open(
|
||||
pathname,
|
||||
@@ -853,26 +857,6 @@ impl Pal for Sys {
|
||||
0
|
||||
}
|
||||
|
||||
fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int {
|
||||
let file = match File::open(pathname, fcntl::O_PATH | fcntl::O_CLOEXEC) {
|
||||
Ok(ok) => ok,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
if out.is_empty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let len = out.len();
|
||||
let read = e(syscall::fpath(*file as usize, &mut out[..len - 1]));
|
||||
if (read as c_int) < 0 {
|
||||
return -1;
|
||||
}
|
||||
out[read as usize] = 0;
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn rename(oldpath: &CStr, newpath: &CStr) -> c_int {
|
||||
match File::open(oldpath, fcntl::O_WRONLY | fcntl::O_CLOEXEC) {
|
||||
Ok(file) => e(syscall::frename(*file as usize, newpath.to_bytes())) as c_int,
|
||||
|
||||
Reference in New Issue
Block a user