mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-12 08:32:07 +00:00
Cleanup libbase
This commit is contained in:
@@ -14,16 +14,9 @@ use crate::files::map_file_at;
|
||||
pub(crate) use crate::xwrap::*;
|
||||
use crate::{
|
||||
BufReadExt, CxxResultExt, Directory, OsResultStatic, Utf8CStr, clone_attr, cstr, fclone_attr,
|
||||
fd_path, map_fd, map_file, slice_from_ptr,
|
||||
map_fd, map_file, slice_from_ptr,
|
||||
};
|
||||
|
||||
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
||||
let mut buf = cstr::buf::wrap(buf);
|
||||
fd_path(fd, &mut buf)
|
||||
.log_cxx()
|
||||
.map_or(-1_isize, |_| buf.len() as isize)
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||
unsafe {
|
||||
|
||||
@@ -8,28 +8,20 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
void full_read(int fd, string &str) {
|
||||
string full_read(int fd) {
|
||||
string str;
|
||||
char buf[4096];
|
||||
for (ssize_t len; (len = xread(fd, buf, sizeof(buf))) > 0;)
|
||||
str.insert(str.end(), buf, buf + len);
|
||||
}
|
||||
|
||||
void full_read(const char *filename, string &str) {
|
||||
if (int fd = xopen(filename, O_RDONLY | O_CLOEXEC); fd >= 0) {
|
||||
full_read(fd, str);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
string full_read(int fd) {
|
||||
string str;
|
||||
full_read(fd, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
string full_read(const char *filename) {
|
||||
string str;
|
||||
full_read(filename, str);
|
||||
if (int fd = xopen(filename, O_RDONLY | O_CLOEXEC); fd >= 0) {
|
||||
str = full_read(fd);
|
||||
close(fd);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <linux/fs.h>
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include "misc.hpp"
|
||||
|
||||
template <typename T>
|
||||
static inline T align_to(T v, int a) {
|
||||
static_assert(std::is_integral<T>::value);
|
||||
return (v + a - 1) / a * a;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline T align_padding(T v, int a) {
|
||||
return align_to(v, a) - v;
|
||||
}
|
||||
#include "base-rs.hpp"
|
||||
|
||||
struct mmap_data : public byte_data {
|
||||
static_assert((sizeof(void *) == 8 && BLKGETSIZE64 == 0x80081272) ||
|
||||
@@ -45,12 +33,6 @@ bool fclone_attr(int src, int dest);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
static inline ssize_t realpath(
|
||||
const char * __restrict__ path, char * __restrict__ buf, size_t bufsiz) {
|
||||
return canonical_path(path, buf, bufsiz);
|
||||
}
|
||||
void full_read(int fd, std::string &str);
|
||||
void full_read(const char *filename, std::string &str);
|
||||
std::string full_read(int fd);
|
||||
std::string full_read(const char *filename);
|
||||
void write_zero(int fd, size_t size);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "../xwrap.hpp"
|
||||
#include "../files.hpp"
|
||||
#include "../misc.hpp"
|
||||
#include "../logging.hpp"
|
||||
#include "../base-rs.hpp"
|
||||
#include "../files.hpp"
|
||||
#include "../logging.hpp"
|
||||
|
||||
using rust::xpipe2;
|
||||
using rust::fd_path;
|
||||
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
@@ -69,8 +69,6 @@ pub mod ffi {
|
||||
#[namespace = "rust"]
|
||||
extern "Rust" {
|
||||
fn xpipe2(fds: &mut [i32; 2], flags: i32) -> i32;
|
||||
#[cxx_name = "fd_path"]
|
||||
fn fd_path_for_cxx(fd: i32, buf: &mut [u8]) -> isize;
|
||||
#[cxx_name = "map_file"]
|
||||
fn map_file_for_cxx(path: Utf8CStrRef, rw: bool) -> &'static mut [u8];
|
||||
#[cxx_name = "map_file_at"]
|
||||
|
||||
@@ -15,14 +15,8 @@ bool byte_view::contains(byte_view pattern) const {
|
||||
return _buf != nullptr && memmem(_buf, _sz, pattern._buf, pattern._sz) != nullptr;
|
||||
}
|
||||
|
||||
bool byte_view::equals(byte_view o) const {
|
||||
return _sz == o._sz && memcmp(_buf, o._buf, _sz) == 0;
|
||||
}
|
||||
|
||||
heap_data byte_view::clone() const {
|
||||
heap_data copy(_sz);
|
||||
memcpy(copy._buf, _buf, _sz);
|
||||
return copy;
|
||||
bool byte_view::operator==(byte_view rhs) const {
|
||||
return _sz == rhs._sz && memcmp(_buf, rhs._buf, _sz) == 0;
|
||||
}
|
||||
|
||||
void byte_data::swap(byte_data &o) {
|
||||
@@ -30,28 +24,25 @@ void byte_data::swap(byte_data &o) {
|
||||
std::swap(_sz, o._sz);
|
||||
}
|
||||
|
||||
rust::Vec<size_t> byte_data::patch(byte_view from, byte_view to) {
|
||||
rust::Vec<size_t> byte_data::patch(byte_view from, byte_view to) const {
|
||||
rust::Vec<size_t> v;
|
||||
if (_buf == nullptr)
|
||||
return v;
|
||||
auto p = _buf;
|
||||
auto eof = _buf + _sz;
|
||||
while (p < eof) {
|
||||
p = static_cast<uint8_t *>(memmem(p, eof - p, from.buf(), from.sz()));
|
||||
p = static_cast<uint8_t *>(memmem(p, eof - p, from.data(), from.size()));
|
||||
if (p == nullptr)
|
||||
return v;
|
||||
memset(p, 0, from.sz());
|
||||
memcpy(p, to.buf(), to.sz());
|
||||
memset(p, 0, from.size());
|
||||
memcpy(p, to.data(), to.size());
|
||||
v.push_back(p - _buf);
|
||||
p += from.sz();
|
||||
p += from.size();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
rust::Vec<size_t> mut_u8_patch(
|
||||
rust::Slice<uint8_t> buf,
|
||||
rust::Slice<const uint8_t> from,
|
||||
rust::Slice<const uint8_t> to) {
|
||||
rust::Vec<size_t> mut_u8_patch(MutByteSlice buf, ByteSlice from, ByteSlice to) {
|
||||
byte_data data(buf);
|
||||
return data.patch(from, to);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <bitset>
|
||||
#include <random>
|
||||
#include <cxx.h>
|
||||
|
||||
#include "xwrap.hpp"
|
||||
@@ -46,30 +45,11 @@ private:
|
||||
Func fn;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class reversed_container {
|
||||
public:
|
||||
reversed_container(T &base) : base(base) {}
|
||||
decltype(std::declval<T>().rbegin()) begin() { return base.rbegin(); }
|
||||
decltype(std::declval<T>().crbegin()) begin() const { return base.crbegin(); }
|
||||
decltype(std::declval<T>().crbegin()) cbegin() const { return base.crbegin(); }
|
||||
decltype(std::declval<T>().rend()) end() { return base.rend(); }
|
||||
decltype(std::declval<T>().crend()) end() const { return base.crend(); }
|
||||
decltype(std::declval<T>().crend()) cend() const { return base.crend(); }
|
||||
private:
|
||||
T &base;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
reversed_container<T> reversed(T &base) {
|
||||
return reversed_container<T>(base);
|
||||
}
|
||||
template<class T>
|
||||
static void default_new(T *&p) { p = new T(); }
|
||||
|
||||
template<class T>
|
||||
static inline void default_new(T *&p) { p = new T(); }
|
||||
|
||||
template<class T>
|
||||
static inline void default_new(std::unique_ptr<T> &p) { p.reset(new T()); }
|
||||
static void default_new(std::unique_ptr<T> &p) { p.reset(new T()); }
|
||||
|
||||
struct StringCmp {
|
||||
using is_transparent = void;
|
||||
@@ -78,49 +58,32 @@ struct StringCmp {
|
||||
|
||||
struct heap_data;
|
||||
|
||||
using ByteSlice = rust::Slice<const uint8_t>;
|
||||
using MutByteSlice = rust::Slice<uint8_t>;
|
||||
|
||||
// Interchangeable as `&[u8]` in Rust
|
||||
struct byte_view {
|
||||
byte_view() : _buf(nullptr), _sz(0) {}
|
||||
byte_view(const void *buf, size_t sz) : _buf((uint8_t *) buf), _sz(sz) {}
|
||||
|
||||
// byte_view, or any of its subclass, can be copied as byte_view
|
||||
// byte_view, or any of its subclasses, can be copied as byte_view
|
||||
byte_view(const byte_view &o) : _buf(o._buf), _sz(o._sz) {}
|
||||
|
||||
// Bridging to Rust slice
|
||||
byte_view(rust::Slice<const uint8_t> o) : byte_view(o.data(), o.size()) {}
|
||||
operator rust::Slice<const uint8_t>() const { return rust::Slice<const uint8_t>(_buf, _sz); }
|
||||
// Transparent conversion to Rust slice
|
||||
byte_view(const ByteSlice o) : byte_view(o.data(), o.size()) {}
|
||||
operator ByteSlice() const { return {_buf, _sz}; }
|
||||
|
||||
// String as bytes
|
||||
byte_view(const char *s, bool with_nul = true)
|
||||
: byte_view(std::string_view(s), with_nul, false) {}
|
||||
byte_view(const std::string &s, bool with_nul = true)
|
||||
: byte_view(std::string_view(s), with_nul, false) {}
|
||||
byte_view(std::string_view s, bool with_nul = true)
|
||||
: byte_view(s, with_nul, true /* string_view is not guaranteed to null terminate */ ) {}
|
||||
|
||||
// Vector as bytes
|
||||
byte_view(const std::vector<uint8_t> &v) : byte_view(v.data(), v.size()) {}
|
||||
|
||||
const uint8_t *buf() const { return _buf; }
|
||||
size_t sz() const { return _sz; }
|
||||
// String as bytes, including null terminator
|
||||
byte_view(const char *s) : byte_view(s, strlen(s) + 1) {}
|
||||
|
||||
const uint8_t *data() const { return _buf; }
|
||||
size_t size() const { return _sz; }
|
||||
bool contains(byte_view pattern) const;
|
||||
bool equals(byte_view o) const;
|
||||
heap_data clone() const;
|
||||
bool operator==(byte_view rhs) const;
|
||||
|
||||
protected:
|
||||
uint8_t *_buf;
|
||||
size_t _sz;
|
||||
|
||||
private:
|
||||
byte_view(std::string_view s, bool with_nul, bool check_nul)
|
||||
: byte_view(static_cast<const void *>(s.data()), s.length()) {
|
||||
if (with_nul) {
|
||||
if (check_nul && s[s.length()] != '\0')
|
||||
return;
|
||||
++_sz;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Interchangeable as `&mut [u8]` in Rust
|
||||
@@ -128,23 +91,18 @@ struct byte_data : public byte_view {
|
||||
byte_data() = default;
|
||||
byte_data(void *buf, size_t sz) : byte_view(buf, sz) {}
|
||||
|
||||
// byte_data, or any of its subclass, can be copied as byte_data
|
||||
// byte_data, or any of its subclasses, can be copied as byte_data
|
||||
byte_data(const byte_data &o) : byte_data(o._buf, o._sz) {}
|
||||
|
||||
// Transparent conversion from common C++ types to mutable byte references
|
||||
byte_data(std::string &s, bool with_nul = true)
|
||||
: byte_data(s.data(), with_nul ? s.length() + 1 : s.length()) {}
|
||||
byte_data(std::vector<uint8_t> &v) : byte_data(v.data(), v.size()) {}
|
||||
// Transparent conversion to Rust slice
|
||||
byte_data(const MutByteSlice o) : byte_data(o.data(), o.size()) {}
|
||||
operator MutByteSlice() const { return {_buf, _sz}; }
|
||||
|
||||
// Bridging to Rust slice
|
||||
byte_data(rust::Slice<uint8_t> o) : byte_data(o.data(), o.size()) {}
|
||||
operator rust::Slice<uint8_t>() { return rust::Slice<uint8_t>(_buf, _sz); }
|
||||
|
||||
using byte_view::buf;
|
||||
uint8_t *buf() { return _buf; }
|
||||
using byte_view::data;
|
||||
uint8_t *data() const { return _buf; }
|
||||
|
||||
void swap(byte_data &o);
|
||||
rust::Vec<size_t> patch(byte_view from, byte_view to);
|
||||
rust::Vec<size_t> patch(byte_view from, byte_view to) const;
|
||||
};
|
||||
|
||||
struct heap_data : public byte_data {
|
||||
@@ -170,10 +128,7 @@ private:
|
||||
int fd;
|
||||
};
|
||||
|
||||
rust::Vec<size_t> mut_u8_patch(
|
||||
rust::Slice<uint8_t> buf,
|
||||
rust::Slice<const uint8_t> from,
|
||||
rust::Slice<const uint8_t> to);
|
||||
rust::Vec<size_t> mut_u8_patch(MutByteSlice buf, ByteSlice from, ByteSlice to);
|
||||
|
||||
uint32_t parse_uint32_hex(std::string_view s);
|
||||
int parse_int(std::string_view s);
|
||||
@@ -276,9 +231,7 @@ struct Utf8CStr {
|
||||
|
||||
Utf8CStr() : Utf8CStr("", 1) {};
|
||||
Utf8CStr(const Utf8CStr &o) = default;
|
||||
Utf8CStr(Utf8CStr &&o) = default;
|
||||
Utf8CStr(const char *s) : Utf8CStr(s, strlen(s) + 1) {};
|
||||
Utf8CStr(std::string_view s) : Utf8CStr(s.data(), s.length() + 1) {};
|
||||
Utf8CStr(std::string s) : Utf8CStr(s.data(), s.length() + 1) {};
|
||||
const char *c_str() const { return this->data(); }
|
||||
size_t size() const { return this->length(); }
|
||||
@@ -296,15 +249,17 @@ private:
|
||||
} // namespace rust
|
||||
|
||||
// Bindings for std::function to be callable from Rust
|
||||
struct FnBoolStrStr : public std::function<bool(rust::Str, rust::Str)> {
|
||||
using std::function<bool(rust::Str, rust::Str)>::function;
|
||||
|
||||
using CxxFnBoolStrStr = std::function<bool(rust::Str, rust::Str)>;
|
||||
struct FnBoolStrStr : public CxxFnBoolStrStr {
|
||||
using CxxFnBoolStrStr::function;
|
||||
bool call(rust::Str a, rust::Str b) const {
|
||||
return operator()(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
struct FnBoolString : public std::function<bool(rust::String&)> {
|
||||
using std::function<bool(rust::String&)>::function;
|
||||
using CxxFnBoolString = std::function<bool(rust::String&)>;
|
||||
struct FnBoolString : public CxxFnBoolString {
|
||||
using CxxFnBoolString::function;
|
||||
bool call(rust::String &s) const {
|
||||
return operator()(s);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ int xlisten(int sockfd, int backlog);
|
||||
int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
|
||||
int xstat(const char *pathname, struct stat *buf);
|
||||
int xfstat(int fd, struct stat *buf);
|
||||
int xdup(int fd);
|
||||
int xdup2(int oldfd, int newfd);
|
||||
ssize_t xreadlink(const char * __restrict__ pathname, char * __restrict__ buf, size_t bufsiz);
|
||||
ssize_t xreadlinkat(
|
||||
@@ -42,7 +41,6 @@ int xmkdir(const char *pathname, mode_t mode);
|
||||
int xmkdirs(const char *pathname, mode_t mode);
|
||||
ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count);
|
||||
pid_t xfork();
|
||||
int xpoll(pollfd *fds, nfds_t nfds, int timeout);
|
||||
ssize_t xrealpath(const char * __restrict__ path, char * __restrict__ buf, size_t bufsiz);
|
||||
int xmknod(const char * pathname, mode_t mode, dev_t dev);
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@ use crate::cxx_extern::readlinkat;
|
||||
use crate::{
|
||||
BorrowedDirectory, CxxResultExt, LibcReturn, Utf8CStr, cstr, slice_from_ptr, slice_from_ptr_mut,
|
||||
};
|
||||
use libc::{
|
||||
c_char, c_uint, c_ulong, c_void, dev_t, mode_t, nfds_t, off_t, pollfd, sockaddr, socklen_t,
|
||||
};
|
||||
use libc::{c_char, c_uint, c_ulong, c_void, dev_t, mode_t, off_t, sockaddr, socklen_t};
|
||||
use std::ffi::CStr;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
@@ -270,16 +268,6 @@ unsafe extern "C" fn xfstat(fd: RawFd, buf: *mut libc::stat) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn xdup(oldfd: RawFd) -> RawFd {
|
||||
unsafe {
|
||||
libc::dup(oldfd)
|
||||
.as_os_result("dup", None, None)
|
||||
.log_cxx()
|
||||
.unwrap_or(-1)
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn xdup2(oldfd: RawFd, newfd: RawFd) -> RawFd {
|
||||
unsafe {
|
||||
@@ -381,16 +369,6 @@ extern "C" fn xfork() -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn xpoll(fds: *mut pollfd, nfds: nfds_t, timeout: i32) -> i32 {
|
||||
unsafe {
|
||||
libc::poll(fds, nfds, timeout)
|
||||
.as_os_result("poll", None, None)
|
||||
.log_cxx()
|
||||
.unwrap_or(-1)
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn xmknod(pathname: *const c_char, mode: mode_t, dev: dev_t) -> i32 {
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user