Magisk/native/jni/utils/misc.hpp

119 lines
3.3 KiB
C++
Raw Normal View History

2019-07-02 07:58:19 +02:00
#pragma once
2019-12-13 06:37:06 +01:00
#include <pthread.h>
2019-07-02 07:58:19 +02:00
#include <string>
#include <functional>
#include <string_view>
2019-11-19 08:04:47 +01:00
#define UID_ROOT 0
#define UID_SHELL 2000
2019-09-26 05:55:39 +02:00
class mutex_guard {
2019-07-02 07:58:19 +02:00
public:
explicit mutex_guard(pthread_mutex_t &m): mutex(&m) {
pthread_mutex_lock(mutex);
}
2021-01-12 09:07:48 +01:00
void unlock() {
pthread_mutex_unlock(mutex);
mutex = nullptr;
}
~mutex_guard() {
2021-01-12 09:07:48 +01:00
if (mutex) pthread_mutex_unlock(mutex);
}
2019-07-02 07:58:19 +02:00
private:
pthread_mutex_t *mutex;
2019-07-02 07:58:19 +02:00
};
2020-04-30 10:27:36 +02:00
template <class Func>
2019-09-26 05:55:39 +02:00
class run_finally {
2019-07-02 07:58:19 +02:00
public:
explicit run_finally(const Func &fn) : fn(fn) {}
~run_finally() { fn(); }
2019-07-02 07:58:19 +02:00
private:
const Func &fn;
2019-07-02 07:58:19 +02:00
};
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);
}
2019-11-19 08:04:47 +01:00
int parse_int(const char *s);
2020-11-07 23:36:13 +01:00
static inline int parse_int(const std::string &s) { return parse_int(s.data()); }
2019-07-02 07:58:19 +02:00
static inline int parse_int(std::string_view s) { return parse_int(s.data()); }
2020-04-30 10:27:36 +02:00
using thread_entry = void *(*)(void *);
int new_daemon_thread(thread_entry entry, void *arg = nullptr);
int new_daemon_thread(void(*entry)());
2020-04-30 10:27:36 +02:00
int new_daemon_thread(std::function<void()> &&entry);
2019-07-02 07:58:19 +02:00
static inline bool str_contains(std::string_view s, std::string_view ss) {
return s.find(ss) != std::string::npos;
}
static inline bool str_starts(std::string_view s, std::string_view ss) {
return s.rfind(ss, 0) == 0;
}
static inline bool str_ends(std::string_view s, std::string_view ss) {
return s.size() >= ss.size() && s.compare(s.size() - ss.size(), std::string::npos, ss) == 0;
}
2020-11-07 23:36:13 +01:00
int fork_dont_care();
int fork_no_orphan();
2020-11-07 23:36:13 +01:00
void init_argv0(int argc, char **argv);
void set_nice_name(const char *name);
uint32_t binary_gcd(uint32_t u, uint32_t v);
int switch_mnt_ns(int pid);
int gen_rand_str(char *buf, int len, bool varlen = true);
std::string &replace_all(std::string &str, std::string_view from, std::string_view to);
2019-07-02 07:58:19 +02:00
struct exec_t {
bool err = false;
int fd = -2;
void (*pre_exec)() = nullptr;
int (*fork)() = xfork;
const char **argv = nullptr;
2019-07-02 07:58:19 +02:00
};
int exec_command(exec_t &exec);
template <class ...Args>
int exec_command(exec_t &exec, Args &&...args) {
const char *argv[] = {args..., nullptr};
exec.argv = argv;
return exec_command(exec);
2019-07-02 07:58:19 +02:00
}
int exec_command_sync(exec_t &exec);
template <class ...Args>
int exec_command_sync(exec_t &exec, Args &&...args) {
const char *argv[] = {args..., nullptr};
exec.argv = argv;
return exec_command_sync(exec);
2019-07-02 07:58:19 +02:00
}
template <class ...Args>
int exec_command_sync(Args &&...args) {
exec_t exec{};
return exec_command_sync(exec, args...);
2019-07-02 07:58:19 +02:00
}
2020-11-07 23:36:13 +01:00
template <class ...Args>
void exec_command_async(Args &&...args) {
const char *argv[] = {args..., nullptr};
exec_t exec {
.argv = argv,
.fork = fork_dont_care
};
exec_command(exec);
2020-11-07 23:36:13 +01:00
}