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
7c12bf7f
Commit
7c12bf7f
authored
Nov 07, 2018
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modernize code base
parent
ca35a968
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
421 additions
and
287 deletions
+421
-287
bootstages.cpp
native/jni/daemon/bootstages.cpp
+89
-105
daemon.cpp
native/jni/daemon/daemon.cpp
+1
-1
resetprop.h
native/jni/include/resetprop.h
+3
-1
cpio.cpp
native/jni/magiskboot/cpio.cpp
+42
-53
cpio.h
native/jni/magiskboot/cpio.h
+4
-2
ramdisk.cpp
native/jni/magiskboot/ramdisk.cpp
+46
-46
hide_utils.cpp
native/jni/magiskhide/hide_utils.cpp
+25
-39
magiskhide.cpp
native/jni/magiskhide/magiskhide.cpp
+2
-2
magiskhide.h
native/jni/magiskhide/magiskhide.h
+4
-4
proc_monitor.cpp
native/jni/magiskhide/proc_monitor.cpp
+6
-9
_resetprop.h
native/jni/resetprop/_resetprop.h
+2
-1
persist_properties.cpp
native/jni/resetprop/persist_properties.cpp
+4
-4
resetprop.cpp
native/jni/resetprop/resetprop.cpp
+10
-10
Android.mk
native/jni/utils/Android.mk
+1
-0
CharArray.cpp
native/jni/utils/CharArray.cpp
+99
-0
file.cpp
native/jni/utils/file.cpp
+2
-2
CharArray.h
native/jni/utils/include/CharArray.h
+39
-0
array.h
native/jni/utils/include/array.h
+14
-6
cpputils.h
native/jni/utils/include/cpputils.h
+12
-0
utils.h
native/jni/utils/include/utils.h
+8
-2
misc.cpp
native/jni/utils/misc.cpp
+8
-0
No files found.
native/jni/daemon/bootstages.cpp
View file @
7c12bf7f
This diff is collapsed.
Click to expand it.
native/jni/daemon/daemon.cpp
View file @
7c12bf7f
...
...
@@ -82,7 +82,7 @@ static void *request_handler(void *args) {
close
(
client
);
break
;
}
return
NULL
;
return
nullptr
;
}
static
void
main_daemon
()
{
...
...
native/jni/include/resetprop.h
View file @
7c12bf7f
...
...
@@ -3,9 +3,11 @@
#pragma once
#include "CharArray.h"
int
prop_exist
(
const
char
*
name
);
int
setprop
(
const
char
*
name
,
const
char
*
value
,
const
bool
trigger
=
true
);
char
*
getprop
(
const
char
*
name
,
bool
persist
=
false
);
CharArray
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
);
...
...
native/jni/magiskboot/cpio.cpp
View file @
7c12bf7f
...
...
@@ -40,8 +40,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
=
(
char
*
)
xmalloc
(
namesize
);
xxread
(
fd
,
filename
,
namesize
);
filename
=
CharArray
(
namesize
);
xxread
(
fd
,
filename
,
filename
.
size
()
);
parse_align
();
if
(
filesize
)
{
data
=
xmalloc
(
filesize
);
...
...
@@ -51,7 +51,6 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
}
cpio_entry
::~
cpio_entry
()
{
free
(
filename
);
free
(
data
);
}
...
...
@@ -61,7 +60,7 @@ int(*Array<cpio_entry*>::_cmp)(cpio_entry*&, cpio_entry*&) = [](auto a, auto b)
if
(
a
==
b
)
return
0
;
if
(
a
==
nullptr
)
return
1
;
if
(
b
==
nullptr
)
return
-
1
;
return
strcmp
(
a
->
filename
,
b
->
filename
);
return
a
->
filename
.
compare
(
b
->
filename
);
};
...
...
@@ -73,12 +72,11 @@ cpio::cpio(const char *filename) {
cpio_entry
*
entry
;
while
(
xxread
(
fd
,
&
header
,
sizeof
(
cpio_newc_header
))
!=
-
1
)
{
entry
=
new
cpio_entry
(
fd
,
header
);
if
(
strcmp
(
entry
->
filename
,
"."
)
==
0
||
strcmp
(
entry
->
filename
,
".."
)
==
0
||
strcmp
(
entry
->
filename
,
"TRAILER!!!"
)
==
0
)
{
if
(
entry
->
filename
==
"."
||
entry
->
filename
==
".."
||
entry
->
filename
==
"TRAILER!!!"
)
{
bool
trailer
=
entry
->
filename
[
0
]
==
'T'
;
delete
entry
;
if
(
entry
->
filename
[
0
]
==
'T'
)
if
(
trailer
)
break
;
continue
;
}
arr
.
push_back
(
entry
);
}
...
...
@@ -110,11 +108,11 @@ void cpio::dump(const char *file) {
0
,
// e->devminor
0
,
// e->rdevmajor
0
,
// e->rdevminor
(
uint32_t
)
strlen
(
e
->
filename
)
+
1
,
(
uint32_t
)
e
->
filename
.
size
()
,
0
// e->check
);
xwrite
(
fd
,
header
,
110
);
xwrite
(
fd
,
e
->
filename
,
strlen
(
e
->
filename
)
+
1
);
xwrite
(
fd
,
e
->
filename
,
e
->
filename
.
size
()
);
dump_align
();
if
(
e
->
filesize
)
{
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
...
...
@@ -134,7 +132,7 @@ int cpio::find(const char *name) {
for
(
int
i
=
0
;
i
<
arr
.
size
();
++
i
)
{
if
(
!
arr
[
i
])
continue
;
if
(
strcmp
(
arr
[
i
]
->
filename
,
name
)
==
0
)
if
(
arr
[
i
]
->
filename
==
name
)
return
i
;
}
return
-
1
;
...
...
@@ -143,12 +141,11 @@ int cpio::find(const char *name) {
void
cpio
::
insert
(
cpio_entry
*
e
)
{
int
i
=
find
(
e
->
filename
);
if
(
i
>=
0
)
{
// Replace, then all is done
delete
arr
[
i
];
arr
[
i
]
=
e
;
return
;
}
else
{
arr
.
push_back
(
e
);
}
arr
.
push_back
(
e
);
}
void
cpio
::
insert
(
Array
<
cpio_entry
*>
&
arr
)
{
...
...
@@ -156,17 +153,17 @@ void cpio::insert(Array<cpio_entry *> &arr) {
insert
(
e
);
}
void
cpio
::
rm
(
int
recur
,
const
char
*
name
)
{
void
cpio
::
rm
(
const
char
*
name
,
bool
r
)
{
size_t
len
=
strlen
(
name
);
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
if
(
strncmp
(
e
->
filename
,
name
,
len
)
==
0
&&
((
r
ecur
&&
e
->
filename
[
len
]
==
'/'
)
||
e
->
filename
[
len
]
==
'\0'
))
{
fprintf
(
stderr
,
"Remove [%s]
\n
"
,
e
->
filename
);
if
(
e
->
filename
.
compare
(
name
,
len
)
==
0
&&
((
r
&&
e
->
filename
[
len
]
==
'/'
)
||
e
->
filename
[
len
]
==
'\0'
))
{
fprintf
(
stderr
,
"Remove [%s]
\n
"
,
e
->
filename
.
c_str
()
);
delete
e
;
e
=
nullptr
;
if
(
!
r
ecur
)
if
(
!
r
)
return
;
}
}
...
...
@@ -175,7 +172,7 @@ void cpio::rm(int recur, const char *name) {
void
cpio
::
makedir
(
mode_t
mode
,
const
char
*
name
)
{
auto
e
=
new
cpio_entry
();
e
->
mode
=
S_IFDIR
|
mode
;
e
->
filename
=
strdup
(
name
)
;
e
->
filename
=
name
;
insert
(
e
);
fprintf
(
stderr
,
"Create directory [%s] (%04o)
\n
"
,
name
,
mode
);
}
...
...
@@ -183,7 +180,7 @@ void cpio::makedir(mode_t mode, const char *name) {
void
cpio
::
ln
(
const
char
*
target
,
const
char
*
name
)
{
auto
e
=
new
cpio_entry
();
e
->
mode
=
S_IFLNK
;
e
->
filename
=
strdup
(
name
)
;
e
->
filename
=
name
;
e
->
filesize
=
strlen
(
target
);
e
->
data
=
strdup
(
target
);
insert
(
e
);
...
...
@@ -194,7 +191,7 @@ void cpio::add(mode_t mode, const char *name, const char *file) {
int
fd
=
xopen
(
file
,
O_RDONLY
);
auto
e
=
new
cpio_entry
();
e
->
mode
=
S_IFREG
|
mode
;
e
->
filename
=
strdup
(
name
)
;
e
->
filename
=
name
;
e
->
filesize
=
lseek
(
fd
,
0
,
SEEK_END
);
lseek
(
fd
,
0
,
SEEK_SET
);
e
->
data
=
xmalloc
(
e
->
filesize
);
...
...
@@ -212,35 +209,38 @@ bool cpio::mv(const char *from, const char *to) {
arr
[
t
]
=
nullptr
;
}
fprintf
(
stderr
,
"Move [%s] -> [%s]
\n
"
,
from
,
to
);
char
*
tmp
=
strdup
(
to
);
free
(
arr
[
f
]
->
filename
);
arr
[
f
]
->
filename
=
tmp
;
arr
[
f
]
->
filename
=
to
;
return
true
;
}
fprintf
(
stderr
,
"Cannot find entry %s
\n
"
,
from
);
return
false
;
}
static
void
extract_entry
(
cpio_entry
*
e
,
const
char
*
file
)
{
fprintf
(
stderr
,
"Extract [%s] to [%s]
\n
"
,
e
->
filename
.
c_str
(),
file
);
unlink
(
file
);
rmdir
(
file
);
if
(
S_ISDIR
(
e
->
mode
))
{
mkdir
(
file
,
e
->
mode
&
0777
);
}
else
if
(
S_ISREG
(
e
->
mode
))
{
int
fd
=
creat
(
file
,
e
->
mode
&
0777
);
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
fchown
(
fd
,
e
->
uid
,
e
->
gid
);
close
(
fd
);
}
else
if
(
S_ISLNK
(
e
->
mode
))
{
auto
target
=
new
char
[
e
->
filesize
+
1
];
memcpy
(
target
,
e
->
data
,
e
->
filesize
);
target
[
e
->
filesize
]
=
'\0'
;
symlink
(
target
,
file
);
delete
[]
target
;
}
}
void
cpio
::
extract
()
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
fprintf
(
stderr
,
"Extract [%s]
\n
"
,
e
->
filename
);
unlink
(
e
->
filename
);
rmdir
(
e
->
filename
);
if
(
S_ISDIR
(
e
->
mode
))
{
mkdir
(
e
->
filename
,
e
->
mode
&
0777
);
}
else
if
(
S_ISREG
(
e
->
mode
))
{
int
fd
=
creat
(
e
->
filename
,
e
->
mode
&
0777
);
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
fchown
(
fd
,
e
->
uid
,
e
->
gid
);
close
(
fd
);
}
else
if
(
S_ISLNK
(
e
->
mode
))
{
char
*
target
=
new
char
[
e
->
filesize
+
1
];
memcpy
(
target
,
e
->
data
,
e
->
filesize
);
symlink
(
target
,
e
->
filename
);
delete
[]
target
;
}
extract_entry
(
e
,
e
->
filename
);
}
}
...
...
@@ -248,18 +248,7 @@ bool cpio::extract(const char *name, const char *file) {
int
i
=
find
(
name
);
if
(
i
>
0
)
{
auto
e
=
arr
[
i
];
fprintf
(
stderr
,
"Extract [%s] to [%s]
\n
"
,
name
,
file
);
if
(
S_ISREG
(
e
->
mode
))
{
int
fd
=
creat
(
file
,
e
->
mode
&
0777
);
xwrite
(
fd
,
e
->
data
,
e
->
filesize
);
fchown
(
fd
,
e
->
uid
,
e
->
gid
);
close
(
fd
);
}
else
if
(
S_ISLNK
(
e
->
mode
))
{
char
*
target
=
new
char
[
e
->
filesize
+
1
];
memcpy
(
target
,
e
->
data
,
e
->
filesize
);
symlink
(
target
,
e
->
filename
);
delete
[]
target
;
}
extract_entry
(
e
,
file
);
return
true
;
}
fprintf
(
stderr
,
"Cannot find the file entry [%s]
\n
"
,
name
);
...
...
native/jni/magiskboot/cpio.h
View file @
7c12bf7f
...
...
@@ -4,6 +4,7 @@
#include <stdint.h>
#include "array.h"
#include "CharArray.h"
struct
cpio_newc_header
{
char
magic
[
6
];
...
...
@@ -36,7 +37,8 @@ struct cpio_entry {
// uint32_t rdevminor;
// uint32_t namesize;
// uint32_t check;
char
*
filename
=
nullptr
;
// char *filename = nullptr;
CharArray
filename
;
void
*
data
=
nullptr
;
cpio_entry
()
{}
...
...
@@ -51,7 +53,7 @@ public:
void
dump
(
const
char
*
file
);
int
find
(
const
char
*
name
);
void
insert
(
cpio_entry
*
e
);
void
rm
(
int
recur
,
const
char
*
nam
e
);
void
rm
(
const
char
*
name
,
bool
r
=
fals
e
);
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
);
...
...
native/jni/magiskboot/ramdisk.cpp
View file @
7c12bf7f
...
...
@@ -23,10 +23,13 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
bool
fstab
=
(
!
keepverity
||
!
keepforceencrypt
)
&&
!
e
->
filename
.
starts_with
(
".backup"
)
&&
e
->
filename
.
contains
(
"fstab"
)
&&
S_ISREG
(
e
->
mode
);
if
(
!
keepverity
)
{
if
(
strncmp
(
e
->
filename
,
".backup"
,
7
)
&&
strstr
(
e
->
filename
,
"fstab"
)
&&
S_ISREG
(
e
->
mode
)
)
{
if
(
fstab
)
{
patch_verity
(
&
e
->
data
,
&
e
->
filesize
,
1
);
}
else
if
(
strcmp
(
e
->
filename
,
"verity_key"
)
==
0
)
{
}
else
if
(
e
->
filename
==
"verity_key"
)
{
fprintf
(
stderr
,
"Remove [verity_key]
\n
"
);
delete
e
;
e
=
nullptr
;
...
...
@@ -34,7 +37,7 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
}
}
if
(
!
keepforceencrypt
)
{
if
(
strstr
(
e
->
filename
,
"fstab"
)
!=
NULL
&&
S_ISREG
(
e
->
mode
)
)
{
if
(
fstab
)
{
patch_encryption
(
&
e
->
data
,
&
e
->
filesize
);
}
}
...
...
@@ -47,27 +50,26 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
#define UNSUPPORT_PATCH 0x2
int
magisk_cpio
::
test
()
{
static
const
char
*
UNSUPPORT_LIST
[]
=
{
"sbin/launch_daemonsu.sh"
,
"sbin/su"
,
"init.xposed.rc"
,
"boot/sbin/launch_daemonsu.sh"
,
nullptr
};
"boot/sbin/launch_daemonsu.sh"
};
static
const
char
*
MAGISK_LIST
[]
=
{
".backup/.magisk"
,
"init.magisk.rc"
,
"overlay/init.magisk.rc"
,
nullptr
};
"overlay/init.magisk.rc"
};
for
(
int
i
=
0
;
UNSUPPORT_LIST
[
i
];
++
i
)
if
(
find
(
UNSUPPORT_LIST
[
i
]
)
>=
0
)
for
(
auto
file
:
UNSUPPORT_LIST
)
if
(
find
(
file
)
>=
0
)
return
UNSUPPORT_PATCH
;
for
(
int
i
=
0
;
MAGISK_LIST
[
i
];
++
i
)
if
(
find
(
MAGISK_LIST
[
i
]
)
>=
0
)
for
(
auto
file
:
MAGISK_LIST
)
if
(
find
(
file
)
>=
0
)
return
MAGISK_PATCH
;
return
STOCK_BOOT
;
}
char
*
magisk_cpio
::
sha1
()
{
char
*
magisk_cpio
::
sha1
()
{
char
sha1
[
41
];
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
if
(
strcmp
(
e
->
filename
,
"init.magisk.rc"
)
==
0
||
strcmp
(
e
->
filename
,
"overlay/init.magisk.rc"
)
==
0
)
{
if
(
e
->
filename
==
"init.magisk.rc"
||
e
->
filename
==
"overlay/init.magisk.rc"
)
{
for
(
char
*
pos
=
(
char
*
)
e
->
data
;
pos
<
(
char
*
)
e
->
data
+
e
->
filesize
;
pos
=
strchr
(
pos
+
1
,
'\n'
)
+
1
)
{
if
(
memcmp
(
pos
,
"# STOCKSHA1="
,
12
)
==
0
)
{
...
...
@@ -77,7 +79,7 @@ char * magisk_cpio::sha1() {
return
strdup
(
sha1
);
}
}
}
else
if
(
strcmp
(
e
->
filename
,
".backup/.sha1"
)
==
0
)
{
}
else
if
(
e
->
filename
==
".backup/.sha1"
)
{
return
(
char
*
)
e
->
data
;
}
}
...
...
@@ -87,12 +89,12 @@ char * magisk_cpio::sha1() {
void
magisk_cpio
::
restore
()
{
for
(
auto
&
e
:
arr
)
{
if
(
!
e
)
continue
;
if
(
strncmp
(
e
->
filename
,
".backup"
,
7
)
==
0
)
{
if
(
e
->
filename
.
starts_with
(
".backup"
)
)
{
if
(
e
->
filename
[
7
]
==
'\0'
)
continue
;
if
(
e
->
filename
[
8
]
==
'.'
)
{
if
(
strcmp
(
e
->
filename
+
8
,
".rmlist"
)
==
0
)
{
if
(
strcmp
(
&
e
->
filename
[
8
]
,
".rmlist"
)
==
0
)
{
for
(
int
pos
=
0
;
pos
<
e
->
filesize
;
pos
+=
strlen
((
char
*
)
e
->
data
+
pos
)
+
1
)
rm
(
false
,
(
char
*
)
e
->
data
+
pos
);
rm
(
(
char
*
)
e
->
data
+
pos
,
false
);
}
}
else
{
mv
(
e
->
filename
,
e
->
filename
+
8
);
...
...
@@ -101,43 +103,41 @@ void magisk_cpio::restore() {
}
// Some known stuff we can remove
rm
(
true
,
".backup"
);
rm
(
true
,
"overlay"
);
rm
(
false
,
"sbin/magic_mask.sh"
);
rm
(
false
,
"init.magisk.rc"
);
rm
(
true
,
"magisk"
);
rm
(
".backup"
,
true
);
rm
(
"overlay"
,
true
);
rm
(
"sbin/magic_mask.sh"
,
false
);
rm
(
"init.magisk.rc"
,
false
);
rm
(
"magisk"
,
true
);
}
void
magisk_cpio
::
backup
(
Array
<
cpio_entry
*>
&
bak
,
const
char
*
orig
,
const
char
*
sha1
)
{
cpio_entry
*
m
,
*
n
,
*
rem
,
*
cksm
;
char
buf
[
PATH_MAX
];
int
res
;
bool
backup
;
m
=
new
cpio_entry
();
m
->
filename
=
strdup
(
".backup"
)
;
m
->
filename
=
".backup"
;
m
->
mode
=
S_IFDIR
;
bak
.
push_back
(
m
);
rem
=
new
cpio_entry
();
rem
->
filename
=
strdup
(
".backup/.rmlist"
)
;
rem
->
filename
=
".backup/.rmlist"
;
rem
->
mode
=
S_IFREG
;
if
(
sha1
)
{
fprintf
(
stderr
,
"Save SHA1: [%s] -> [.backup/.sha1]
\n
"
,
sha1
);
cksm
=
new
cpio_entry
();
bak
.
push_back
(
cksm
);
cksm
->
filename
=
strdup
(
".backup/.sha1"
);
cksm
->
filename
=
".backup/.sha1"
;
cksm
->
mode
=
S_IFREG
;
cksm
->
data
=
strdup
(
sha1
);
cksm
->
filesize
=
strlen
(
sha1
)
+
1
;
bak
.
push_back
(
cksm
);
}
magisk_cpio
o
=
magisk_cpio
(
orig
);
magisk_cpio
o
(
orig
);
// Remove possible backups in original ramdisk
o
.
rm
(
true
,
".backup"
);
rm
(
true
,
".backup"
);
o
.
rm
(
".backup"
,
true
);
rm
(
".backup"
,
true
);
// Sort both CPIOs before comparing
o
.
sort
();
...
...
@@ -146,11 +146,12 @@ void magisk_cpio::backup(Array<cpio_entry*> &bak, const char *orig, const char *
// Start comparing
size_t
i
=
0
,
j
=
0
;
while
(
i
!=
o
.
arr
.
size
()
||
j
!=
arr
.
size
())
{
backup
=
false
;
int
res
;
bool
backup
=
false
;
if
(
i
!=
o
.
arr
.
size
()
&&
j
!=
arr
.
size
())
{
m
=
o
.
arr
[
i
];
n
=
arr
[
j
];
res
=
strcmp
(
m
->
filename
,
n
->
filename
);
res
=
m
->
filename
.
compare
(
n
->
filename
);
}
else
if
(
i
==
o
.
arr
.
size
())
{
n
=
arr
[
j
];
res
=
1
;
...
...
@@ -174,16 +175,15 @@ void magisk_cpio::backup(Array<cpio_entry*> &bak, const char *orig, const char *
}
else
{
// Something new in ramdisk, record in rem
++
j
;
rem
->
data
=
xrealloc
(
rem
->
data
,
rem
->
filesize
+
strlen
(
n
->
filename
)
+
1
);
memcpy
((
char
*
)
rem
->
data
+
rem
->
filesize
,
n
->
filename
,
strlen
(
n
->
filename
)
+
1
);
rem
->
filesize
+=
strlen
(
n
->
filename
)
+
1
;
fprintf
(
stderr
,
"Record new entry: [%s] -> [.backup/.rmlist]
\n
"
,
n
->
filename
);
rem
->
data
=
xrealloc
(
rem
->
data
,
rem
->
filesize
+
n
->
filename
.
size
()
);
memcpy
((
char
*
)
rem
->
data
+
rem
->
filesize
,
n
->
filename
,
n
->
filename
.
size
()
);
rem
->
filesize
+=
n
->
filename
.
size
()
;
fprintf
(
stderr
,
"Record new entry: [%s] -> [.backup/.rmlist]
\n
"
,
n
->
filename
.
c_str
()
);
}
if
(
backup
)
{
sprintf
(
buf
,
".backup/%s"
,
m
->
filename
);
fprintf
(
stderr
,
"[%s] -> [%s]
\n
"
,
m
->
filename
,
buf
);
free
(
m
->
filename
);
m
->
filename
=
strdup
(
buf
);
sprintf
(
buf
,
".backup/%s"
,
m
->
filename
.
c_str
());
fprintf
(
stderr
,
"[%s] -> [%s]
\n
"
,
m
->
filename
.
c_str
(),
buf
);
m
->
filename
=
buf
;
bak
.
push_back
(
m
);
// NULL the original entry, so it won't be freed
o
.
arr
[
i
-
1
]
=
nullptr
;
...
...
@@ -202,7 +202,7 @@ int cpio_commands(int argc, char *argv[]) {
++
argv
;
--
argc
;
magisk_cpio
cpio
=
magisk_cpio
(
incpio
);
magisk_cpio
cpio
(
incpio
);
int
cmdc
;
char
*
cmdv
[
6
];
...
...
@@ -230,17 +230,17 @@ int cpio_commands(int argc, char *argv[]) {
free
(
sha1
);
return
0
;
}
else
if
(
cmdc
>=
2
&&
strcmp
(
cmdv
[
0
],
"backup"
)
==
0
)
{
auto
bak
=
Array
<
cpio_entry
*>
()
;
Array
<
cpio_entry
*>
bak
;
cpio
.
backup
(
bak
,
cmdv
[
1
],
cmdv
[
2
]);
cpio
.
insert
(
bak
);
}
else
if
(
cmdc
>=
4
&&
strcmp
(
cmdv
[
0
],
"magisk"
)
==
0
)
{
cpio
.
patch
(
strcmp
(
cmdv
[
2
],
"true"
)
==
0
,
strcmp
(
cmdv
[
3
],
"true"
)
==
0
);
auto
bak
=
Array
<
cpio_entry
*>
()
;
Array
<
cpio_entry
*>
bak
;
cpio
.
backup
(
bak
,
cmdv
[
1
],
cmdv
[
4
]);
auto
e
=
new
cpio_entry
();
e
->
filename
=
strdup
(
".backup/.magisk"
)
;
e
->
filename
=
".backup/.magisk"
;
e
->
mode
=
S_IFREG
;
e
->
data
=
xmalloc
(
50
);
snprintf
((
char
*
)
e
->
data
,
50
,
"KEEPVERITY=%s
\n
KEEPFORCEENCRYPT=%s
\n
"
,
cmdv
[
2
],
cmdv
[
3
]);
...
...
@@ -249,8 +249,8 @@ int cpio_commands(int argc, char *argv[]) {
cpio
.
insert
(
bak
);
cpio
.
insert
(
e
);
}
else
if
(
cmdc
>=
2
&&
strcmp
(
cmdv
[
0
],
"rm"
)
==
0
)
{
int
recu
r
=
cmdc
>
2
&&
strcmp
(
cmdv
[
1
],
"-r"
)
==
0
;
cpio
.
rm
(
recur
,
cmdv
[
1
+
recur
]
);
bool
r
=
cmdc
>
2
&&
strcmp
(
cmdv
[
1
],
"-r"
)
==
0
;
cpio
.
rm
(
cmdv
[
1
+
r
],
r
);
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"mv"
)
==
0
)
{
cpio
.
mv
(
cmdv
[
1
],
cmdv
[
2
]);
}
else
if
(
cmdc
==
3
&&
strcmp
(
cmdv
[
0
],
"patch"
)
==
0
)
{
...
...
native/jni/magiskhide/hide_utils.cpp
View file @
7c12bf7f
...
...
@@ -15,7 +15,7 @@
#include "daemon.h"
#include "db.h"
auto
hide_list
=
Array
<
char
*>
()
;
Array
<
CharArray
>
hide_list
;
static
const
char
*
prop_key
[]
=
{
"ro.boot.vbmeta.device_state"
,
"ro.boot.verifiedbootstate"
,
"ro.boot.flash.locked"
,
...
...
@@ -46,14 +46,10 @@ void hide_sensitive_props() {
LOGI
(
"hide_utils: Hiding sensitive props
\n
"
);
// Hide all sensitive props
char
*
value
;
for
(
int
i
=
0
;
prop_key
[
i
];
++
i
)
{
value
=
getprop
(
prop_key
[
i
]);
if
(
value
)
{
if
(
strcmp
(
value
,
prop_value
[
i
])
!=
0
)
setprop
(
prop_key
[
i
],
prop_value
[
i
],
false
);
free
(
value
);
}
CharArray
value
=
getprop
(
prop_key
[
i
]);
if
(
!
value
.
empty
()
&&
value
!=
prop_value
[
i
])
setprop
(
prop_key
[
i
],
prop_value
[
i
],
false
);
}
}
...
...
@@ -139,13 +135,11 @@ void clean_magisk_props() {
},
nullptr
,
false
);
}
static
int
add_list
(
sqlite3
*
db
,
char
*
proc
)
{
static
int
add_list
(
sqlite3
*
db
,
c
onst
c
har
*
proc
)
{
for
(
auto
&
s
:
hide_list
)
{
// They should be unique
if
(
strcmp
(
s
,
proc
)
==
0
)
{
free
(
proc
);
if
(
s
==
proc
)
return
HIDE_ITEM_EXIST
;
}
}
LOGI
(
"hide_list add: [%s]
\n
"
,
proc
);
...
...
@@ -164,7 +158,7 @@ static int add_list(sqlite3 *db, char *proc) {
return
DAEMON_SUCCESS
;
}
int
add_list
(
char
*
proc
)
{
int
add_list
(
c
onst
c
har
*
proc
)
{
sqlite3
*
db
=
get_magiskdb
();
if
(
db
)
{
int
ret
=
add_list
(
db
,
proc
);
...
...
@@ -175,20 +169,20 @@ int add_list(char *proc) {
}
int
add_list
(
int
client
)
{
return
add_list
(
read_string
(
client
));
char
*
proc
=
read_string
(
client
);
int
ret
=
add_list
(
proc
);
free
(
proc
);
return
ret
;
}
static
int
rm_list
(
char
*
proc
)
{
int
ret
=
DAEMON_ERROR
;
static
int
rm_list
(
const
char
*
proc
)
{
// Update list in critical region
bool
do_rm
=
false
;
pthread_mutex_lock
(
&
list_lock
);
for
(
auto
it
=
hide_list
.
begin
();
it
!=
hide_list
.
end
();
++
it
)
{
if
(
strcmp
(
*
it
,
proc
)
==
0
)
{
if
(
*
it
==
proc
)
{
do_rm
=
true
;
LOGI
(
"hide_list rm: [%s]
\n
"
,
proc
);
free
(
*
it
);
hide_list
.
erase
(
it
);
break
;
}
...
...
@@ -199,45 +193,44 @@ static int rm_list(char *proc) {
kill_process
(
proc
);
sqlite3
*
db
=
get_magiskdb
();
if
(
db
==
nullptr
)
goto
error
;
return
DAEMON_ERROR
;
char
sql
[
128
];
sprintf
(
sql
,
"DELETE FROM hidelist WHERE process='%s'"
,
proc
);
sqlite3_exec
(
db
,
sql
,
nullptr
,
nullptr
,
nullptr
);
sqlite3_close_v2
(
db
);
ret
=
DAEMON_SUCCESS
;
ret
urn
DAEMON_SUCCESS
;
}
else
{
ret
=
HIDE_ITEM_NOT_EXIST
;
ret
urn
HIDE_ITEM_NOT_EXIST
;
}
error:
free
(
proc
);
return
ret
;
}
int
rm_list
(
int
client
)
{
return
rm_list
(
read_string
(
client
));
char
*
proc
=
read_string
(
client
);
int
ret
=
rm_list
(
proc
);
free
(
proc
);
return
ret
;
}
#define LEGACY_LIST MOUNTPOINT "/.core/hidelist"
int
init_list
()
{
bool
init_list
()
{
LOGD
(
"hide_list: initialize
\n
"
);
sqlite3
*
db
=
get_magiskdb
();
if
(
db
==
nullptr
)
return
1
;
return
false
;
sqlite3_exec
(
db
,
"SELECT process FROM hidelist"
,
[]
(
auto
,
auto
,
char
**
data
,
auto
)
->
int
{
LOGI
(
"hide_list: [%s]
\n
"
,
data
[
0
]);
hide_list
.
push_back
(
strdup
(
data
[
0
])
);
hide_list
.
push_back
(
data
[
0
]
);
return
0
;
},
nullptr
,
nullptr
);
// Migrate old hide list into database
if
(
access
(
LEGACY_LIST
,
R_OK
)
==
0
)
{
auto
tmp
=
Array
<
char
*>
()
;
Array
<
CharArray
>
tmp
;
file_to_array
(
LEGACY_LIST
,
tmp
);
for
(
auto
&
s
:
tmp
)
add_list
(
db
,
s
);
...
...
@@ -245,14 +238,7 @@ int init_list() {
}
sqlite3_close_v2
(
db
);
return
0
;
}
int
destroy_list
()
{
for
(
auto
&
str
:
hide_list
)
free
(
str
);
hide_list
.
clear
();
return
0
;
return
true
;
}
void
ls_list
(
int
client
)
{
...
...
native/jni/magiskhide/magiskhide.cpp
View file @
7c12bf7f
...
...
@@ -54,11 +54,11 @@ int launch_magiskhide() {
pthread_mutex_init
(
&
list_lock
,
nullptr
);
// Initialize the hide list
if
(
init_list
())
if
(
!
init_list
())
goto
error
;
// Add SafetyNet by default
add_list
(
strdup
(
"com.google.android.gms.unstable"
)
);
add_list
(
"com.google.android.gms.unstable"
);
// Get thread reference
proc_monitor_thread
=
pthread_self
();
...
...
native/jni/magiskhide/magiskhide.h
View file @
7c12bf7f
...
...
@@ -5,6 +5,7 @@
#include "daemon.h"
#include "array.h"
#include "CharArray.h"
#define TERM_THREAD SIGUSR1
...
...
@@ -24,13 +25,12 @@ void hide_sensitive_props();
void
clean_magisk_props
();
// List managements
int
add_list
(
char
*
proc
);
int
init_list
();
int
destroy_list
();
int
add_list
(
const
char
*
proc
);
bool
init_list
();
extern
int
hide_enabled
;
extern
pthread_mutex_t
list_lock
;
extern
Array
<
char
*
>
hide_list
;
extern
Array
<
CharArray
>
hide_list
;
enum
{
LAUNCH_MAGISKHIDE
,
...
...
native/jni/magiskhide/proc_monitor.cpp
View file @
7c12bf7f
...
...
@@ -27,13 +27,13 @@ static int sockfd = -1;
// Workaround for the lack of pthread_cancel
static
void
term_thread
(
int
)
{
LOGD
(
"proc_monitor: running cleanup
\n
"
);
destroy_list
(
);
hide_list
.
clear
(
true
);
hide_enabled
=
0
;
close
(
sockfd
);
sockfd
=
-
1
;
pthread_mutex_destroy
(
&
list_lock
);
LOGD
(
"proc_monitor: terminating
\n
"
);
pthread_exit
(
NULL
);
pthread_exit
(
nullptr
);
}
static
int
read_ns
(
const
int
pid
,
struct
stat
*
st
)
{
...
...
@@ -63,7 +63,7 @@ static void hide_daemon(int pid) {
LOGD
(
"hide_daemon: start unmount for pid=[%d]
\n
"
,
pid
);
char
buffer
[
PATH_MAX
];
auto
mounts
=
Array
<
char
*>
()
;
Array
<
CharArray
>
mounts
;
manage_selinux
();
clean_magisk_props
();
...
...
@@ -76,11 +76,10 @@ static void hide_daemon(int pid) {
// Unmount dummy skeletons and /sbin links
for
(
auto
&
s
:
mounts
)
{
if
(
s
trstr
(
s
,
"tmpfs /system/"
)
||
strstr
(
s
,
"tmpfs /vendor/"
)
||
strstr
(
s
,
"tmpfs /sbin"
))
{
if
(
s
.
contains
(
"tmpfs /system/"
)
||
s
.
contains
(
"tmpfs /vendor/"
)
||
s
.
contains
(
"tmpfs /sbin"
))
{
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
}
free
(
s
);
}
mounts
.
clear
();
...
...
@@ -90,13 +89,11 @@ static void hide_daemon(int pid) {
// Unmount everything under /system, /vendor, and loop mounts
for
(
auto
&
s
:
mounts
)
{
if
(
s
trstr
(
s
,
"/dev/block/loop"
)
||
strstr
(
s
,
" /system/"
)
||
strstr
(
s
,
" /vendor/"
))
{
if
(
s
.
contains
(
"/dev/block/loop"
)
||
s
.
contains
(
" /system/"
)
||
s
.
contains
(
" /vendor/"
))
{
sscanf
(
s
,
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
}
free
(
s
);
}
mounts
.
clear
();
exit:
// Send resume signal
...
...
@@ -159,7 +156,7 @@ void proc_monitor() {
bool
hide
=
false
;
pthread_mutex_lock
(
&
list_lock
);
for
(
auto
&
s
:
hide_list
)
{
if
(
s
trcmp
(
proc
,
s
)
==
0
)
{
if
(
s
==
proc
)
{
hide
=
true
;
break
;
}
...
...
native/jni/resetprop/_resetprop.h
View file @
7c12bf7f
...
...
@@ -5,6 +5,7 @@
#ifndef MAGISK_PROPS_H
#define MAGISK_PROPS_H
#include <CharArray.h>
#include "resetprop/private/system_properties.h"
#include "logging.h"
...
...
@@ -48,7 +49,7 @@ struct read_cb_t {
extern
bool
use_pb
;
char
*
persist_getprop
(
const
char
*
name
);
CharArray
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 @
7c12bf7f
...
...
@@ -190,21 +190,21 @@ void persist_getprop(read_cb_t *read_cb) {
}
}
char
*
persist_getprop
(
const
char
*
name
)
{
CharArray
persist_getprop
(
const
char
*
name
)
{
prop_t
prop
(
name
);
if
(
use_pb
)
{
read_cb_t
read_cb
(
pb_getprop_cb
,
&
prop
);
pb_getprop
(
&
read_cb
);
if
(
prop
.
value
[
0
])
return
strdup
(
prop
.
value
)
;
return
prop
.
value
;
}
else
{
// Try to read from file
char
value
[
PROP_VALUE_MAX
];
file_getprop
(
name
,
value
);
if
(
value
[
0
])
return
strdup
(
value
)
;
return
value
;
}
return
nullptr
;
return
CharArray
()
;
}
bool
persist_deleteprop
(
const
char
*
name
)
{
...
...
native/jni/resetprop/resetprop.cpp
View file @
7c12bf7f
...
...
@@ -130,18 +130,18 @@ int prop_exist(const char *name) {
}
// Get prop by name, return string (should free manually!)
char
*
getprop
(
const
char
*
name
,
bool
persist
)
{
CharArray
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
)
{
char
*
value
=
persist_getprop
(
name
);
if
(
value
)
CharArray
value
=
persist_getprop
(
name
);
if
(
!
value
.
empty
()
)
return
value
;
}
LOGD
(
"resetprop: prop [%s] does not exist
\n
"
,
name
);
return
nullptr
;
return
CharArray
()
;
}
else
{
char
value
[
PROP_VALUE_MAX
];
read_cb_t
read_cb
;
...
...
@@ -149,7 +149,7 @@ char *getprop(const char *name, bool persist) {
read_cb
.
arg
=
value
;
read_props
(
pi
,
&
read_cb
);
LOGD
(
"resetprop: getprop [%s]: [%s]
\n
"
,
name
,
value
);
return
strdup
(
value
)
;
return
value
;
}
}
...
...
@@ -254,7 +254,8 @@ int resetprop_main(int argc, char *argv[]) {
log_cb
.
d
=
[](
auto
fmt
,
auto
ap
)
->
int
{
return
verbose
?
vfprintf
(
stderr
,
fmt
,
ap
)
:
0
;
};
bool
trigger
=
true
,
persist
=
false
;
char
*
argv0
=
argv
[
0
],
*
prop
;
char
*
argv0
=
argv
[
0
];
CharArray
prop
;
--
argc
;
++
argv
;
...
...
@@ -297,10 +298,9 @@ int resetprop_main(int argc, char *argv[]) {
print_props
(
persist
);
return
0
;
case
1
:
prop
=
getprop
(
argv
[
0
],
persist
);
if
(
prop
==
nullptr
)
return
1
;
printf
(
"%s
\n
"
,
prop
);
free
(
prop
);
prop
=
utils
::
move
(
getprop
(
argv
[
0
],
persist
));
if
(
!
prop
)
return
1
;
printf
(
"%s
\n
"
,
prop
.
c_str
());
return
0
;
case
2
:
return
setprop
(
argv
[
0
],
argv
[
1
],
trigger
);
...
...
native/jni/utils/Android.mk
View file @
7c12bf7f
...
...
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES := \
selinux.cpp \
logging.cpp \
xwrap.cpp \
CharArray.cpp \
vector.c
include $(BUILD_STATIC_LIBRARY)
native/jni/utils/CharArray.cpp
0 → 100644
View file @
7c12bf7f
#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
strstr
(
_buf
,
s
)
!=
nullptr
;
}
bool
CharArray
::
starts_with
(
const
char
*
s
)
const
{
return
compare
(
s
,
strlen
(
s
))
==
0
;
}
bool
CharArray
::
empty
()
const
{
return
_buf
==
nullptr
||
_buf
[
0
]
==
'\0'
;
}
native/jni/utils/file.cpp
View file @
7c12bf7f
...
...
@@ -388,7 +388,7 @@ void write_zero(int fd, size_t size) {
lseek
(
fd
,
pos
+
size
,
SEEK_SET
);
}
int
file_to_array
(
const
char
*
filename
,
Array
<
char
*
>
&
arr
)
{
int
file_to_array
(
const
char
*
filename
,
Array
<
CharArray
>
&
arr
)
{
if
(
access
(
filename
,
R_OK
)
!=
0
)
return
1
;
char
*
line
=
nullptr
;
...
...
@@ -404,8 +404,8 @@ int file_to_array(const char *filename, Array<char *> &arr) {
if
(
line
[
read
-
1
]
==
'\n'
)
line
[
read
-
1
]
=
'\0'
;
arr
.
push_back
(
line
);
line
=
nullptr
;
}
fclose
(
fp
);
free
(
line
);
return
0
;
}
native/jni/utils/include/CharArray.h
0 → 100644
View file @
7c12bf7f
#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/array.h
View file @
7c12bf7f
#pragma once
#include <stdlib.h>
#include "cpputils.h"
template
<
class
T
>
class
Array
{
...
...
@@ -72,7 +73,7 @@ public:
if
(
_capacity
)
{
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
(
T
&&
)
a
[
i
]
;
_data
[
i
]
=
utils
::
move
(
a
[
i
])
;
}
return
*
this
;
}
...
...
@@ -101,7 +102,7 @@ public:
void
push_back
(
T
&&
x
)
{
if
(
_size
==
_capacity
)
expand
();
_data
[
_size
]
=
(
T
&&
)
x
;
_data
[
_size
]
=
utils
::
move
(
x
)
;
++
_size
;
}
...
...
@@ -114,7 +115,7 @@ public:
if
(
_size
==
0
||
d
<
_data
||
d
>=
_data
+
_size
)
return
false
;
for
(;
d
<
_data
+
_size
-
1
;
++
d
)
*
d
=
(
T
&&
)
*
(
d
+
1
);
*
d
=
utils
::
move
(
*
(
d
+
1
)
);
--
_size
;
return
true
;
...
...
@@ -130,9 +131,16 @@ public:
return
false
;
}
void
clear
()
{
_size
=
0
;
}
void
clear
(
bool
dealloc
=
false
)
{
_size
=
0
;
if
(
dealloc
)
{
_capacity
=
0
;
delete
[]
_data
;
_data
=
nullptr
;
}
}
void
sort
()
const
{
void
sort
()
{
qsort
(
_data
,
_size
,
sizeof
(
T
),
compare
);
}
...
...
@@ -161,7 +169,7 @@ private:
T
*
temp
=
_data
;
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
(
T
&&
)
temp
[
i
]
;
_data
[
i
]
=
utils
::
move
(
temp
[
i
])
;
delete
[]
temp
;
}
};
...
...
native/jni/utils/include/cpputils.h
0 → 100644
View file @
7c12bf7f
#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 @
7c12bf7f
...
...
@@ -12,9 +12,15 @@
#include <sys/stat.h>
#ifdef __cplusplus
// C++ only
#include "array.h"
int
file_to_array
(
const
char
*
filename
,
Array
<
char
*>
&
arr
);
#include "CharArray.h"
#include "cpputils.h"
int
file_to_array
(
const
char
*
filename
,
Array
<
CharArray
>
&
arr
);
char
*
strdup2
(
const
char
*
s
,
size_t
*
size
=
nullptr
);
extern
"C"
{
#endif
...
...
native/jni/utils/misc.cpp
View file @
7c12bf7f
...
...
@@ -268,3 +268,11 @@ int exec_command(int err, int *fd, void (*cb)(void), const char *argv0, ...) {
va_end
(
argv
);
return
pid
;
}
char
*
strdup2
(
const
char
*
s
,
size_t
*
size
)
{
size_t
l
=
strlen
(
s
)
+
1
;
char
*
buf
=
new
char
[
l
];
memcpy
(
buf
,
s
,
l
);
if
(
size
)
*
size
=
l
;
return
buf
;
}
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