mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-29 22:14:27 +02:00
Cleanup xwrap implementation
This commit is contained in:
parent
7bd901273c
commit
f063fa5054
@ -15,7 +15,7 @@ use crate::{
|
|||||||
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
||||||
let mut buf = cstr_buf::wrap(buf);
|
let mut buf = cstr_buf::wrap(buf);
|
||||||
fd_path(fd, &mut buf)
|
fd_path(fd, &mut buf)
|
||||||
.log_cxx_with_msg(|w| w.write_str("fd_path failed"))
|
.log_cxx()
|
||||||
.map_or(-1_isize, |_| buf.len() as isize)
|
.map_or(-1_isize, |_| buf.len() as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ pub(crate) fn map_fd_for_cxx(fd: RawFd, sz: usize, rw: bool) -> &'static mut [u8
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn readlinkat_for_cxx(
|
pub(crate) unsafe fn readlinkat(
|
||||||
dirfd: RawFd,
|
dirfd: RawFd,
|
||||||
path: *const c_char,
|
path: *const c_char,
|
||||||
buf: *mut u8,
|
buf: *mut u8,
|
||||||
@ -116,12 +116,7 @@ unsafe extern "C" fn cp_afc_for_cxx(src: *const c_char, dest: *const c_char) ->
|
|||||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||||
let src = FsPath::from(src);
|
let src = FsPath::from(src);
|
||||||
let dest = FsPath::from(dest);
|
let dest = FsPath::from(dest);
|
||||||
return src
|
return src.copy_to(dest).log_cxx().is_ok();
|
||||||
.copy_to(dest)
|
|
||||||
.log_cxx_with_msg(|w| {
|
|
||||||
w.write_fmt(format_args!("cp_afc {} -> {} failed", src, dest))
|
|
||||||
})
|
|
||||||
.is_ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -135,12 +130,7 @@ unsafe extern "C" fn mv_path_for_cxx(src: *const c_char, dest: *const c_char) ->
|
|||||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||||
let src = FsPath::from(src);
|
let src = FsPath::from(src);
|
||||||
let dest = FsPath::from(dest);
|
let dest = FsPath::from(dest);
|
||||||
return src
|
return src.move_to(dest).log_cxx().is_ok();
|
||||||
.move_to(dest)
|
|
||||||
.log_cxx_with_msg(|w| {
|
|
||||||
w.write_fmt(format_args!("mv_path {} -> {} failed", src, dest))
|
|
||||||
})
|
|
||||||
.is_ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -154,12 +144,7 @@ unsafe extern "C" fn link_path_for_cxx(src: *const c_char, dest: *const c_char)
|
|||||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||||
let src = FsPath::from(src);
|
let src = FsPath::from(src);
|
||||||
let dest = FsPath::from(dest);
|
let dest = FsPath::from(dest);
|
||||||
return src
|
return src.link_to(dest).log_cxx().is_ok();
|
||||||
.link_to(dest)
|
|
||||||
.log_cxx_with_msg(|w| {
|
|
||||||
w.write_fmt(format_args!("link_path {} -> {} failed", src, dest))
|
|
||||||
})
|
|
||||||
.is_ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -173,11 +158,7 @@ unsafe extern "C" fn clone_attr_for_cxx(src: *const c_char, dest: *const c_char)
|
|||||||
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
if let Ok(dest) = Utf8CStr::from_ptr(dest) {
|
||||||
let src = FsPath::from(src);
|
let src = FsPath::from(src);
|
||||||
let dest = FsPath::from(dest);
|
let dest = FsPath::from(dest);
|
||||||
return clone_attr(src, dest)
|
return clone_attr(src, dest).log_cxx().is_ok();
|
||||||
.log_cxx_with_msg(|w| {
|
|
||||||
w.write_fmt(format_args!("clone_attr {} -> {} failed", src, dest))
|
|
||||||
})
|
|
||||||
.is_ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
@ -186,9 +167,7 @@ unsafe extern "C" fn clone_attr_for_cxx(src: *const c_char, dest: *const c_char)
|
|||||||
|
|
||||||
#[unsafe(export_name = "fclone_attr")]
|
#[unsafe(export_name = "fclone_attr")]
|
||||||
unsafe extern "C" fn fclone_attr_for_cxx(a: RawFd, b: RawFd) -> bool {
|
unsafe extern "C" fn fclone_attr_for_cxx(a: RawFd, b: RawFd) -> bool {
|
||||||
fclone_attr(a, b)
|
fclone_attr(a, b).log_cxx().is_ok()
|
||||||
.log_cxx_with_msg(|w| w.write_str("fclone_attr failed"))
|
|
||||||
.is_ok()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(export_name = "cxx$utf8str$new")]
|
#[unsafe(export_name = "cxx$utf8str$new")]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::cxx_extern::readlinkat_for_cxx;
|
use crate::cxx_extern::readlinkat;
|
||||||
use crate::{
|
use crate::{
|
||||||
FileAttr, FsPath, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr, Utf8CStrBuf, cstr,
|
FileAttr, FsPath, LibcReturn, OsError, OsResult, OsResultStatic, Utf8CStr, Utf8CStrBuf, cstr,
|
||||||
cstr_buf, errno, fd_path, fd_set_attr,
|
cstr_buf, errno, fd_path, fd_set_attr,
|
||||||
@ -8,15 +8,20 @@ use std::ffi::CStr;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||||
|
use std::ptr::NonNull;
|
||||||
use std::{mem, slice};
|
use std::{mem, slice};
|
||||||
|
|
||||||
pub struct DirEntry<'a> {
|
pub struct DirEntry<'a> {
|
||||||
dir: &'a Directory,
|
dir: &'a Directory,
|
||||||
entry: &'a dirent,
|
entry: NonNull<dirent>,
|
||||||
d_name_len: usize,
|
d_name_len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DirEntry<'_> {
|
impl DirEntry<'_> {
|
||||||
|
pub fn as_ptr(&self) -> *mut dirent {
|
||||||
|
self.entry.as_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &CStr {
|
pub fn name(&self) -> &CStr {
|
||||||
unsafe {
|
unsafe {
|
||||||
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(
|
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(
|
||||||
@ -81,7 +86,7 @@ impl DirEntry<'_> {
|
|||||||
pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> {
|
pub fn read_link(&self, buf: &mut dyn Utf8CStrBuf) -> OsResult<()> {
|
||||||
buf.clear();
|
buf.clear();
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = readlinkat_for_cxx(
|
let r = readlinkat(
|
||||||
self.dir.as_raw_fd(),
|
self.dir.as_raw_fd(),
|
||||||
self.d_name.as_ptr(),
|
self.d_name.as_ptr(),
|
||||||
buf.as_mut_ptr().cast(),
|
buf.as_mut_ptr().cast(),
|
||||||
@ -154,12 +159,13 @@ impl Deref for DirEntry<'_> {
|
|||||||
type Target = dirent;
|
type Target = dirent;
|
||||||
|
|
||||||
fn deref(&self) -> &dirent {
|
fn deref(&self) -> &dirent {
|
||||||
self.entry
|
unsafe { self.entry.as_ref() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
pub struct Directory {
|
pub struct Directory {
|
||||||
dirp: *mut libc::DIR,
|
inner: NonNull<libc::DIR>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum WalkResult {
|
pub enum WalkResult {
|
||||||
@ -172,12 +178,14 @@ impl Directory {
|
|||||||
pub fn open(path: &Utf8CStr) -> OsResult<Directory> {
|
pub fn open(path: &Utf8CStr) -> OsResult<Directory> {
|
||||||
let dirp = unsafe { libc::opendir(path.as_ptr()) };
|
let dirp = unsafe { libc::opendir(path.as_ptr()) };
|
||||||
let dirp = dirp.as_os_result("opendir", Some(path), None)?;
|
let dirp = dirp.as_os_result("opendir", Some(path), None)?;
|
||||||
Ok(Directory { dirp })
|
Ok(Directory {
|
||||||
|
inner: unsafe { NonNull::new_unchecked(dirp) },
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&mut self) -> OsResult<'static, Option<DirEntry>> {
|
pub fn read(&mut self) -> OsResult<'static, Option<DirEntry>> {
|
||||||
*errno() = 0;
|
*errno() = 0;
|
||||||
let e = unsafe { libc::readdir(self.dirp) };
|
let e = unsafe { libc::readdir(self.inner.as_ptr()) };
|
||||||
if e.is_null() {
|
if e.is_null() {
|
||||||
return if *errno() != 0 {
|
return if *errno() != 0 {
|
||||||
Err(OsError::last_os_error("readdir", None, None))
|
Err(OsError::last_os_error("readdir", None, None))
|
||||||
@ -194,7 +202,7 @@ impl Directory {
|
|||||||
} else {
|
} else {
|
||||||
let e = DirEntry {
|
let e = DirEntry {
|
||||||
dir: self,
|
dir: self,
|
||||||
entry,
|
entry: NonNull::from(entry),
|
||||||
d_name_len: d_name.to_bytes_with_nul().len(),
|
d_name_len: d_name.to_bytes_with_nul().len(),
|
||||||
};
|
};
|
||||||
Ok(Some(e))
|
Ok(Some(e))
|
||||||
@ -203,7 +211,7 @@ impl Directory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn rewind(&mut self) {
|
pub fn rewind(&mut self) {
|
||||||
unsafe { libc::rewinddir(self.dirp) }
|
unsafe { libc::rewinddir(self.inner.as_ptr()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn openat<'a>(&self, name: &'a CStr, flags: i32, mode: u32) -> OsResult<'a, OwnedFd> {
|
fn openat<'a>(&self, name: &'a CStr, flags: i32, mode: u32) -> OsResult<'a, OwnedFd> {
|
||||||
@ -416,13 +424,15 @@ impl TryFrom<OwnedFd> for Directory {
|
|||||||
fn try_from(fd: OwnedFd) -> OsResult<'static, Self> {
|
fn try_from(fd: OwnedFd) -> OsResult<'static, Self> {
|
||||||
let dirp = unsafe { libc::fdopendir(fd.into_raw_fd()) };
|
let dirp = unsafe { libc::fdopendir(fd.into_raw_fd()) };
|
||||||
let dirp = dirp.as_os_result("fdopendir", None, None)?;
|
let dirp = dirp.as_os_result("fdopendir", None, None)?;
|
||||||
Ok(Directory { dirp })
|
Ok(Directory {
|
||||||
|
inner: unsafe { NonNull::new_unchecked(dirp) },
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRawFd for Directory {
|
impl AsRawFd for Directory {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
unsafe { libc::dirfd(self.dirp) }
|
unsafe { libc::dirfd(self.inner.as_ptr()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +445,7 @@ impl AsFd for Directory {
|
|||||||
impl Drop for Directory {
|
impl Drop for Directory {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::closedir(self.dirp);
|
libc::closedir(self.inner.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,6 @@ pub trait ResultExt<T> {
|
|||||||
// Internal C++ bridging logging routines
|
// Internal C++ bridging logging routines
|
||||||
pub(crate) trait CxxResultExt<T> {
|
pub(crate) trait CxxResultExt<T> {
|
||||||
fn log_cxx(self) -> LoggedResult<T>;
|
fn log_cxx(self) -> LoggedResult<T>;
|
||||||
fn log_cxx_with_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Loggable<T> {
|
trait Loggable<T> {
|
||||||
@ -78,10 +77,6 @@ impl<T, R: Loggable<T>> CxxResultExt<T> for R {
|
|||||||
fn log_cxx(self) -> LoggedResult<T> {
|
fn log_cxx(self) -> LoggedResult<T> {
|
||||||
self.do_log(LogLevel::ErrorCxx, None)
|
self.do_log(LogLevel::ErrorCxx, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log_cxx_with_msg<F: FnOnce(Formatter) -> fmt::Result>(self, f: F) -> LoggedResult<T> {
|
|
||||||
self.do_log_msg(LogLevel::ErrorCxx, None, f)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, R: Loggable<T>> ResultExt<T> for R {
|
impl<T, R: Loggable<T>> ResultExt<T> for R {
|
||||||
|
@ -25,7 +25,6 @@ int xsocket(int domain, int type, int protocol);
|
|||||||
int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||||
int xlisten(int sockfd, int backlog);
|
int xlisten(int sockfd, int backlog);
|
||||||
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
|
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
|
||||||
int xaccess(const char *path, int mode);
|
|
||||||
int xstat(const char *pathname, struct stat *buf);
|
int xstat(const char *pathname, struct stat *buf);
|
||||||
int xfstat(int fd, struct stat *buf);
|
int xfstat(int fd, struct stat *buf);
|
||||||
int xdup(int fd);
|
int xdup(int fd);
|
||||||
|
@ -1,62 +1,27 @@
|
|||||||
// Functions in this file are only for exporting to C++, DO NOT USE IN RUST
|
// Functions in this file are only for exporting to C++, DO NOT USE IN RUST
|
||||||
|
|
||||||
use std::ffi::CStr;
|
|
||||||
use std::os::unix::io::RawFd;
|
|
||||||
|
|
||||||
use libc::{
|
use libc::{
|
||||||
c_char, c_uint, c_ulong, c_void, dev_t, mode_t, nfds_t, off_t, pollfd, sockaddr, socklen_t,
|
c_char, c_uint, c_ulong, c_void, dev_t, mode_t, nfds_t, off_t, pollfd, sockaddr, socklen_t,
|
||||||
ssize_t,
|
};
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::os::fd::FromRawFd;
|
||||||
|
use std::os::unix::io::RawFd;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
use crate::cxx_extern::readlinkat;
|
||||||
|
use crate::{
|
||||||
|
CxxResultExt, Directory, FsPath, LibcReturn, Utf8CStr, cstr_buf, slice_from_ptr,
|
||||||
|
slice_from_ptr_mut,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::cxx_extern::readlinkat_for_cxx;
|
fn ptr_to_str<'a>(ptr: *const c_char) -> Option<&'a str> {
|
||||||
use crate::{CxxResultExt, FsPath, Utf8CStr, Utf8CStrBufRef, errno, raw_cstr};
|
|
||||||
|
|
||||||
fn ptr_to_str<'a, T>(ptr: *const T) -> &'a str {
|
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
"(null)"
|
None
|
||||||
} else {
|
} else {
|
||||||
unsafe { CStr::from_ptr(ptr.cast()) }.to_str().unwrap_or("")
|
unsafe { CStr::from_ptr(ptr) }.to_str().ok()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn error_str() -> &'static str {
|
|
||||||
unsafe { ptr_to_str(libc::strerror(*errno())) }
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! error_cxx {
|
|
||||||
($($args:tt)+) => {
|
|
||||||
($crate::log_with_args($crate::LogLevel::ErrorCxx, format_args_nl!($($args)+)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! perror {
|
|
||||||
($fmt:expr) => {
|
|
||||||
$crate::log_with_formatter($crate::LogLevel::ErrorCxx, |w| {
|
|
||||||
w.write_str($fmt)?;
|
|
||||||
w.write_fmt(format_args_nl!(" failed with {}: {}", $crate::errno(), error_str()))
|
|
||||||
})
|
|
||||||
};
|
|
||||||
($fmt:expr, $($args:tt)*) => {
|
|
||||||
$crate::log_with_formatter($crate::LogLevel::ErrorCxx, |w| {
|
|
||||||
w.write_fmt(format_args!($fmt, $($args)*))?;
|
|
||||||
w.write_fmt(format_args_nl!(" failed with {}: {}", $crate::errno(), error_str()))
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
mod c_export {
|
|
||||||
use std::os::unix::io::RawFd;
|
|
||||||
|
|
||||||
use crate::{slice_from_ptr, slice_from_ptr_mut};
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
unsafe extern "C" fn xwrite(fd: RawFd, buf: *const u8, bufsz: usize) -> isize {
|
|
||||||
unsafe { super::xwrite(fd, slice_from_ptr(buf, bufsz)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
unsafe extern "C" fn xxread(fd: RawFd, buf: *mut u8, bufsz: usize) -> isize {
|
|
||||||
unsafe { super::xxread(fd, slice_from_ptr_mut(buf, bufsz)) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,10 +30,10 @@ unsafe extern "C" fn xrealpath(path: *const c_char, buf: *mut u8, bufsz: usize)
|
|||||||
unsafe {
|
unsafe {
|
||||||
match Utf8CStr::from_ptr(path) {
|
match Utf8CStr::from_ptr(path) {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
let mut buf = Utf8CStrBufRef::from_ptr(buf, bufsz);
|
let mut buf = cstr_buf::wrap_ptr(buf, bufsz);
|
||||||
FsPath::from(p)
|
FsPath::from(p)
|
||||||
.realpath(&mut buf)
|
.realpath(&mut buf)
|
||||||
.log_cxx_with_msg(|w| w.write_fmt(format_args!("realpath {} failed", p)))
|
.log_cxx()
|
||||||
.map_or(-1, |_| buf.len() as isize)
|
.map_or(-1, |_| buf.len() as isize)
|
||||||
}
|
}
|
||||||
Err(_) => -1,
|
Err(_) => -1,
|
||||||
@ -81,10 +46,10 @@ unsafe extern "C" fn xreadlink(path: *const c_char, buf: *mut u8, bufsz: usize)
|
|||||||
unsafe {
|
unsafe {
|
||||||
match Utf8CStr::from_ptr(path) {
|
match Utf8CStr::from_ptr(path) {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
let mut buf = Utf8CStrBufRef::from_ptr(buf, bufsz);
|
let mut buf = cstr_buf::wrap_ptr(buf, bufsz);
|
||||||
FsPath::from(p)
|
FsPath::from(p)
|
||||||
.read_link(&mut buf)
|
.read_link(&mut buf)
|
||||||
.log_cxx_with_msg(|w| w.write_fmt(format_args!("readlink {} failed", p)))
|
.log_cxx()
|
||||||
.map_or(-1, |_| buf.len() as isize)
|
.map_or(-1, |_| buf.len() as isize)
|
||||||
}
|
}
|
||||||
Err(_) => -1,
|
Err(_) => -1,
|
||||||
@ -100,244 +65,176 @@ unsafe extern "C" fn xreadlinkat(
|
|||||||
bufsz: usize,
|
bufsz: usize,
|
||||||
) -> isize {
|
) -> isize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = readlinkat_for_cxx(dirfd, path, buf, bufsz);
|
readlinkat(dirfd, path, buf, bufsz)
|
||||||
if r < 0 {
|
.as_os_result("readlinkat", ptr_to_str(path), None)
|
||||||
perror!("readlinkat {}", ptr_to_str(path))
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xfopen(path: *const c_char, mode: *const c_char) -> *mut libc::FILE {
|
unsafe extern "C" fn xfopen(path: *const c_char, mode: *const c_char) -> *mut libc::FILE {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fp = libc::fopen(path, mode);
|
libc::fopen(path, mode)
|
||||||
if fp.is_null() {
|
.as_os_result("fopen", ptr_to_str(path), None)
|
||||||
perror!("fopen {}", ptr_to_str(path));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(ptr::null_mut())
|
||||||
fp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xfdopen(fd: RawFd, mode: *const c_char) -> *mut libc::FILE {
|
unsafe extern "C" fn xfdopen(fd: RawFd, mode: *const c_char) -> *mut libc::FILE {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fp = libc::fdopen(fd, mode);
|
libc::fdopen(fd, mode)
|
||||||
if fp.is_null() {
|
.as_os_result("fdopen", None, None)
|
||||||
perror!("fdopen");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(ptr::null_mut())
|
||||||
fp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xopen(path: *const c_char, flags: i32, mode: mode_t) -> RawFd {
|
unsafe extern "C" fn xopen(path: *const c_char, flags: i32, mode: mode_t) -> RawFd {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::open(path, flags, mode as c_uint);
|
libc::open(path, flags, mode as c_uint)
|
||||||
if r < 0 {
|
.as_os_result("open", ptr_to_str(path), None)
|
||||||
perror!("open {}", ptr_to_str(path));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xopenat(dirfd: RawFd, path: *const c_char, flags: i32, mode: mode_t) -> RawFd {
|
unsafe extern "C" fn xopenat(dirfd: RawFd, path: *const c_char, flags: i32, mode: mode_t) -> RawFd {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::openat(dirfd, path, flags, mode as c_uint);
|
libc::openat(dirfd, path, flags, mode as c_uint)
|
||||||
if r < 0 {
|
.as_os_result("openat", ptr_to_str(path), None)
|
||||||
perror!("openat {}", ptr_to_str(path));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fully write data slice
|
#[unsafe(no_mangle)]
|
||||||
fn xwrite(fd: RawFd, data: &[u8]) -> isize {
|
unsafe extern "C" fn xwrite(fd: RawFd, buf: *const u8, bufsz: usize) -> isize {
|
||||||
unsafe {
|
let mut file = unsafe { ManuallyDrop::new(File::from_raw_fd(fd)) };
|
||||||
let mut write_sz: usize = 0;
|
let data = unsafe { slice_from_ptr(buf, bufsz) };
|
||||||
let mut r: ssize_t;
|
file.write_all(data)
|
||||||
let mut remain: &[u8] = data;
|
.log_cxx()
|
||||||
loop {
|
.map_or(-1, |_| data.len() as isize)
|
||||||
r = libc::write(fd, remain.as_ptr().cast(), remain.len());
|
|
||||||
if r < 0 {
|
|
||||||
if *errno() == libc::EINTR {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
perror!("write");
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
let r = r as usize;
|
|
||||||
write_sz += r;
|
|
||||||
remain = &remain[r..];
|
|
||||||
if r == 0 || remain.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !remain.is_empty() {
|
|
||||||
error_cxx!("write ({} != {})", write_sz, data.len())
|
|
||||||
}
|
|
||||||
write_sz as isize
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xread(fd: RawFd, buf: *mut c_void, bufsz: usize) -> isize {
|
unsafe extern "C" fn xread(fd: RawFd, buf: *mut c_void, bufsz: usize) -> isize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::read(fd, buf, bufsz);
|
libc::read(fd, buf, bufsz)
|
||||||
if r < 0 {
|
.as_os_result("read", None, None)
|
||||||
perror!("read");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fully read size of data slice
|
#[unsafe(no_mangle)]
|
||||||
fn xxread(fd: RawFd, data: &mut [u8]) -> isize {
|
unsafe extern "C" fn xxread(fd: RawFd, buf: *mut u8, bufsz: usize) -> isize {
|
||||||
unsafe {
|
let mut file = unsafe { ManuallyDrop::new(File::from_raw_fd(fd)) };
|
||||||
let mut read_sz: usize = 0;
|
let data = unsafe { slice_from_ptr_mut(buf, bufsz) };
|
||||||
let mut r: ssize_t;
|
file.read_exact(data)
|
||||||
let mut remain: &mut [u8] = data;
|
.log_cxx()
|
||||||
loop {
|
.map_or(-1, |_| data.len() as isize)
|
||||||
r = libc::read(fd, remain.as_mut_ptr().cast(), remain.len());
|
|
||||||
if r < 0 {
|
|
||||||
if *errno() == libc::EINTR {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
perror!("read");
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
let r = r as usize;
|
|
||||||
read_sz += r;
|
|
||||||
remain = &mut remain[r..];
|
|
||||||
if r == 0 || remain.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !remain.is_empty() {
|
|
||||||
error_cxx!("read ({} != {})", read_sz, data.len())
|
|
||||||
}
|
|
||||||
read_sz as isize
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn xpipe2(fds: &mut [i32; 2], flags: i32) -> i32 {
|
pub(crate) fn xpipe2(fds: &mut [i32; 2], flags: i32) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::pipe2(fds.as_mut_ptr(), flags);
|
libc::pipe2(fds.as_mut_ptr(), flags)
|
||||||
if r < 0 {
|
.as_os_result("pipe2", None, None)
|
||||||
perror!("pipe2");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xsetns(fd: RawFd, nstype: i32) -> i32 {
|
extern "C" fn xsetns(fd: RawFd, nstype: i32) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::setns(fd, nstype);
|
libc::setns(fd, nstype)
|
||||||
if r < 0 {
|
.as_os_result("setns", None, None)
|
||||||
perror!("setns");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xunshare(flags: i32) -> i32 {
|
extern "C" fn xunshare(flags: i32) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::unshare(flags);
|
libc::unshare(flags)
|
||||||
if r < 0 {
|
.as_os_result("unshare", None, None)
|
||||||
perror!("unshare");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xopendir(path: *const c_char) -> *mut libc::DIR {
|
unsafe extern "C" fn xopendir(path: *const c_char) -> *mut libc::DIR {
|
||||||
unsafe {
|
unsafe {
|
||||||
let dp = libc::opendir(path);
|
libc::opendir(path)
|
||||||
if dp.is_null() {
|
.as_os_result("opendir", ptr_to_str(path), None)
|
||||||
perror!("opendir {}", ptr_to_str(path));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(ptr::null_mut())
|
||||||
dp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xfdopendir(fd: RawFd) -> *mut libc::DIR {
|
extern "C" fn xfdopendir(fd: RawFd) -> *mut libc::DIR {
|
||||||
unsafe {
|
unsafe {
|
||||||
let dp = libc::fdopendir(fd);
|
libc::fdopendir(fd)
|
||||||
if dp.is_null() {
|
.as_os_result("fdopendir", None, None)
|
||||||
perror!("fdopendir");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(ptr::null_mut())
|
||||||
dp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xreaddir(dirp: *mut libc::DIR) -> *mut libc::dirent {
|
unsafe extern "C" fn xreaddir(mut dir: ManuallyDrop<Directory>) -> *mut libc::dirent {
|
||||||
unsafe {
|
dir.read()
|
||||||
*errno() = 0;
|
.log_cxx()
|
||||||
loop {
|
.ok()
|
||||||
let e = libc::readdir(dirp);
|
.flatten()
|
||||||
if e.is_null() {
|
.map_or(ptr::null_mut(), |entry| entry.as_ptr())
|
||||||
if *errno() != 0 {
|
|
||||||
perror!("readdir")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Filter out . and ..
|
|
||||||
let s = (*e).d_name.as_ptr();
|
|
||||||
if libc::strcmp(s, raw_cstr!(".")) == 0 || libc::strcmp(s, raw_cstr!("..")) == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xsetsid() -> i32 {
|
extern "C" fn xsetsid() -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::setsid();
|
libc::setsid()
|
||||||
if r < 0 {
|
.as_os_result("setsid", None, None)
|
||||||
perror!("setsid");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xsocket(domain: i32, ty: i32, protocol: i32) -> RawFd {
|
extern "C" fn xsocket(domain: i32, ty: i32, protocol: i32) -> RawFd {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fd = libc::socket(domain, ty, protocol);
|
libc::socket(domain, ty, protocol)
|
||||||
if fd < 0 {
|
.as_os_result("socket", None, None)
|
||||||
perror!("socket");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
fd
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xbind(socket: i32, address: *const sockaddr, len: socklen_t) -> i32 {
|
unsafe extern "C" fn xbind(socket: i32, address: *const sockaddr, len: socklen_t) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::bind(socket, address, len);
|
libc::bind(socket, address, len)
|
||||||
if r < 0 {
|
.as_os_result("bind", None, None)
|
||||||
perror!("bind");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xlisten(socket: i32, backlog: i32) -> i32 {
|
extern "C" fn xlisten(socket: i32, backlog: i32) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::listen(socket, backlog);
|
libc::listen(socket, backlog)
|
||||||
if r < 0 {
|
.as_os_result("listen", None, None)
|
||||||
perror!("listen");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,77 +246,60 @@ unsafe extern "C" fn xaccept4(
|
|||||||
flg: i32,
|
flg: i32,
|
||||||
) -> RawFd {
|
) -> RawFd {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fd = libc::accept4(sockfd, addr, len, flg);
|
libc::accept4(sockfd, addr, len, flg)
|
||||||
if fd < 0 {
|
.as_os_result("accept4", None, None)
|
||||||
perror!("accept4");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
fd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
unsafe extern "C" fn xaccess(path: *const c_char, mode: i32) -> i32 {
|
|
||||||
unsafe {
|
|
||||||
let r = libc::access(path, mode);
|
|
||||||
if r < 0 {
|
|
||||||
perror!("access {}", ptr_to_str(path));
|
|
||||||
}
|
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xstat(path: *const c_char, buf: *mut libc::stat) -> i32 {
|
unsafe extern "C" fn xstat(path: *const c_char, buf: *mut libc::stat) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::stat(path, buf);
|
libc::stat(path, buf)
|
||||||
if r < 0 {
|
.as_os_result("stat", ptr_to_str(path), None)
|
||||||
perror!("stat {}", ptr_to_str(path));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xfstat(fd: RawFd, buf: *mut libc::stat) -> i32 {
|
unsafe extern "C" fn xfstat(fd: RawFd, buf: *mut libc::stat) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::fstat(fd, buf);
|
libc::fstat(fd, buf)
|
||||||
if r < 0 {
|
.as_os_result("fstat", None, None)
|
||||||
perror!("fstat");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xdup(oldfd: RawFd) -> RawFd {
|
extern "C" fn xdup(oldfd: RawFd) -> RawFd {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fd = libc::dup(oldfd);
|
libc::dup(oldfd)
|
||||||
if fd < 0 {
|
.as_os_result("dup", None, None)
|
||||||
perror!("dup");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
fd
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xdup2(oldfd: RawFd, newfd: RawFd) -> RawFd {
|
extern "C" fn xdup2(oldfd: RawFd, newfd: RawFd) -> RawFd {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fd = libc::dup2(oldfd, newfd);
|
libc::dup2(oldfd, newfd)
|
||||||
if fd < 0 {
|
.as_os_result("dup2", None, None)
|
||||||
perror!("dup2");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
fd
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xsymlink(target: *const c_char, linkpath: *const c_char) -> i32 {
|
unsafe extern "C" fn xsymlink(target: *const c_char, linkpath: *const c_char) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::symlink(target, linkpath);
|
libc::symlink(target, linkpath)
|
||||||
if r < 0 {
|
.as_os_result("symlink", ptr_to_str(target), ptr_to_str(linkpath))
|
||||||
perror!("symlink {} -> {}", ptr_to_str(target), ptr_to_str(linkpath));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,44 +312,40 @@ unsafe extern "C" fn xmount(
|
|||||||
data: *const c_void,
|
data: *const c_void,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::mount(src, target, fstype, flags, data);
|
libc::mount(src, target, fstype, flags, data)
|
||||||
if r < 0 {
|
.as_os_result("mount", ptr_to_str(src), ptr_to_str(target))
|
||||||
perror!("mount {} -> {}", ptr_to_str(src), ptr_to_str(target));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xumount2(target: *const c_char, flags: i32) -> i32 {
|
unsafe extern "C" fn xumount2(target: *const c_char, flags: i32) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::umount2(target, flags);
|
libc::umount2(target, flags)
|
||||||
if r < 0 {
|
.as_os_result("umount2", ptr_to_str(target), None)
|
||||||
perror!("umount2 {}", ptr_to_str(target));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xrename(oldname: *const c_char, newname: *const c_char) -> i32 {
|
unsafe extern "C" fn xrename(oldname: *const c_char, newname: *const c_char) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::rename(oldname, newname);
|
libc::rename(oldname, newname)
|
||||||
if r < 0 {
|
.as_os_result("rename", ptr_to_str(oldname), ptr_to_str(newname))
|
||||||
perror!("rename {} -> {}", ptr_to_str(oldname), ptr_to_str(newname));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 {
|
unsafe extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::mkdir(path, mode);
|
match Utf8CStr::from_ptr(path) {
|
||||||
if r < 0 && *errno() != libc::EEXIST {
|
Ok(p) => FsPath::from(p).mkdir(mode).log_cxx().map_or(-1, |_| 0),
|
||||||
perror!("mkdir {}", ptr_to_str(path));
|
Err(_) => -1,
|
||||||
}
|
}
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,10 +353,7 @@ unsafe extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 {
|
|||||||
unsafe extern "C" fn xmkdirs(path: *const c_char, mode: mode_t) -> i32 {
|
unsafe extern "C" fn xmkdirs(path: *const c_char, mode: mode_t) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
match Utf8CStr::from_ptr(path) {
|
match Utf8CStr::from_ptr(path) {
|
||||||
Ok(p) => FsPath::from(p)
|
Ok(p) => FsPath::from(p).mkdirs(mode).log_cxx().map_or(-1, |_| 0),
|
||||||
.mkdirs(mode)
|
|
||||||
.log_cxx_with_msg(|w| w.write_fmt(format_args!("mkdirs {} failed", p)))
|
|
||||||
.map_or(-1, |_| 0),
|
|
||||||
Err(_) => -1,
|
Err(_) => -1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,43 +367,39 @@ unsafe extern "C" fn xsendfile(
|
|||||||
count: usize,
|
count: usize,
|
||||||
) -> isize {
|
) -> isize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::sendfile(out_fd, in_fd, offset, count);
|
libc::sendfile(out_fd, in_fd, offset, count)
|
||||||
if r < 0 {
|
.as_os_result("sendfile", None, None)
|
||||||
perror!("sendfile");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn xfork() -> i32 {
|
extern "C" fn xfork() -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::fork();
|
libc::fork()
|
||||||
if r < 0 {
|
.as_os_result("fork", None, None)
|
||||||
perror!("fork");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xpoll(fds: *mut pollfd, nfds: nfds_t, timeout: i32) -> i32 {
|
unsafe extern "C" fn xpoll(fds: *mut pollfd, nfds: nfds_t, timeout: i32) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::poll(fds, nfds, timeout);
|
libc::poll(fds, nfds, timeout)
|
||||||
if r < 0 {
|
.as_os_result("poll", None, None)
|
||||||
perror!("poll");
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn xmknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> i32 {
|
unsafe extern "C" fn xmknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
let r = libc::mknod(pathname, mode, dev);
|
libc::mknod(pathname, mode, dev)
|
||||||
if r < 0 {
|
.as_os_result("mknod", ptr_to_str(pathname), None)
|
||||||
perror!("mknod {}", ptr_to_str(pathname));
|
.log_cxx()
|
||||||
}
|
.unwrap_or(-1)
|
||||||
r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user