Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
3e4c12cf
Commit
3e4c12cf
authored
Jan 20, 2019
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate to STL
parent
03c39e69
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
226 additions
and
548 deletions
+226
-548
bootstages.cpp
native/jni/daemon/bootstages.cpp
+46
-39
log_daemon.cpp
native/jni/daemon/log_daemon.cpp
+7
-8
resetprop.h
native/jni/include/resetprop.h
+4
-5
cpio.cpp
native/jni/magiskboot/cpio.cpp
+24
-34
cpio.h
native/jni/magiskboot/cpio.h
+7
-8
ramdisk.cpp
native/jni/magiskboot/ramdisk.cpp
+15
-14
hide_utils.cpp
native/jni/magiskhide/hide_utils.cpp
+9
-8
magiskhide.h
native/jni/magiskhide/magiskhide.h
+3
-3
proc_monitor.cpp
native/jni/magiskhide/proc_monitor.cpp
+18
-15
magiskpolicy.cpp
native/jni/magiskpolicy/magiskpolicy.cpp
+14
-10
_resetprop.h
native/jni/resetprop/_resetprop.h
+12
-6
persist_properties.cpp
native/jni/resetprop/persist_properties.cpp
+15
-13
resetprop.cpp
native/jni/resetprop/resetprop.cpp
+25
-27
Android.mk
native/jni/utils/Android.mk
+1
-2
CharArray.cpp
native/jni/utils/CharArray.cpp
+0
-99
file.cpp
native/jni/utils/file.cpp
+9
-6
CharArray.h
native/jni/utils/include/CharArray.h
+0
-39
Vector.h
native/jni/utils/include/Vector.h
+0
-191
cpputils.h
native/jni/utils/include/cpputils.h
+0
-12
utils.h
native/jni/utils/include/utils.h
+9
-7
misc.cpp
native/jni/utils/misc.cpp
+4
-1
new.cpp
native/jni/utils/new.cpp
+3
-0
xwrap.cpp
native/jni/utils/xwrap.cpp
+1
-1
No files found.
native/jni/daemon/bootstages.cpp
View file @
3e4c12cf
...
...
@@ -13,6 +13,8 @@
#include <dirent.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <vector>
#include <string>
#include "magisk.h"
#include "db.h"
...
...
@@ -23,8 +25,10 @@
#include "selinux.h"
#include "flags.h"
using
namespace
std
;
static
char
buf
[
PATH_MAX
],
buf2
[
PATH_MAX
];
static
Vector
<
CharArray
>
module_list
;
static
vector
<
string
>
module_list
;
static
bool
seperate_vendor
;
char
*
system_block
,
*
vendor_block
,
*
magiskloop
;
...
...
@@ -42,9 +46,9 @@ extern void auto_start_magiskhide();
#define IS_SKEL 0x04
/* mount from skeleton */
#define IS_MODULE 0x08
/* mount from module */
#define IS_DIR(n) (
n
->type == DT_DIR)
#define IS_LNK(n) (
n
->type == DT_LNK)
#define IS_REG(n) (
n
->type == DT_REG)
#define IS_DIR(n) (
(n)
->type == DT_DIR)
#define IS_LNK(n) (
(n)
->type == DT_LNK)
#define IS_REG(n) (
(n)
->type == DT_REG)
class
node_entry
{
public
:
...
...
@@ -56,15 +60,15 @@ public:
private
:
const
char
*
module
;
/* Only used when status & IS_MODULE */
const
CharArray
name
;
const
string
name
;
uint8_t
type
;
uint8_t
status
;
node_entry
*
parent
;
V
ector
<
node_entry
*>
children
;
v
ector
<
node_entry
*>
children
;
node_entry
(
const
char
*
,
const
char
*
,
uint8_t
type
);
bool
is_root
();
CharArray
get_path
();
string
get_path
();
node_entry
*
insert
(
node_entry
*
);
void
clone_skeleton
();
int
get_path
(
char
*
path
);
...
...
@@ -87,7 +91,7 @@ bool node_entry::is_root() {
return
parent
==
nullptr
;
}
CharArray
node_entry
::
get_path
()
{
string
node_entry
::
get_path
()
{
get_path
(
buf
);
return
buf
;
}
...
...
@@ -123,7 +127,7 @@ void node_entry::create_module_tree(const char *module) {
DIR
*
dir
;
struct
dirent
*
entry
;
CharArray
full_path
=
get_path
();
auto
full_path
=
get_path
();
snprintf
(
buf
,
PATH_MAX
,
"%s/%s%s"
,
MOUNTPOINT
,
module
,
full_path
.
c_str
());
if
(
!
(
dir
=
xopendir
(
buf
)))
...
...
@@ -133,7 +137,7 @@ void node_entry::create_module_tree(const char *module) {
if
(
strcmp
(
entry
->
d_name
,
"."
)
==
0
||
strcmp
(
entry
->
d_name
,
".."
)
==
0
)
continue
;
// Create new node
node_entry
*
node
=
new
node_entry
(
module
,
entry
->
d_name
,
entry
->
d_type
);
auto
node
=
new
node_entry
(
module
,
entry
->
d_name
,
entry
->
d_type
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
full_path
.
c_str
(),
entry
->
d_name
);
/*
...
...
@@ -185,7 +189,7 @@ void node_entry::clone_skeleton() {
struct
node_entry
*
dummy
;
// Clone the structure
CharArray
full_path
=
get_path
();
auto
full_path
=
get_path
();
snprintf
(
buf
,
PATH_MAX
,
"%s%s"
,
MIRRDIR
,
full_path
.
c_str
());
if
(
!
(
dir
=
xopendir
(
buf
)))
return
;
...
...
@@ -200,10 +204,10 @@ void node_entry::clone_skeleton() {
if
(
status
&
IS_SKEL
)
{
file_attr
attr
;
getattr
(
full_path
,
&
attr
);
getattr
(
full_path
.
c_str
()
,
&
attr
);
LOGI
(
"mnt_tmpfs : %s
\n
"
,
full_path
.
c_str
());
xmount
(
"tmpfs"
,
full_path
,
"tmpfs"
,
0
,
nullptr
);
setattr
(
full_path
,
&
attr
);
xmount
(
"tmpfs"
,
full_path
.
c_str
()
,
"tmpfs"
,
0
,
nullptr
);
setattr
(
full_path
.
c_str
()
,
&
attr
);
}
for
(
auto
&
child
:
children
)
{
...
...
@@ -254,9 +258,9 @@ void node_entry::clone_skeleton() {
void
node_entry
::
magic_mount
()
{
if
(
status
&
IS_MODULE
)
{
// Mount module item
CharArray
real_path
=
get_path
();
auto
real_path
=
get_path
();
snprintf
(
buf
,
PATH_MAX
,
"%s/%s%s"
,
MOUNTPOINT
,
module
,
real_path
.
c_str
());
bind_mount
(
buf
,
real_path
);
bind_mount
(
buf
,
real_path
.
c_str
()
);
}
else
if
(
status
&
IS_SKEL
)
{
// The node is labeled to be cloned with skeleton, lets do it
clone_skeleton
();
...
...
@@ -330,7 +334,8 @@ static void exec_common_script(const char* stage) {
}
static
void
exec_module_script
(
const
char
*
stage
)
{
for
(
const
char
*
module
:
module_list
)
{
for
(
const
auto
&
m
:
module_list
)
{
const
auto
module
=
m
.
c_str
();
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s/%s.sh"
,
MOUNTPOINT
,
module
,
stage
);
if
(
access
(
buf2
,
F_OK
)
==
-
1
)
continue
;
...
...
@@ -364,7 +369,7 @@ static void simple_mount(const char *path) {
if
(
access
(
buf2
,
F_OK
)
==
-
1
)
continue
;
if
(
entry
->
d_type
==
DT_DIR
)
{
simple_mount
(
CharArray
(
buf2
));
simple_mount
(
string
(
buf2
).
c_str
(
));
}
else
if
(
entry
->
d_type
==
DT_REG
)
{
// Actual file path
snprintf
(
buf
,
PATH_MAX
,
"%s%s"
,
SIMPLEMOUNT
,
buf2
);
...
...
@@ -431,21 +436,20 @@ static bool magisk_env() {
xmkdir
(
SECURE_DIR
"/post-fs-data.d"
,
0755
);
xmkdir
(
SECURE_DIR
"/service.d"
,
0755
);
CharArray
sdk_prop
=
getprop
(
"ro.build.version.sdk"
);
int
sdk
=
sdk_prop
.
empty
()
?
-
1
:
atoi
(
sdk_prop
);
auto
sdk_prop
=
getprop
(
"ro.build.version.sdk"
);
int
sdk
=
sdk_prop
.
empty
()
?
-
1
:
atoi
(
sdk_prop
.
c_str
()
);
LOGI
(
"* Mounting mirrors"
);
Vector
<
CharArray
>
mounts
;
file_to_vector
(
"/proc/mounts"
,
mounts
);
auto
mounts
=
file_to_vector
(
"/proc/mounts"
);
bool
system_as_root
=
false
;
for
(
auto
&
line
:
mounts
)
{
if
(
line
.
contains
(
" /system_root "
)
)
{
if
(
line
.
find
(
" /system_root "
)
!=
string
::
npos
)
{
bind_mount
(
"/system_root/system"
,
MIRRDIR
"/system"
);
sscanf
(
line
,
"%s"
,
buf
);
sscanf
(
line
.
c_str
()
,
"%s"
,
buf
);
system_block
=
strdup2
(
buf
);
system_as_root
=
true
;
}
else
if
(
!
system_as_root
&&
line
.
contains
(
" /system "
)
)
{
sscanf
(
line
,
"%s %*s %s"
,
buf
,
buf2
);
}
else
if
(
!
system_as_root
&&
line
.
find
(
" /system "
)
!=
string
::
npos
)
{
sscanf
(
line
.
c_str
()
,
"%s %*s %s"
,
buf
,
buf2
);
system_block
=
strdup2
(
buf
);
xmount
(
system_block
,
MIRRDIR
"/system"
,
buf2
,
MS_RDONLY
,
nullptr
);
#ifdef MAGISK_DEBUG
...
...
@@ -453,9 +457,9 @@ static bool magisk_env() {
#else
LOGI
(
"mount: %s
\n
"
,
MIRRDIR
"/system"
);
#endif
}
else
if
(
line
.
contains
(
" /vendor "
)
)
{
}
else
if
(
line
.
find
(
" /vendor "
)
!=
string
::
npos
)
{
seperate_vendor
=
true
;
sscanf
(
line
,
"%s %*s %s"
,
buf
,
buf2
);
sscanf
(
line
.
c_str
()
,
"%s %*s %s"
,
buf
,
buf2
);
vendor_block
=
strdup2
(
buf
);
xmkdir
(
MIRRDIR
"/vendor"
,
0755
);
xmount
(
buf
,
MIRRDIR
"/vendor"
,
buf2
,
MS_RDONLY
,
nullptr
);
...
...
@@ -464,7 +468,9 @@ static bool magisk_env() {
#else
LOGI
(
"mount: %s
\n
"
,
MIRRDIR
"/vendor"
);
#endif
}
else
if
(
sdk
>=
24
&&
line
.
contains
(
" /proc "
)
&&
!
line
.
contains
(
"hidepid=2"
))
{
}
else
if
(
sdk
>=
24
&&
line
.
find
(
" /proc "
)
!=
string
::
npos
&&
line
.
find
(
"hidepid=2"
)
==
string
::
npos
)
{
// Enforce hidepid
xmount
(
nullptr
,
"/proc"
,
nullptr
,
MS_REMOUNT
,
"hidepid=2,gid=3009"
);
}
...
...
@@ -508,7 +514,7 @@ static void collect_modules() {
}
unlink
(
"update"
);
if
(
access
(
"disable"
,
F_OK
))
module_list
.
push
_back
(
entry
->
d_name
);
module_list
.
emplace
_back
(
entry
->
d_name
);
chdir
(
".."
);
}
}
...
...
@@ -559,7 +565,7 @@ static bool prepare_img() {
static
void
install_apk
(
const
char
*
apk
)
{
setfilecon
(
apk
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
while
(
1
)
{
while
(
true
)
{
sleep
(
5
);
LOGD
(
"apk_install: attempting to install APK
\n
"
);
int
fd
=
-
1
,
pid
;
...
...
@@ -586,14 +592,14 @@ static void install_apk(const char *apk) {
static
bool
check_data
()
{
bool
mnt
=
false
;
bool
data
=
false
;
Vector
<
CharArray
>
mounts
;
file_to_vector
(
"/proc/mounts"
,
mounts
);
auto
mounts
=
file_to_vector
(
"/proc/mounts"
);
for
(
auto
&
line
:
mounts
)
{
if
(
line
.
contains
(
" /data "
)
&&
!
line
.
contains
(
"tmpfs"
))
if
(
line
.
find
(
" /data "
)
!=
string
::
npos
&&
line
.
find
(
"tmpfs"
)
==
string
::
npos
)
mnt
=
true
;
}
if
(
mnt
)
{
CharArray
crypto
=
getprop
(
"ro.crypto.state"
);
auto
crypto
=
getprop
(
"ro.crypto.state"
);
if
(
!
crypto
.
empty
())
{
if
(
crypto
==
"unencrypted"
)
{
// Unencrypted, we can directly access data
...
...
@@ -811,11 +817,11 @@ void post_fs_data(int client) {
exec_module_script
(
"post-fs-data"
);
// Recollect modules
module_list
.
clear
(
true
);
module_list
.
clear
();
collect_modules
();
// Create the system root entry
node_entry
*
sys_root
=
new
node_entry
(
"system"
,
IS_INTER
);
auto
sys_root
=
new
node_entry
(
"system"
,
IS_INTER
);
// Vendor root entry
node_entry
*
ven_root
=
nullptr
;
...
...
@@ -823,7 +829,8 @@ void post_fs_data(int client) {
bool
has_modules
=
false
;
LOGI
(
"* Loading modules
\n
"
);
for
(
const
char
*
module
:
module_list
)
{
for
(
const
auto
&
m
:
module_list
)
{
const
auto
module
=
m
.
c_str
();
// Read props
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/system.prop"
,
MOUNTPOINT
,
module
);
if
(
access
(
buf
,
F_OK
)
==
0
)
{
...
...
@@ -911,7 +918,7 @@ core_only:
}
// All boot stage done, cleanup
module_list
.
clear
(
true
);
module_list
.
clear
();
}
void
boot_complete
(
int
client
)
{
...
...
native/jni/daemon/log_daemon.cpp
View file @
3e4c12cf
...
...
@@ -12,14 +12,17 @@
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <vector>
#include "magisk.h"
#include "utils.h"
#include "daemon.h"
#include "flags.h"
using
namespace
std
;
bool
log_daemon_started
=
false
;
static
V
ector
<
const
char
*>
log_cmd
,
clear_cmd
;
static
v
ector
<
const
char
*>
log_cmd
,
clear_cmd
;
static
pthread_mutex_t
lock
=
PTHREAD_MUTEX_INITIALIZER
;
enum
{
...
...
@@ -68,7 +71,7 @@ static void *monitor_thread(void *) {
sleep
(
5
);
int
fd
;
char
b
;
while
(
1
)
{
while
(
true
)
{
fd
=
connect_daemon
();
write_int
(
fd
,
HANDSHAKE
);
// This should hold unless the daemon is killed
...
...
@@ -136,11 +139,7 @@ static void log_daemon() {
}
chmod
(
"/dev/null"
,
0666
);
clear_cmd
=
log_cmd
;
log_cmd
.
push_back
(
"-v"
);
log_cmd
.
push_back
(
"threadtime"
);
log_cmd
.
push_back
(
"-s"
);
log_cmd
.
push_back
(
"am_proc_start"
);
log_cmd
.
push_back
(
"Magisk"
);
log_cmd
.
insert
(
log_cmd
.
end
(),
{
"-v"
,
"threadtime"
,
"-s"
,
"am_proc_start"
,
"Magisk"
});
#ifdef MAGISK_DEBUG
log_cmd
.
push_back
(
"*:F"
);
#endif
...
...
@@ -163,7 +162,7 @@ static void log_daemon() {
if
(
xbind
(
sockfd
,
(
struct
sockaddr
*
)
&
sun
,
len
))
exit
(
1
);
xlisten
(
sockfd
,
10
);
while
(
1
)
{
while
(
true
)
{
int
fd
=
xaccept4
(
sockfd
,
nullptr
,
nullptr
,
SOCK_CLOEXEC
);
switch
(
read_int
(
fd
))
{
case
HIDE_CONNECT
:
...
...
native/jni/include/resetprop.h
View file @
3e4c12cf
...
...
@@ -3,12 +3,11 @@
#pragma once
#include
"CharArray.h"
#include
<string>
int
prop_exist
(
const
char
*
name
);
int
setprop
(
const
char
*
name
,
const
char
*
value
,
const
bool
trigger
=
true
);
CharArray
getprop
(
const
char
*
name
,
bool
persist
=
false
);
int
setprop
(
const
char
*
name
,
const
char
*
value
,
bool
trigger
=
true
);
std
::
string
getprop
(
const
char
*
name
,
bool
persist
=
false
);
void
getprop
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
=
false
);
int
deleteprop
(
const
char
*
name
,
bool
persist
=
false
);
int
load_prop_file
(
const
char
*
filename
,
const
bool
trigger
=
true
);
int
load_prop_file
(
const
char
*
filename
,
bool
trigger
=
true
);
native/jni/magiskboot/cpio.cpp
View file @
3e4c12cf
...
...
@@ -2,11 +2,14 @@
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include "cpio.h"
#include "utils.h"
#include "logging.h"
using
namespace
std
;
#define parse_align() lseek(fd, align(lseek(fd, 0, SEEK_CUR), 4), SEEK_SET)
static
uint32_t
x8u
(
char
*
hex
)
{
...
...
@@ -40,8 +43,8 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
// rdevminor = x8u(header.rdevminor);
uint32_t
namesize
=
x8u
(
header
.
namesize
);
// check = x8u(header.check);
filename
=
CharArray
(
namesize
);
xxread
(
fd
,
filename
,
filename
.
size
()
);
filename
.
resize
(
namesize
-
1
);
xxread
(
fd
,
&
filename
[
0
],
namesize
);
parse_align
();
if
(
filesize
)
{
data
=
xmalloc
(
filesize
);
...
...
@@ -54,22 +57,13 @@ cpio_entry::~cpio_entry() {
free
(
data
);
}
// Define the way to sort cpio_entry
template
<>
int
(
*
Vector
<
cpio_entry
*>::
_cmp
)(
cpio_entry
*&
,
cpio_entry
*&
)
=
[](
auto
a
,
auto
b
)
->
int
{
if
(
a
==
b
)
return
0
;
if
(
a
==
nullptr
)
return
1
;
if
(
b
==
nullptr
)
return
-
1
;
return
a
->
filename
.
compare
(
b
->
filename
);
};
cpio
::
cpio
(
const
char
*
filename
)
{
int
fd
=
open
(
filename
,
O_RDONLY
);
if
(
fd
<
0
)
return
;
fprintf
(
stderr
,
"Loading cpio: [%s]
\n
"
,
filename
);
cpio_newc_header
header
;
cpio_entry
*
entry
;
int
i
=
0
;
while
(
xxread
(
fd
,
&
header
,
sizeof
(
cpio_newc_header
))
!=
-
1
)
{
entry
=
new
cpio_entry
(
fd
,
header
);
if
(
entry
->
filename
==
"."
||
entry
->
filename
==
".."
||
entry
->
filename
==
"TRAILER!!!"
)
{
...
...
@@ -86,7 +80,7 @@ cpio::cpio(const char *filename) {
cpio
::~
cpio
()
{
for
(
auto
&
e
:
arr
)
if
(
e
)
delete
e
;
delete
e
;
}
#define dump_align() write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR), 4))
...
...
@@ -109,11 +103,11 @@ void cpio::dump(const char *file) {
0
,
// e->devminor
0
,
// e->rdevmajor
0
,
// e->rdevminor
(
uint32_t
)
e
->
filename
.
size
(),
(
uint32_t
)
e
->
filename
.
size
()
+
1
,
0
// e->check
);
xwrite
(
fd
,
header
,
110
);
xwrite
(
fd
,
e
->
filename
,
e
->
filename
.
size
()
);
xwrite
(
fd
,
e
->
filename
.
c_str
(),
e
->
filename
.
size
()
+
1
);
dump_align
();
if
(
e
->
filesize
)
{
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
...
...
@@ -140,7 +134,7 @@ int cpio::find(const char *name) {
}
void
cpio
::
insert
(
cpio_entry
*
e
)
{
int
i
=
find
(
e
->
filename
);
int
i
=
find
(
e
->
filename
.
c_str
()
);
if
(
i
>=
0
)
{
delete
arr
[
i
];
arr
[
i
]
=
e
;
...
...
@@ -149,17 +143,12 @@ void cpio::insert(cpio_entry *e) {
}
}
void
cpio
::
insert
(
Vector
<
cpio_entry
*>
&
arr
)
{
for
(
auto
&
e
:
arr
)
insert
(
e
);
}
void
cpio
::
rm
(
const
char
*
name
,
bool
r
)
{
size_t
len
=
strlen
(
name
);
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
if
(
e
->
filename
.
compare
(
name
,
len
)
==
0
&&
if
(
e
->
filename
.
compare
(
0
,
len
,
name
)
==
0
&&
((
r
&&
e
->
filename
[
len
]
==
'/'
)
||
e
->
filename
[
len
]
==
'\0'
))
{
fprintf
(
stderr
,
"Remove [%s]
\n
"
,
e
->
filename
.
c_str
());
delete
e
;
...
...
@@ -171,17 +160,15 @@ void cpio::rm(const char *name, bool r) {
}
void
cpio
::
makedir
(
mode_t
mode
,
const
char
*
name
)
{
auto
e
=
new
cpio_entry
();
auto
e
=
new
cpio_entry
(
name
);
e
->
mode
=
S_IFDIR
|
mode
;
e
->
filename
=
name
;
insert
(
e
);
fprintf
(
stderr
,
"Create directory [%s] (%04o)
\n
"
,
name
,
mode
);
}
void
cpio
::
ln
(
const
char
*
target
,
const
char
*
name
)
{
auto
e
=
new
cpio_entry
();
auto
e
=
new
cpio_entry
(
name
);
e
->
mode
=
S_IFLNK
;
e
->
filename
=
name
;
e
->
filesize
=
strlen
(
target
);
e
->
data
=
strdup
(
target
);
insert
(
e
);
...
...
@@ -190,9 +177,8 @@ void cpio::ln(const char *target, const char *name) {
void
cpio
::
add
(
mode_t
mode
,
const
char
*
name
,
const
char
*
file
)
{
int
fd
=
xopen
(
file
,
O_RDONLY
);
auto
e
=
new
cpio_entry
();
auto
e
=
new
cpio_entry
(
name
);
e
->
mode
=
S_IFREG
|
mode
;
e
->
filename
=
name
;
e
->
filesize
=
lseek
(
fd
,
0
,
SEEK_END
);
lseek
(
fd
,
0
,
SEEK_SET
);
e
->
data
=
xmalloc
(
e
->
filesize
);
...
...
@@ -239,17 +225,15 @@ static void extract_entry(cpio_entry *e, const char *file) {
void
cpio
::
extract
()
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
extract_entry
(
e
,
e
->
filename
);
if
(
!
e
)
continue
;
extract_entry
(
e
,
e
->
filename
.
c_str
());
}
}
bool
cpio
::
extract
(
const
char
*
name
,
const
char
*
file
)
{
int
i
=
find
(
name
);
if
(
i
>
0
)
{
auto
e
=
arr
[
i
];
extract_entry
(
e
,
file
);
extract_entry
(
arr
[
i
],
file
);
return
true
;
}
fprintf
(
stderr
,
"Cannot find the file entry [%s]
\n
"
,
name
);
...
...
@@ -257,7 +241,13 @@ bool cpio::extract(const char *name, const char *file) {
}
void
cpio
::
sort
()
{
arr
.
sort
();
std
::
sort
(
arr
.
begin
(),
arr
.
end
(),
[]
(
auto
a
,
auto
b
)
->
bool
{
if
(
a
==
b
||
a
==
nullptr
)
return
false
;
if
(
b
==
nullptr
)
return
true
;
return
a
->
filename
.
compare
(
b
->
filename
)
<
0
;
});
while
(
arr
.
back
()
==
nullptr
)
arr
.
pop_back
();
}
native/jni/magiskboot/cpio.h
View file @
3e4c12cf
...
...
@@ -2,9 +2,8 @@
#define _CPIO_H_
#include <stdint.h>
#include "Vector.h"
#include "CharArray.h"
#include <vector>
#include <string>
struct
cpio_newc_header
{
char
magic
[
6
];
...
...
@@ -38,17 +37,18 @@ struct cpio_entry {
// uint32_t namesize;
// uint32_t check;
// char *filename = nullptr;
CharArray
filename
;
std
::
string
filename
;
void
*
data
=
nullptr
;
cpio_entry
()
{}
cpio_entry
()
=
default
;
explicit
cpio_entry
(
const
char
*
name
)
:
filename
(
name
)
{}
cpio_entry
(
int
fd
,
cpio_newc_header
&
header
);
~
cpio_entry
();
};
class
cpio
{
public
:
cpio
(
const
char
*
filename
);
explicit
cpio
(
const
char
*
filename
);
~
cpio
();
void
dump
(
const
char
*
file
);
int
find
(
const
char
*
name
);
...
...
@@ -57,14 +57,13 @@ public:
void
makedir
(
mode_t
mode
,
const
char
*
name
);
void
ln
(
const
char
*
target
,
const
char
*
name
);
void
add
(
mode_t
mode
,
const
char
*
name
,
const
char
*
file
);
void
insert
(
Vector
<
cpio_entry
*>
&
arr
);
bool
mv
(
const
char
*
from
,
const
char
*
to
);
void
extract
();
bool
extract
(
const
char
*
name
,
const
char
*
file
);
void
sort
();
protected
:
V
ector
<
cpio_entry
*>
arr
;
std
::
v
ector
<
cpio_entry
*>
arr
;
};
#endif
native/jni/magiskboot/ramdisk.cpp
View file @
3e4c12cf
...
...
@@ -6,9 +6,11 @@
#include "cpio.h"
#include "utils.h"
using
namespace
std
;
class
magisk_cpio
:
public
cpio
{
public
:
magisk_cpio
(
const
char
*
filename
)
:
cpio
(
filename
)
{}
explicit
magisk_cpio
(
const
char
*
filename
)
:
cpio
(
filename
)
{}
void
patch
(
bool
keepverity
,
bool
keepforceencrypt
);
int
test
();
char
*
sha1
();
...
...
@@ -23,8 +25,8 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
if
(
!
e
)
continue
;
bool
fstab
=
(
!
keepverity
||
!
keepforceencrypt
)
&&
!
e
->
filename
.
starts_with
(
".backup"
)
&&
e
->
filename
.
contains
(
"fstab"
)
&&
S_ISREG
(
e
->
mode
);
!
str_starts
(
e
->
filename
,
".backup"
)
&&
str_contains
(
e
->
filename
,
"fstab"
)
&&
S_ISREG
(
e
->
mode
);
if
(
!
keepverity
)
{
if
(
fstab
)
{
patch_verity
(
&
e
->
data
,
&
e
->
filesize
,
1
);
...
...
@@ -98,7 +100,7 @@ char *magisk_cpio::sha1() {
void
magisk_cpio
::
restore
()
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
if
(
e
->
filename
.
starts_with
(
".backup"
))
{
if
(
str_starts
(
e
->
filename
,
".backup"
))
{
if
(
e
->
filename
[
7
]
==
'\0'
)
continue
;
if
(
e
->
filename
[
8
]
==
'.'
)
{
if
(
strcmp
(
&
e
->
filename
[
8
],
".rmlist"
)
==
0
)
{
...
...
@@ -106,7 +108,7 @@ void magisk_cpio::restore() {
rm
((
char
*
)
e
->
data
+
pos
,
false
);
}
}
else
{
mv
(
e
->
filename
,
e
->
filename
+
8
);
mv
(
e
->
filename
.
c_str
(),
&
e
->
filename
[
8
]
);
}
}
}
...
...
@@ -120,17 +122,15 @@ void magisk_cpio::restore() {
}
void
magisk_cpio
::
backup
(
const
char
*
orig
)
{
V
ector
<
cpio_entry
*>
bak
;
v
ector
<
cpio_entry
*>
bak
;
cpio_entry
*
m
,
*
n
,
*
rem
;
char
buf
[
PATH_MAX
];
m
=
new
cpio_entry
();
m
->
filename
=
".backup"
;
m
=
new
cpio_entry
(
".backup"
);
m
->
mode
=
S_IFDIR
;
bak
.
push_back
(
m
);
rem
=
new
cpio_entry
();
rem
->
filename
=
".backup/.rmlist"
;
rem
=
new
cpio_entry
(
".backup/.rmlist"
);
rem
->
mode
=
S_IFREG
;
magisk_cpio
o
(
orig
);
...
...
@@ -176,7 +176,7 @@ void magisk_cpio::backup(const char *orig) {
// Something new in ramdisk, record in rem
++
j
;
rem
->
data
=
xrealloc
(
rem
->
data
,
rem
->
filesize
+
n
->
filename
.
size
());
memcpy
((
char
*
)
rem
->
data
+
rem
->
filesize
,
n
->
filename
,
n
->
filename
.
size
());
memcpy
((
char
*
)
rem
->
data
+
rem
->
filesize
,
n
->
filename
.
c_str
()
,
n
->
filename
.
size
());
rem
->
filesize
+=
n
->
filename
.
size
();
fprintf
(
stderr
,
"Record new entry: [%s] -> [.backup/.rmlist]
\n
"
,
n
->
filename
.
c_str
());
}
...
...
@@ -196,7 +196,8 @@ void magisk_cpio::backup(const char *orig) {
delete
rem
;
if
(
bak
.
size
()
>
1
)
insert
(
bak
);
for
(
auto
item
:
bak
)
insert
(
item
);
}
...
...
@@ -249,11 +250,11 @@ int cpio_commands(int argc, char *argv[]) {
return
0
;
}
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"mkdir"
)
==
0
)
{
cpio
.
makedir
(
strtoul
(
cmdv
[
1
],
NULL
,
8
),
cmdv
[
2
]);
cpio
.
makedir
(
strtoul
(
cmdv
[
1
],
nullptr
,
8
),
cmdv
[
2
]);
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"ln"
)
==
0
)
{
cpio
.
ln
(
cmdv
[
1
],
cmdv
[
2
]);
}
else
if
(
cmdc
==
4
&&
strcmp
(
cmdv
[
0
],
"add"
)
==
0
)
{
cpio
.
add
(
strtoul
(
cmdv
[
1
],
NULL
,
8
),
cmdv
[
2
],
cmdv
[
3
]);
cpio
.
add
(
strtoul
(
cmdv
[
1
],
nullptr
,
8
),
cmdv
[
2
],
cmdv
[
3
]);
}
else
{
return
1
;
}
...
...
native/jni/magiskhide/hide_utils.cpp
View file @
3e4c12cf
...
...
@@ -15,10 +15,12 @@
#include "daemon.h"
#include "db.h"
using
namespace
std
;
#define SAFETYNET_COMPONENT "com.google.android.gms/.droidguard.DroidGuardService"
#define SAFETYNET_PROCESS "com.google.android.gms.unstable"
Vector
<
CharArray
>
hide_list
;
vector
<
string
>
hide_list
;
pthread_mutex_t
list_lock
;
static
pthread_t
proc_monitor_thread
;
...
...
@@ -55,7 +57,7 @@ void hide_sensitive_props() {
// Hide all sensitive props
for
(
int
i
=
0
;
prop_key
[
i
];
++
i
)
{
CharArray
value
=
getprop
(
prop_key
[
i
]);
auto
value
=
getprop
(
prop_key
[
i
]);
if
(
!
value
.
empty
()
&&
value
!=
prop_value
[
i
])
setprop
(
prop_key
[
i
],
prop_value
[
i
],
false
);
}
...
...
@@ -118,7 +120,7 @@ static bool proc_name_match(int pid, const char *name) {
}
static
void
kill_proc_cb
(
int
pid
,
void
*
v
)
{
ps_arg
*
args
=
static_cast
<
ps_arg
*>
(
v
);
auto
args
=
static_cast
<
ps_arg
*>
(
v
);
if
(
proc_name_match
(
pid
,
args
->
name
))
kill
(
pid
,
SIGTERM
);
else
if
(
args
->
uid
>
0
)
{
...
...
@@ -183,7 +185,7 @@ int add_list(const char *proc) {
// Critical region
pthread_mutex_lock
(
&
list_lock
);
hide_list
.
push
_back
(
proc
);
hide_list
.
emplace
_back
(
proc
);
kill_process
(
proc
);
pthread_mutex_unlock
(
&
list_lock
);
...
...
@@ -247,10 +249,9 @@ bool init_list() {
// Migrate old hide list into database
if
(
access
(
LEGACY_LIST
,
R_OK
)
==
0
)
{
Vector
<
CharArray
>
tmp
;
file_to_vector
(
LEGACY_LIST
,
tmp
);
auto
tmp
=
file_to_vector
(
LEGACY_LIST
);
for
(
auto
&
s
:
tmp
)
add_list
(
s
);
add_list
(
s
.
c_str
()
);
unlink
(
LEGACY_LIST
);
}
...
...
@@ -307,7 +308,7 @@ int launch_magiskhide(int client) {
// Start monitoring
proc_monitor
();
error:
error:
hide_enabled
=
false
;
return
DAEMON_ERROR
;
}
...
...
native/jni/magiskhide/magiskhide.h
View file @
3e4c12cf
...
...
@@ -2,10 +2,10 @@
#define MAGISK_HIDE_H
#include <pthread.h>
#include <vector>
#include <string>
#include "daemon.h"
#include "Vector.h"
#include "CharArray.h"
#define TERM_THREAD SIGUSR1
...
...
@@ -30,7 +30,7 @@ bool init_list();
extern
bool
hide_enabled
;
extern
pthread_mutex_t
list_lock
;
extern
Vector
<
CharArray
>
hide_list
;
extern
std
::
vector
<
std
::
string
>
hide_list
;
enum
{
LAUNCH_MAGISKHIDE
,
...
...
native/jni/magiskhide/proc_monitor.cpp
View file @
3e4c12cf
...
...
@@ -15,19 +15,23 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <vector>
#include <string>
#include "magisk.h"
#include "daemon.h"
#include "utils.h"
#include "magiskhide.h"
using
namespace
std
;
static
int
sockfd
=
-
1
;
extern
char
*
system_block
,
*
vendor_block
,
*
magiskloop
;
// Workaround for the lack of pthread_cancel
static
void
term_thread
(
int
)
{
LOGD
(
"proc_monitor: running cleanup
\n
"
);
hide_list
.
clear
(
true
);
hide_list
.
clear
();
hide_enabled
=
false
;
close
(
sockfd
);
sockfd
=
-
1
;
...
...
@@ -64,7 +68,7 @@ static void hide_daemon(int pid) {
LOGD
(
"hide_daemon: handling pid=[%d]
\n
"
,
pid
);
char
buffer
[
4096
];
Vector
<
CharArray
>
mounts
;
vector
<
string
>
mounts
;
manage_selinux
();
clean_magisk_props
();
...
...
@@ -75,24 +79,24 @@ static void hide_daemon(int pid) {
snprintf
(
buffer
,
sizeof
(
buffer
),
"/proc/%d"
,
pid
);
chdir
(
buffer
);
file_to_vector
(
"mounts"
,
mounts
);
mounts
=
file_to_vector
(
"mounts"
);
// Unmount dummy skeletons and /sbin links
for
(
auto
&
s
:
mounts
)
{
if
(
s
.
contains
(
"tmpfs /system/"
)
||
s
.
contains
(
"tmpfs /vendor/"
)
||
s
.
contains
(
"tmpfs /sbin"
))
{
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
if
(
str_contains
(
s
,
"tmpfs /system/"
)
||
str_contains
(
s
,
"tmpfs /vendor/"
)
||
str_contains
(
s
,
"tmpfs /sbin"
))
{
sscanf
(
s
.
c_str
(),
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
}
}
mounts
.
clear
();
// Re-read mount infos
file_to_vector
(
"mounts"
,
mounts
);
mounts
=
file_to_vector
(
"mounts"
);
// Unmount everything under /system, /vendor, and loop mounts
for
(
auto
&
s
:
mounts
)
{
if
((
s
.
contains
(
" /system/"
)
||
s
.
contains
(
" /vendor/"
))
&&
(
s
.
contains
(
system_block
)
||
s
.
contains
(
vendor_block
)
||
s
.
contains
(
magiskloop
)))
{
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
if
((
s
tr_contains
(
s
,
" /system/"
)
||
str_contains
(
s
,
" /vendor/"
))
&&
(
s
tr_contains
(
s
,
system_block
)
||
str_contains
(
s
,
vendor_block
)
||
str_contains
(
s
,
magiskloop
)))
{
sscanf
(
s
.
c_str
()
,
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
}
}
...
...
@@ -108,13 +112,12 @@ void proc_monitor() {
sigset_t
block_set
;
sigemptyset
(
&
block_set
);
sigaddset
(
&
block_set
,
TERM_THREAD
);
pthread_sigmask
(
SIG_UNBLOCK
,
&
block_set
,
NULL
);
pthread_sigmask
(
SIG_UNBLOCK
,
&
block_set
,
nullptr
);
// Register the cancel signal
struct
sigaction
act
;
memset
(
&
act
,
0
,
sizeof
(
act
));
struct
sigaction
act
{};
act
.
sa_handler
=
term_thread
;
sigaction
(
TERM_THREAD
,
&
act
,
NULL
);
sigaction
(
TERM_THREAD
,
&
act
,
nullptr
);
if
(
access
(
"/proc/1/ns/mnt"
,
F_OK
)
!=
0
)
{
LOGE
(
"proc_monitor: Your kernel doesn't support mount namespace :(
\n
"
);
...
...
@@ -155,7 +158,7 @@ void proc_monitor() {
bool
hide
=
false
;
pthread_mutex_lock
(
&
list_lock
);
for
(
auto
&
s
:
hide_list
)
{
if
(
strncmp
(
cpnt
,
s
,
s
.
size
()
-
1
)
==
0
)
{
if
(
strncmp
(
cpnt
,
s
.
c_str
()
,
s
.
size
()
-
1
)
==
0
)
{
hide
=
true
;
break
;
}
...
...
native/jni/magiskpolicy/magiskpolicy.cpp
View file @
3e4c12cf
...
...
@@ -5,6 +5,8 @@
#include <stdio.h>
#include <limits.h>
#include <vector>
#include <string>
#include "sepolicy.h"
#include "magiskpolicy.h"
...
...
@@ -12,6 +14,8 @@
#include "utils.h"
#include "flags.h"
using
namespace
std
;
static
const
char
*
type_msg_1
=
"Type 1:
\n
"
"
\"
<rule_name> source_type target_type class perm_set
\"\n
"
...
...
@@ -101,7 +105,7 @@ static const char *type_msg_6 =
exit
(
1
);
}
static
int
parse_bracket
(
char
*
tok
,
char
*&
stmt
,
V
ector
<
const
char
*>
*
vec
)
{
static
int
parse_bracket
(
char
*
tok
,
char
*&
stmt
,
v
ector
<
const
char
*>
*
vec
)
{
if
(
tok
==
nullptr
||
tok
[
0
]
!=
'{'
)
{
// Not in a bracket
vec
->
push_back
(
tok
);
...
...
@@ -143,10 +147,10 @@ static int parse_pattern_1(int action, const char *action_str, char *stmt) {
int
state
=
0
;
char
*
cur
,
*
cls
;
V
ector
<
const
char
*>
source
,
target
,
permission
;
v
ector
<
const
char
*>
source
,
target
,
permission
;
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
V
ector
<
const
char
*>
*
vec
;
v
ector
<
const
char
*>
*
vec
;
switch
(
state
)
{
case
0
:
vec
=
&
source
;
...
...
@@ -200,10 +204,10 @@ static int parse_pattern_2(int action, const char *action_str, char *stmt) {
int
state
=
0
;
char
*
cur
,
*
range
;
V
ector
<
const
char
*>
source
,
target
,
classes
;
v
ector
<
const
char
*>
source
,
target
,
classes
;
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
V
ector
<
const
char
*>
*
vec
;
v
ector
<
const
char
*>
*
vec
;
switch
(
state
)
{
case
0
:
vec
=
&
source
;
...
...
@@ -216,7 +220,7 @@ static int parse_pattern_2(int action, const char *action_str, char *stmt) {
break
;
case
3
:
// Currently only support ioctl
if
(
strcmp
(
cur
,
"ioctl"
))
if
(
strcmp
(
cur
,
"ioctl"
)
!=
0
)
return
1
;
vec
=
nullptr
;
break
;
...
...
@@ -262,7 +266,7 @@ static int parse_pattern_3(int action, const char *action_str, char* stmt) {
}
char
*
cur
;
V
ector
<
const
char
*>
domains
;
v
ector
<
const
char
*>
domains
;
while
((
cur
=
strtok_r
(
nullptr
,
" {}"
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
domains
.
push_back
(
cur
);
...
...
@@ -291,10 +295,10 @@ static int parse_pattern_4(int action, const char *action_str, char *stmt) {
int
state
=
0
;
char
*
cur
;
V
ector
<
const
char
*>
classes
,
attribute
;
v
ector
<
const
char
*>
classes
,
attribute
;
while
((
cur
=
strtok_r
(
nullptr
,
" "
,
&
stmt
))
!=
nullptr
)
{
if
(
cur
[
0
]
==
'*'
)
cur
=
ALL
;
V
ector
<
const
char
*>
*
vec
;
v
ector
<
const
char
*>
*
vec
;
switch
(
state
)
{
case
0
:
vec
=
&
classes
;
...
...
@@ -409,7 +413,7 @@ static void parse_statement(char *statement) {
char
*
action
,
*
remain
;
// strtok will modify the origin string, duplicate the statement for error messages
CharArray
orig
(
statement
);
string
orig
(
statement
);
action
=
strtok_r
(
statement
,
" "
,
&
remain
);
if
(
remain
==
nullptr
)
remain
=
&
action
[
strlen
(
action
)];
...
...
native/jni/resetprop/_resetprop.h
View file @
3e4c12cf
...
...
@@ -5,15 +5,15 @@
#ifndef MAGISK_PROPS_H
#define MAGISK_PROPS_H
#include <
CharArray.h
>
#include <
string
>
#include "resetprop/private/system_properties.h"
#include "logging.h"
struct
prop_t
{
char
*
name
;
char
value
[
PROP_VALUE_MAX
];
prop_t
()
=
default
;
prop_t
(
const
char
*
name
)
{
prop_t
()
:
name
(
nullptr
)
{}
explicit
prop_t
(
const
char
*
name
)
{
this
->
name
=
strdup
(
name
);
value
[
0
]
=
'\0'
;
}
...
...
@@ -21,7 +21,13 @@ struct prop_t {
this
->
name
=
strdup
(
name
);
strcpy
(
this
->
value
,
value
);
}
prop_t
&
operator
=
(
prop_t
&&
prop
)
{
prop_t
(
prop_t
&&
prop
)
:
name
(
nullptr
)
{
operator
=
(
std
::
move
(
prop
));
}
bool
operator
<
(
const
prop_t
&
prop
)
const
{
return
strcmp
(
name
,
prop
.
name
)
<
0
;
}
prop_t
&
operator
=
(
prop_t
&&
prop
)
{
if
(
this
!=
&
prop
)
{
free
(
name
);
name
=
prop
.
name
;
...
...
@@ -38,7 +44,7 @@ struct prop_t {
struct
read_cb_t
{
void
(
*
cb
)(
const
char
*
,
const
char
*
,
void
*
);
void
*
arg
;
read_cb_t
(
void
(
*
cb
)(
const
char
*
,
const
char
*
,
void
*
)
=
nullptr
,
void
*
arg
=
nullptr
)
explicit
read_cb_t
(
void
(
*
cb
)(
const
char
*
,
const
char
*
,
void
*
)
=
nullptr
,
void
*
arg
=
nullptr
)
:
cb
(
cb
),
arg
(
arg
)
{}
void
exec
(
const
char
*
name
,
const
char
*
value
)
{
cb
(
name
,
value
,
arg
);
...
...
@@ -49,7 +55,7 @@ struct read_cb_t {
extern
bool
use_pb
;
CharArray
persist_getprop
(
const
char
*
name
);
std
::
string
persist_getprop
(
const
char
*
name
);
void
persist_getprop
(
read_cb_t
*
read_cb
);
bool
persist_deleteprop
(
const
char
*
name
);
void
collect_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
);
...
...
native/jni/resetprop/persist_properties.cpp
View file @
3e4c12cf
...
...
@@ -5,6 +5,8 @@
#include <unistd.h>
#include <sys/mman.h>
#include <vector>
#include <pb.h>
#include <pb_decode.h>
#include <pb_encode.h>
...
...
@@ -12,6 +14,8 @@
#include "_resetprop.h"
#include "utils.h"
using
namespace
std
;
/* ***********************************************************************
* Auto generated header and constant definitions compiled from
* android/platform/system/core/master/init/persistent_properties.proto
...
...
@@ -113,7 +117,7 @@ static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * co
PersistentProperties_PersistentPropertyRecord
prop
=
{};
prop
.
name
.
funcs
.
encode
=
name_encode
;
prop
.
has_value
=
true
;
Vector
<
prop_t
>
&
prop_list
=
*
(
V
ector
<
prop_t
>
*
)
*
arg
;
auto
&
prop_list
=
*
(
v
ector
<
prop_t
>
*
)
*
arg
;
for
(
auto
&
p
:
prop_list
)
{
if
(
!
pb_encode_tag_for_field
(
stream
,
field
))
return
false
;
...
...
@@ -160,16 +164,16 @@ static void pb_getprop(read_cb_t *read_cb) {
munmap
(
buf
,
size
);
}
static
void
file_getprop
(
const
char
*
name
,
char
*
value
)
{
value
[
0
]
=
'\0'
;
static
bool
file_getprop
(
const
char
*
name
,
char
*
value
)
{
char
path
[
PATH_MAX
];
snprintf
(
path
,
sizeof
(
path
),
PERSISTENT_PROPERTY_DIR
"/%s"
,
name
);
int
fd
=
open
(
path
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
return
;
return
false
;
LOGD
(
"resetprop: read prop from [%s]
\n
"
,
path
);
value
[
read
(
fd
,
value
,
sizeof
(
PROP_VALUE_MAX
)
)]
=
'\0'
;
// Null terminate the read value
value
[
read
(
fd
,
value
,
PROP_VALUE_MAX
)]
=
'\0'
;
// Null terminate the read value
close
(
fd
);
return
value
[
0
]
!=
'\0'
;
}
void
persist_getprop
(
read_cb_t
*
read_cb
)
{
...
...
@@ -182,14 +186,13 @@ void persist_getprop(read_cb_t *read_cb) {
if
(
strcmp
(
entry
->
d_name
,
"."
)
==
0
||
strcmp
(
entry
->
d_name
,
".."
)
==
0
)
continue
;
char
value
[
PROP_VALUE_MAX
];
file_getprop
(
entry
->
d_name
,
value
);
if
(
value
[
0
])
if
(
file_getprop
(
entry
->
d_name
,
value
))
read_cb
->
exec
(
entry
->
d_name
,
value
);
}
}
}
CharArray
persist_getprop
(
const
char
*
name
)
{
string
persist_getprop
(
const
char
*
name
)
{
prop_t
prop
(
name
);
if
(
use_pb
)
{
read_cb_t
read_cb
(
pb_getprop_cb
,
&
prop
);
...
...
@@ -199,21 +202,20 @@ CharArray persist_getprop(const char *name) {
}
else
{
// Try to read from file
char
value
[
PROP_VALUE_MAX
];
file_getprop
(
name
,
value
);
if
(
value
[
0
])
if
(
file_getprop
(
name
,
value
))
return
value
;
}
return
CharArray
();
return
string
();
}
bool
persist_deleteprop
(
const
char
*
name
)
{
if
(
use_pb
)
{
V
ector
<
prop_t
>
prop_list
;
v
ector
<
prop_t
>
prop_list
;
read_cb_t
read_cb
(
collect_props
,
&
prop_list
);
persist_getprop
(
&
read_cb
);
for
(
auto
it
=
prop_list
.
begin
();
it
!=
prop_list
.
end
();
++
it
)
{
if
(
strcmp
(
(
*
it
).
name
,
name
)
==
0
)
{
if
(
strcmp
(
it
->
name
,
name
)
==
0
)
{
prop_list
.
erase
(
it
);
// Dump the props back
PersistentProperties
props
=
PersistentProperties_init_zero
;
...
...
native/jni/resetprop/resetprop.cpp
View file @
3e4c12cf
...
...
@@ -6,6 +6,8 @@
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <vector>
#include <algorithm>
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include "private/_system_properties.h"
...
...
@@ -17,6 +19,8 @@
#include "utils.h"
#include "flags.h"
using
namespace
std
;
bool
use_pb
=
false
;
static
bool
verbose
=
false
;
...
...
@@ -74,12 +78,6 @@ illegal:
exit
(
1
);
}
// Define the way to sort prop_t
template
<>
int
(
*
Vector
<
prop_t
>::
_cmp
)(
prop_t
&
,
prop_t
&
)
=
[](
auto
a
,
auto
b
)
->
int
{
return
strcmp
(
a
.
name
,
b
.
name
);
};
static
void
read_props
(
const
prop_info
*
pi
,
void
*
read_cb
)
{
__system_property_read_callback
(
pi
,
[](
auto
cb
,
auto
name
,
auto
value
,
auto
)
->
void
...
...
@@ -89,12 +87,12 @@ static void read_props(const prop_info *pi, void *read_cb) {
}
void
collect_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
)
{
Vector
<
prop_t
>
&
prop_list
=
*
static_cast
<
V
ector
<
prop_t
>
*>
(
v_plist
);
prop_list
.
push_back
(
prop_t
(
name
,
value
)
);
auto
&
prop_list
=
*
static_cast
<
v
ector
<
prop_t
>
*>
(
v_plist
);
prop_list
.
emplace_back
(
name
,
value
);
}
static
void
collect_unique_props
(
const
char
*
name
,
const
char
*
value
,
void
*
v_plist
)
{
Vector
<
prop_t
>
&
prop_list
=
*
static_cast
<
V
ector
<
prop_t
>
*>
(
v_plist
);
auto
&
prop_list
=
*
static_cast
<
v
ector
<
prop_t
>
*>
(
v_plist
);
for
(
auto
&
prop
:
prop_list
)
{
if
(
strcmp
(
name
,
prop
.
name
)
==
0
)
return
;
...
...
@@ -112,9 +110,9 @@ static int init_resetprop() {
}
static
void
print_props
(
bool
persist
)
{
V
ector
<
prop_t
>
prop_list
;
v
ector
<
prop_t
>
prop_list
;
getprop
(
collect_props
,
&
prop_list
,
persist
);
prop_list
.
sort
(
);
sort
(
prop_list
.
begin
(),
prop_list
.
end
()
);
for
(
auto
&
prop
:
prop_list
)
printf
(
"[%s]: [%s]
\n
"
,
prop
.
name
,
prop
.
value
);
}
...
...
@@ -128,19 +126,19 @@ int prop_exist(const char *name) {
return
__system_property_find
(
name
)
!=
nullptr
;
}
// Get prop by name, return string
(should free manually!)
CharArray
getprop
(
const
char
*
name
,
bool
persist
)
{
// Get prop by name, return string
string
getprop
(
const
char
*
name
,
bool
persist
)
{
if
(
!
check_legal_property_name
(
name
)
||
init_resetprop
())
return
nullptr
;
const
prop_info
*
pi
=
__system_property_find
(
name
);
if
(
pi
==
nullptr
)
{
if
(
persist
&&
strncmp
(
name
,
"persist."
,
8
)
==
0
)
{
CharArray
value
=
persist_getprop
(
name
);
if
(
!
value
.
empty
())
return
value
;
auto
value
=
persist_getprop
(
name
);
if
(
value
.
empty
())
LOGD
(
"resetprop: prop [%s] does not exist
\n
"
,
name
);
return
value
;
}
LOGD
(
"resetprop: prop [%s] does not exist
\n
"
,
name
);
return
CharArray
();
return
string
();
}
else
{
char
value
[
PROP_VALUE_MAX
];
read_cb_t
read_cb
;
...
...
@@ -162,7 +160,7 @@ void getprop(void (*callback)(const char *, const char *, void *), void *cookie,
}
}
int
setprop
(
const
char
*
name
,
const
char
*
value
,
const
bool
trigger
)
{
int
setprop
(
const
char
*
name
,
const
char
*
value
,
bool
trigger
)
{
if
(
!
check_legal_property_name
(
name
))
return
1
;
if
(
init_resetprop
())
...
...
@@ -170,7 +168,7 @@ int setprop(const char *name, const char *value, const bool trigger) {
int
ret
;
prop_info
*
pi
=
(
prop_info
*
)
__system_property_find
(
name
);
auto
pi
=
(
prop_info
*
)
__system_property_find
(
name
);
if
(
pi
!=
nullptr
)
{
if
(
trigger
)
{
if
(
strncmp
(
name
,
"ro."
,
3
)
==
0
)
deleteprop
(
name
);
...
...
@@ -208,7 +206,7 @@ int deleteprop(const char *name, bool persist) {
return
__system_property_del
(
name
)
&&
!
(
persist
&&
strncmp
(
name
,
"persist."
,
8
)
==
0
);
}
int
load_prop_file
(
const
char
*
filename
,
const
bool
trigger
)
{
int
load_prop_file
(
const
char
*
filename
,
bool
trigger
)
{
if
(
init_resetprop
())
return
-
1
;
LOGD
(
"resetprop: Load prop file [%s]
\n
"
,
filename
);
FILE
*
fp
=
xfopen
(
filename
,
"re"
);
...
...
@@ -254,14 +252,14 @@ int resetprop_main(int argc, char *argv[]) {
bool
trigger
=
true
,
persist
=
false
;
char
*
argv0
=
argv
[
0
];
CharArray
prop
;
string
prop
;
--
argc
;
++
argv
;
// Parse flags and -- options
while
(
argc
&&
argv
[
0
][
0
]
==
'-'
)
{
for
(
int
idx
=
1
;
1
;
++
idx
)
{
for
(
int
idx
=
1
;
true
;
++
idx
)
{
switch
(
argv
[
0
][
idx
])
{
case
'-'
:
if
(
strcmp
(
argv
[
0
],
"--file"
)
==
0
&&
argc
==
2
)
{
...
...
@@ -275,10 +273,10 @@ int resetprop_main(int argc, char *argv[]) {
verbose
=
true
;
continue
;
case
'p'
:
persist
=
1
;
persist
=
true
;
continue
;
case
'n'
:
trigger
=
0
;
trigger
=
false
;
continue
;
case
'\0'
:
break
;
...
...
@@ -297,8 +295,8 @@ int resetprop_main(int argc, char *argv[]) {
print_props
(
persist
);
return
0
;
case
1
:
prop
=
utils
::
move
(
getprop
(
argv
[
0
],
persist
)
);
if
(
!
prop
)
return
1
;
prop
=
getprop
(
argv
[
0
],
persist
);
if
(
prop
.
empty
()
)
return
1
;
printf
(
"%s
\n
"
,
prop
.
c_str
());
return
0
;
case
2
:
...
...
native/jni/utils/Android.mk
View file @
3e4c12cf
...
...
@@ -9,7 +9,6 @@ LOCAL_SRC_FILES := \
misc.cpp \
selinux.cpp \
logging.cpp \
xwrap.cpp \
CharArray.cpp
xwrap.cpp
include $(BUILD_STATIC_LIBRARY)
native/jni/utils/CharArray.cpp
deleted
100644 → 0
View file @
03c39e69
#include "CharArray.h"
#include "utils.h"
CharArray
::
CharArray
()
:
_buf
(
nullptr
),
_size
(
0
){}
CharArray
::
CharArray
(
const
char
*
s
)
:
CharArray
()
{
this
->
operator
=
(
s
);
}
CharArray
::
CharArray
(
const
CharArray
&
s
)
:
CharArray
()
{
this
->
operator
=
(
s
);
}
CharArray
::
CharArray
(
size_t
i
)
{
_size
=
i
;
_buf
=
new
char
[
i
]();
/* Zero initialize */
}
CharArray
::~
CharArray
()
{
delete
[]
_buf
;
}
CharArray
::
operator
char
*
()
{
return
_buf
;
}
CharArray
::
operator
const
char
*
()
const
{
return
_buf
;
}
const
char
*
CharArray
::
c_str
()
const
{
return
_buf
;
}
size_t
CharArray
::
length
()
const
{
return
strlen
(
_buf
);
}
size_t
CharArray
::
size
()
const
{
return
_size
;
}
CharArray
&
CharArray
::
operator
=
(
const
CharArray
&
s
)
{
delete
[]
_buf
;
_size
=
s
.
_size
;
_buf
=
new
char
[
_size
];
memcpy
(
_buf
,
s
.
_buf
,
_size
);
return
*
this
;
}
CharArray
&
CharArray
::
operator
=
(
const
char
*
s
)
{
delete
[]
_buf
;
_buf
=
strdup2
(
s
,
&
_size
);
return
*
this
;
}
CharArray
&
CharArray
::
operator
=
(
CharArray
&&
s
)
{
delete
[]
_buf
;
_size
=
s
.
_size
;
_buf
=
s
.
_buf
;
s
.
_buf
=
nullptr
;
s
.
_size
=
0
;
return
*
this
;
}
bool
CharArray
::
operator
==
(
const
char
*
s
)
const
{
if
(
_buf
==
nullptr
||
s
==
nullptr
)
return
false
;
return
strcmp
(
_buf
,
s
)
==
0
;
}
bool
CharArray
::
operator
==
(
char
*
s
)
const
{
return
*
this
==
(
const
char
*
)
s
;
}
bool
CharArray
::
operator
!=
(
const
char
*
s
)
const
{
return
!
(
*
this
==
s
);
}
int
CharArray
::
compare
(
const
char
*
s
)
const
{
return
strcmp
(
_buf
,
s
);
}
int
CharArray
::
compare
(
const
char
*
s
,
size_t
len
)
const
{
return
strncmp
(
_buf
,
s
,
len
);
}
bool
CharArray
::
contains
(
const
char
*
s
)
const
{
return
s
==
nullptr
?
false
:
strstr
(
_buf
,
s
)
!=
nullptr
;
}
bool
CharArray
::
starts_with
(
const
char
*
s
)
const
{
return
s
==
nullptr
?
false
:
compare
(
s
,
strlen
(
s
))
==
0
;
}
bool
CharArray
::
empty
()
const
{
return
_buf
==
nullptr
||
_buf
[
0
]
==
'\0'
;
}
native/jni/utils/file.cpp
View file @
3e4c12cf
...
...
@@ -15,6 +15,8 @@
#include "utils.h"
#include "selinux.h"
using
namespace
std
;
const
char
**
excl_list
=
nullptr
;
static
int
is_excl
(
const
char
*
name
)
{
...
...
@@ -307,7 +309,7 @@ void clone_attr(const char *source, const char *target) {
setattr
(
target
,
&
a
);
}
void
fclone_attr
(
const
int
sourcefd
,
const
int
targetfd
)
{
void
fclone_attr
(
int
sourcefd
,
int
targetfd
)
{
struct
file_attr
a
;
fgetattr
(
sourcefd
,
&
a
);
fsetattr
(
targetfd
,
&
a
);
...
...
@@ -388,24 +390,25 @@ void write_zero(int fd, size_t size) {
lseek
(
fd
,
pos
+
size
,
SEEK_SET
);
}
int
file_to_vector
(
const
char
*
filename
,
Vector
<
CharArray
>
&
arr
)
{
vector
<
string
>
file_to_vector
(
const
char
*
filename
)
{
auto
arr
=
vector
<
string
>
();
if
(
access
(
filename
,
R_OK
)
!=
0
)
return
1
;
return
arr
;
char
*
line
=
nullptr
;
size_t
len
=
0
;
ssize_t
read
;
FILE
*
fp
=
xfopen
(
filename
,
"re"
);
if
(
fp
==
nullptr
)
return
1
;
return
arr
;
while
((
read
=
getline
(
&
line
,
&
len
,
fp
))
!=
-
1
)
{
// Remove end newline
if
(
line
[
read
-
1
]
==
'\n'
)
line
[
read
-
1
]
=
'\0'
;
arr
.
push
_back
(
line
);
arr
.
emplace
_back
(
line
);
}
fclose
(
fp
);
free
(
line
);
return
0
;
return
arr
;
}
native/jni/utils/include/CharArray.h
deleted
100644 → 0
View file @
03c39e69
#pragma once
#include <string.h>
/* A wrapper around char array */
class
CharArray
{
public
:
CharArray
();
CharArray
(
const
char
*
s
);
CharArray
(
const
CharArray
&
s
);
CharArray
(
size_t
i
);
~
CharArray
();
CharArray
&
operator
=
(
const
CharArray
&
s
);
CharArray
&
operator
=
(
CharArray
&&
s
);
CharArray
&
operator
=
(
const
char
*
s
);
operator
char
*
();
operator
const
char
*
()
const
;
bool
operator
==
(
char
*
s
)
const
;
bool
operator
==
(
const
char
*
s
)
const
;
bool
operator
!=
(
const
char
*
s
)
const
;
int
compare
(
const
char
*
s
)
const
;
int
compare
(
const
char
*
s
,
size_t
len
)
const
;
bool
starts_with
(
const
char
*
s
)
const
;
bool
contains
(
const
char
*
s
)
const
;
bool
empty
()
const
;
const
char
*
c_str
()
const
;
size_t
length
()
const
;
size_t
size
()
const
;
/* These 2 ops are incompatible with implicit char* conversion */
// char &operator[](size_t i);
// const char &operator[](size_t i) const;
private
:
char
*
_buf
;
size_t
_size
;
};
native/jni/utils/include/Vector.h
deleted
100644 → 0
View file @
03c39e69
#pragma once
#include <stdlib.h>
#include "cpputils.h"
template
<
class
T
>
class
Vector
{
public
:
Vector
()
:
_data
(
0
),
_size
(
0
),
_capacity
(
0
)
{}
~
Vector
()
{
delete
[]
_data
;
}
class
iterator
{
friend
class
Vector
;
public
:
iterator
(
T
*
n
=
0
)
:
_node
(
n
)
{}
iterator
(
const
iterator
&
i
)
:
_node
(
i
.
_node
)
{}
~
iterator
()
{}
// Should NOT delete _node
const
T
&
operator
*
()
const
{
return
(
*
_node
);
}
T
&
operator
*
()
{
return
(
*
_node
);
}
iterator
&
operator
++
()
{
++
_node
;
return
(
*
this
);
}
iterator
operator
++
(
int
)
{
iterator
temp
=
*
this
;
++
_node
;
return
temp
;
}
iterator
&
operator
--
()
{
--
_node
;
return
(
*
this
);
}
iterator
operator
--
(
int
)
{
iterator
temp
=
*
this
;
--
_node
;
return
temp
;
}
iterator
operator
+
(
int
i
)
const
{
iterator
temp
=
*
this
;
temp
+=
i
;
return
temp
;
}
iterator
&
operator
+=
(
int
i
)
{
_node
+=
i
;
return
(
*
this
);
}
iterator
&
operator
=
(
const
iterator
&
i
)
{
_node
=
i
.
_node
;
return
(
*
this
);
}
bool
operator
!=
(
const
iterator
&
i
)
const
{
return
_node
!=
i
.
_node
;
}
bool
operator
==
(
const
iterator
&
i
)
const
{
return
!
(
*
this
!=
i
);
}
private
:
T
*
_node
;
};
Vector
&
operator
=
(
const
Vector
&
a
)
{
delete
[]
_data
;
_data
=
nullptr
;
_size
=
a
.
_size
;
_capacity
=
a
.
_capacity
;
if
(
_capacity
)
{
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
a
[
i
];
}
return
*
this
;
}
Vector
&
operator
=
(
Vector
&&
a
)
{
delete
[]
_data
;
_size
=
a
.
_size
;
_capacity
=
a
.
_capacity
;
_data
=
a
.
_data
;
a
.
_size
=
0
;
a
.
_capacity
=
0
;
a
.
_data
=
nullptr
;
return
*
this
;
}
iterator
begin
()
const
{
return
iterator
(
_data
);
}
iterator
end
()
const
{
return
iterator
(
_data
+
_size
);
}
bool
empty
()
const
{
return
!
_size
;
}
size_t
size
()
const
{
return
_size
;
}
T
&
operator
[]
(
size_t
i
)
{
return
_data
[
i
];
}
const
T
&
operator
[]
(
size_t
i
)
const
{
return
_data
[
i
];
}
const
T
&
back
()
const
{
return
_data
[
_size
-
1
];
}
void
push_back
(
const
T
&
x
)
{
if
(
_size
==
_capacity
)
expand
();
_data
[
_size
]
=
x
;
++
_size
;
}
void
push_back
(
T
&&
x
)
{
if
(
_size
==
_capacity
)
expand
();
_data
[
_size
]
=
utils
::
move
(
x
);
++
_size
;
}
void
pop_front
()
{
erase
(
begin
());
}
void
pop_back
()
{
if
(
_size
)
--
_size
;
}
bool
erase
(
iterator
pos
)
{
T
*
d
=
pos
.
_node
;
if
(
_size
==
0
||
d
<
_data
||
d
>=
_data
+
_size
)
return
false
;
for
(;
d
<
_data
+
_size
-
1
;
++
d
)
*
d
=
utils
::
move
(
*
(
d
+
1
));
--
_size
;
return
true
;
}
bool
erase
(
const
T
&
x
)
{
for
(
T
*
i
=
_data
;
i
<
_data
+
_size
;
++
i
)
{
if
(
*
i
==
x
)
{
erase
(
iterator
(
i
));
return
true
;
}
}
return
false
;
}
void
clear
(
bool
dealloc
=
false
)
{
_size
=
0
;
if
(
dealloc
)
{
_capacity
=
0
;
delete
[]
_data
;
_data
=
nullptr
;
}
}
void
sort
()
{
qsort
(
_data
,
_size
,
sizeof
(
T
),
compare
);
}
T
*
data
()
{
return
_data
;
}
const
T
*
data
()
const
{
return
_data
;
}
// void reserve(size_t n) { ... }
// void resize(size_t n) { ... }
private
:
T
*
_data
;
size_t
_size
;
// number of valid elements
size_t
_capacity
;
// max number of elements
static
int
(
*
_cmp
)(
T
&
,
T
&
);
static
int
compare
(
const
void
*
a
,
const
void
*
b
)
{
return
_cmp
?
_cmp
(
*
((
T
*
)
a
),
*
((
T
*
)
b
))
:
0
;
}
void
expand
()
{
if
(
_capacity
==
0
)
_capacity
=
1
;
else
_capacity
*=
2
;
T
*
temp
=
_data
;
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
utils
::
move
(
temp
[
i
]);
delete
[]
temp
;
}
};
template
<
class
T
>
int
(
*
Vector
<
T
>::
_cmp
)(
T
&
,
T
&
)
=
nullptr
;
native/jni/utils/include/cpputils.h
deleted
100644 → 0
View file @
03c39e69
#pragma once
namespace
utils
{
template
<
class
T
>
struct
remove_reference
{
typedef
T
type
;};
template
<
class
T
>
struct
remove_reference
<
T
&>
{
typedef
T
type
;};
template
<
class
T
>
struct
remove_reference
<
T
&&>
{
typedef
T
type
;};
template
<
class
T
>
constexpr
typename
remove_reference
<
T
>::
type
&&
move
(
T
&&
t
)
noexcept
{
return
static_cast
<
typename
remove_reference
<
T
>::
type
&&>
(
t
);
}
}
\ No newline at end of file
native/jni/utils/include/utils.h
View file @
3e4c12cf
...
...
@@ -13,15 +13,17 @@
#ifdef __cplusplus
#include "Vector.h"
#include "CharArray.h"
#include "cpputils.h"
#include <string>
#include <vector>
int
file_to_vector
(
const
char
*
filename
,
Vector
<
CharArray
>
&
arr
);
#define str_contains(s, ss) ((s).find(ss) != string::npos)
#define str_starts(s, ss) ((s).compare(0, strlen(ss), ss) == 0)
std
::
vector
<
std
::
string
>
file_to_vector
(
const
char
*
filename
);
char
*
strdup2
(
const
char
*
s
,
size_t
*
size
=
nullptr
);
int
exec_array
(
bool
err
,
int
*
fd
,
void
(
*
pre_exec
)(
void
),
const
char
**
argv
);
int
exec_command
(
bool
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
const
char
*
argv0
,
...);
int
exec_array
(
bool
err
,
int
*
fd
,
void
(
*
pre_exec
)(),
const
char
**
argv
);
int
exec_command
(
bool
err
,
int
*
fd
,
void
(
*
cb
)(),
const
char
*
argv0
,
...);
extern
"C"
{
#endif
...
...
@@ -134,7 +136,7 @@ int fgetattr(int fd, struct file_attr *a);
int
setattr
(
const
char
*
path
,
struct
file_attr
*
a
);
int
setattrat
(
int
dirfd
,
const
char
*
pathname
,
struct
file_attr
*
a
);
int
fsetattr
(
int
fd
,
struct
file_attr
*
a
);
void
fclone_attr
(
const
int
sourcefd
,
const
int
targetfd
);
void
fclone_attr
(
int
sourcefd
,
int
targetfd
);
void
clone_attr
(
const
char
*
source
,
const
char
*
target
);
void
mmap_ro
(
const
char
*
filename
,
void
**
buf
,
size_t
*
size
);
void
mmap_rw
(
const
char
*
filename
,
void
**
buf
,
size_t
*
size
);
...
...
native/jni/utils/misc.cpp
View file @
3e4c12cf
...
...
@@ -11,10 +11,13 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/sysmacros.h>
#include <vector>
#include "logging.h"
#include "utils.h"
using
namespace
std
;
unsigned
get_shell_uid
()
{
struct
passwd
*
ppwd
=
getpwnam
(
"shell"
);
if
(
nullptr
==
ppwd
)
...
...
@@ -199,7 +202,7 @@ int exec_array(bool err, int *fd, void (*pre_exec)(void), const char **argv) {
static
int
v_exec_command
(
bool
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
const
char
*
argv0
,
va_list
argv
)
{
// Collect va_list into vector
V
ector
<
const
char
*>
args
;
v
ector
<
const
char
*>
args
;
args
.
push_back
(
argv0
);
for
(
const
char
*
arg
=
va_arg
(
argv
,
char
*
);
arg
;
arg
=
va_arg
(
argv
,
char
*
))
args
.
push_back
(
arg
);
...
...
native/jni/utils/new.cpp
View file @
3e4c12cf
#include <new>
#include <stdlib.h>
/* Override libc++ new implementation
* to optimize final build size */
void
*
operator
new
(
std
::
size_t
s
)
{
return
malloc
(
s
);
}
void
*
operator
new
[](
std
::
size_t
s
)
{
return
malloc
(
s
);
}
void
operator
delete
(
void
*
p
)
{
free
(
p
);
}
...
...
native/jni/utils/xwrap.cpp
View file @
3e4c12cf
...
...
@@ -86,7 +86,7 @@ ssize_t xread(int fd, void *buf, size_t count) {
ssize_t
xxread
(
int
fd
,
void
*
buf
,
size_t
count
)
{
int
ret
=
read
(
fd
,
buf
,
count
);
if
(
count
!=
ret
)
{
PLOGE
(
"read
"
);
PLOGE
(
"read
(%d != %d)"
,
count
,
ret
);
}
return
ret
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment