Add readlink and symlink
This commit is contained in:
@@ -50,6 +50,7 @@ pub const REG_ESPACE: c_int = 13;
|
||||
pub const REG_BADRPT: c_int = 14;
|
||||
|
||||
#[no_mangle]
|
||||
#[linkage = "weak"] // redefined in GIT
|
||||
pub extern "C" fn regcomp(out: *mut regex_t, pat: *const c_char, cflags: c_int) -> c_int {
|
||||
if cflags & REG_EXTENDED == REG_EXTENDED {
|
||||
return REG_ENOSYS;
|
||||
@@ -84,7 +85,9 @@ pub extern "C" fn regcomp(out: *mut regex_t, pat: *const c_char, cflags: c_int)
|
||||
Err(_) => REG_BADPAT,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[linkage = "weak"] // redefined in GIT
|
||||
pub unsafe extern "C" fn regfree(regex: *mut regex_t) {
|
||||
Vec::from_raw_parts(
|
||||
(*regex).ptr as *mut Vec<(Token, Range)>,
|
||||
@@ -92,7 +95,9 @@ pub unsafe extern "C" fn regfree(regex: *mut regex_t) {
|
||||
(*regex).capacity,
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[linkage = "weak"] // redefined in GIT
|
||||
pub extern "C" fn regexec(
|
||||
regex: *const regex_t,
|
||||
input: *const c_char,
|
||||
@@ -143,6 +148,7 @@ pub extern "C" fn regexec(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[linkage = "weak"] // redefined in GIT
|
||||
pub extern "C" fn regerror(code: c_int, _regex: *const regex_t, out: *mut c_char, max: c_int) {
|
||||
let string = match code {
|
||||
0 => "No error\0",
|
||||
|
||||
@@ -445,7 +445,6 @@ pub extern "C" fn pwrite(
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t {
|
||||
use core::slice;
|
||||
let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) };
|
||||
trace_expr!(
|
||||
Sys::read(fildes, buf),
|
||||
@@ -456,9 +455,11 @@ pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssiz
|
||||
)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn readlink(path: *const c_char, buf: *mut c_char, bufsize: size_t) -> c_int {
|
||||
unimplemented!();
|
||||
#[no_mangle]
|
||||
pub extern "C" fn readlink(path: *const c_char, buf: *mut c_char, bufsize: size_t) -> ssize_t {
|
||||
let path = unsafe { CStr::from_ptr(path) };
|
||||
let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, bufsize as usize) };
|
||||
Sys::readlink(path, buf)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -518,9 +519,11 @@ pub extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssize_t) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn symlink(path1: *const c_char, path2: *const c_char) -> c_int {
|
||||
unimplemented!();
|
||||
let path1 = unsafe { CStr::from_ptr(path1) };
|
||||
let path2 = unsafe { CStr::from_ptr(path2) };
|
||||
Sys::symlink(path1, path2)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
|
||||
+17
-13
@@ -305,19 +305,19 @@ impl Pal for Sys {
|
||||
e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t
|
||||
}
|
||||
|
||||
fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int {
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
|
||||
e(unsafe {
|
||||
syscall!(
|
||||
READLINKAT,
|
||||
AT_FDCWD,
|
||||
pathname.as_ptr(),
|
||||
out.as_mut_ptr(),
|
||||
out.len()
|
||||
)
|
||||
}) as ssize_t
|
||||
}
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
|
||||
e(unsafe {
|
||||
syscall!(
|
||||
READLINKAT,
|
||||
AT_FDCWD,
|
||||
pathname.as_ptr(),
|
||||
out.as_mut_ptr(),
|
||||
out.len()
|
||||
)
|
||||
}) 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,
|
||||
@@ -332,7 +332,7 @@ impl Pal for Sys {
|
||||
proc_path.push(0);
|
||||
|
||||
let len = out.len();
|
||||
let read = readlink(
|
||||
let read = Self::readlink(
|
||||
CStr::from_bytes_with_nul(&proc_path).unwrap(),
|
||||
&mut out[..len - 1],
|
||||
);
|
||||
@@ -379,6 +379,10 @@ impl Pal for Sys {
|
||||
e(unsafe { syscall!(SETREUID, ruid, euid) }) as c_int
|
||||
}
|
||||
|
||||
fn symlink(path1: &CStr, path2: &CStr) -> c_int {
|
||||
e(unsafe { syscall!(SYMLINKAT, path1.as_ptr(), AT_FDCWD, path2.as_ptr()) }) as c_int
|
||||
}
|
||||
|
||||
fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
|
||||
Self::ioctl(fd, TCGETS, out as *mut c_void)
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ pub trait Pal {
|
||||
|
||||
fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t;
|
||||
|
||||
//fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t;
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t;
|
||||
|
||||
fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int;
|
||||
|
||||
@@ -138,6 +138,8 @@ pub trait Pal {
|
||||
|
||||
fn setreuid(ruid: uid_t, euid: uid_t) -> c_int;
|
||||
|
||||
fn symlink(path1: &CStr, path2: &CStr) -> c_int;
|
||||
|
||||
fn tcgetattr(fd: c_int, out: *mut termios) -> c_int;
|
||||
|
||||
fn tcsetattr(fd: c_int, act: c_int, value: *const termios) -> c_int;
|
||||
|
||||
@@ -835,6 +835,26 @@ impl Pal for Sys {
|
||||
e(syscall::read(fd as usize, buf)) as ssize_t
|
||||
}
|
||||
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
|
||||
let file = match File::open(pathname, fcntl::O_PATH | fcntl::O_SYMLINK) {
|
||||
Ok(fd) => fd,
|
||||
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 realpath(pathname: &CStr, out: &mut [u8]) -> c_int {
|
||||
let file = match File::open(pathname, fcntl::O_PATH) {
|
||||
Ok(fd) => fd,
|
||||
@@ -1019,6 +1039,22 @@ impl Pal for Sys {
|
||||
e(syscall::setreuid(ruid as usize, euid as usize)) as c_int
|
||||
}
|
||||
|
||||
fn symlink(path1: &CStr, path2: &CStr) -> c_int {
|
||||
let mut file = match File::open(
|
||||
path2,
|
||||
fcntl::O_CREAT | fcntl::O_WRONLY | fcntl::O_SYMLINK | 0o777,
|
||||
) {
|
||||
Ok(fd) => fd,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
if file.write(path1.to_bytes()).is_err() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
|
||||
let dup = e(syscall::dup(fd as usize, b"termios"));
|
||||
if dup == !0 {
|
||||
|
||||
Reference in New Issue
Block a user