Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
bb8cc7d4
Commit
bb8cc7d4
authored
Nov 09, 2018
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace kill calls
parent
011ed722
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
30 additions
and
123 deletions
+30
-123
core/src/main/java/com/github/shadowsocks/JniHelper.java
core/src/main/java/com/github/shadowsocks/JniHelper.java
+0
-21
core/src/main/java/com/github/shadowsocks/bg/Executable.kt
core/src/main/java/com/github/shadowsocks/bg/Executable.kt
+9
-6
core/src/main/java/com/github/shadowsocks/bg/GuardedProcessPool.kt
...main/java/com/github/shadowsocks/bg/GuardedProcessPool.kt
+20
-4
core/src/main/jni/jni-helper.cpp
core/src/main/jni/jni-helper.cpp
+1
-92
No files found.
core/src/main/java/com/github/shadowsocks/JniHelper.java
View file @
bb8cc7d4
...
...
@@ -48,27 +48,6 @@ public class JniHelper {
System
.
loadLibrary
(
"jni-helper"
);
}
@Deprecated
// Use Process.destroy() since API 24
public
static
void
sigtermCompat
(
@NonNull
Process
process
)
throws
Exception
{
if
(
Build
.
VERSION
.
SDK_INT
>=
24
)
throw
new
UnsupportedOperationException
(
"Never call this method in OpenJDK!"
);
int
errno
=
sigterm
(
process
);
if
(
errno
!=
0
)
throw
new
ErrnoException
(
"kill"
,
errno
);
}
@Deprecated
// only implemented for before API 24
public
static
boolean
waitForCompat
(
@NonNull
Process
process
,
long
millis
)
throws
Exception
{
if
(
Build
.
VERSION
.
SDK_INT
>=
24
)
throw
new
UnsupportedOperationException
(
"Never call this method in OpenJDK!"
);
final
Object
mutex
=
getExitValueMutex
(
process
);
synchronized
(
mutex
)
{
if
(
getExitValue
(
process
)
==
null
)
mutex
.
wait
(
millis
);
return
getExitValue
(
process
)
!=
null
;
}
}
public
static
native
int
sigkill
(
int
pid
);
private
static
native
int
sigterm
(
Process
process
);
private
static
native
Integer
getExitValue
(
Process
process
);
private
static
native
Object
getExitValueMutex
(
Process
process
);
public
static
native
int
sendFd
(
int
fd
,
@NonNull
String
path
);
@Nullable
public
static
native
byte
[]
parseNumericAddress
(
@NonNull
String
str
);
...
...
core/src/main/java/com/github/shadowsocks/bg/Executable.kt
View file @
bb8cc7d4
...
...
@@ -20,11 +20,12 @@
package
com.github.shadowsocks.bg
import
android.system.ErrnoException
import
android.system.Os
import
android.text.TextUtils
import
android.util.Log
import
com.crashlytics.android.Crashlytics
import
com.github.shadowsocks.Core.app
import
com.github.shadowsocks.JniHelper
import
java.io.File
import
java.io.FileNotFoundException
...
...
@@ -44,11 +45,13 @@ object Executable {
}
catch
(
ignore
:
FileNotFoundException
)
{
continue
}.
split
(
Character
.
MIN_VALUE
,
limit
=
2
).
first
())
if
(
exe
.
parent
==
app
.
applicationInfo
.
nativeLibraryDir
&&
EXECUTABLES
.
contains
(
exe
.
name
))
{
val
errno
=
JniHelper
.
sigkill
(
process
.
name
.
toInt
())
if
(
errno
!=
0
)
{
Crashlytics
.
log
(
Log
.
WARN
,
"kill"
,
"SIGKILL ${exe.absolutePath} (${process.name}) failed with $errno"
)
if
(
exe
.
parent
==
app
.
applicationInfo
.
nativeLibraryDir
&&
EXECUTABLES
.
contains
(
exe
.
name
))
try
{
Os
.
kill
(
process
.
name
.
toInt
(),
9
)
// SIGKILL
}
catch
(
e
:
ErrnoException
)
{
if
(
e
.
errno
!=
3
)
{
// ESRCH
e
.
printStackTrace
()
Crashlytics
.
log
(
Log
.
WARN
,
"kill"
,
"SIGKILL ${exe.absolutePath} (${process.name}) failed"
)
Crashlytics
.
logException
(
e
)
}
}
}
...
...
core/src/main/java/com/github/shadowsocks/bg/GuardedProcessPool.kt
View file @
bb8cc7d4
...
...
@@ -22,10 +22,11 @@ package com.github.shadowsocks.bg
import
android.os.Build
import
android.os.SystemClock
import
android.system.ErrnoException
import
android.system.Os
import
android.util.Log
import
com.crashlytics.android.Crashlytics
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.JniHelper
import
com.github.shadowsocks.utils.Commandline
import
com.github.shadowsocks.utils.thread
import
java.io.File
...
...
@@ -37,6 +38,9 @@ import java.util.concurrent.atomic.AtomicReference
class
GuardedProcessPool
{
companion
object
Dummy
:
IOException
(
"Oopsie the developer has made a no-no"
)
{
private
const
val
TAG
=
"GuardedProcessPool"
private
val
ProcessImpl
by
lazy
{
Class
.
forName
(
"java/lang/ProcessManager\$ProcessImpl"
)
}
private
val
pid
by
lazy
{
ProcessImpl
.
getField
(
"pid"
).
apply
{
isAccessible
=
true
}
}
private
val
exitValueMutex
by
lazy
{
ProcessImpl
.
getField
(
"exitValueMutex"
).
apply
{
isAccessible
=
true
}
}
}
private
inner
class
Guard
(
private
val
cmd
:
List
<
String
>,
private
val
onRestartCallback
:
(()
->
Unit
)?)
{
...
...
@@ -88,9 +92,21 @@ class GuardedProcessPool {
pushException
(
e
)
}
finally
{
if
(
process
!=
null
)
{
if
(
Build
.
VERSION
.
SDK_INT
<
24
)
@Suppress
(
"DEPRECATION"
)
{
JniHelper
.
sigtermCompat
(
process
)
JniHelper
.
waitForCompat
(
process
,
500
)
if
(
Build
.
VERSION
.
SDK_INT
<
24
)
{
val
pid
=
pid
.
get
(
process
)
as
Int
try
{
Os
.
kill
(
pid
,
15
)
// SIGTERM
}
catch
(
e
:
ErrnoException
)
{
if
(
e
.
errno
!=
3
)
throw
e
// ESRCH
}
val
mutex
=
exitValueMutex
.
get
(
process
)
as
Object
synchronized
(
mutex
)
{
try
{
process
.
exitValue
()
}
catch
(
e
:
IllegalThreadStateException
)
{
mutex
.
wait
(
500
)
}
}
}
process
.
destroy
()
process
.
waitFor
()
// ensure the process is destroyed
...
...
core/src/main/jni/jni-helper.cpp
View file @
bb8cc7d4
...
...
@@ -2,20 +2,13 @@
#include "jni.h"
#include <android/log.h>
#include <sys/system_properties.h>
#include <algorithm>
#include <cerrno>
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ancillary.h>
...
...
@@ -24,50 +17,9 @@ using namespace std;
#define LOGI(...) do { __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__); } while(0)
#define LOGW(...) do { __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__); } while(0)
#define LOGE(...) do { __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__); } while(0)
#define THROW(env, clazz, msg) do { env->ThrowNew(env->FindClass(clazz), msg); } while (0)
static
int
sdk_version
;
static
jclass
ProcessImpl
;
static
jfieldID
ProcessImpl_pid
,
ProcessImpl_exitValue
,
ProcessImpl_exitValueMutex
;
#pragma clang diagnostic ignored "-Wunused-parameter"
extern
"C"
{
JNIEXPORT
jint
JNICALL
Java_com_github_shadowsocks_JniHelper_sigkill
(
JNIEnv
*
env
,
jobject
thiz
,
jint
pid
)
{
// Suppress "No such process" errors. We just want the process killed. It's fine if it's already killed.
return
kill
(
pid
,
SIGKILL
)
==
-
1
&&
errno
!=
ESRCH
?
errno
:
0
;
}
JNIEXPORT
jint
JNICALL
Java_com_github_shadowsocks_JniHelper_sigterm
(
JNIEnv
*
env
,
jobject
thiz
,
jobject
process
)
{
if
(
!
env
->
IsInstanceOf
(
process
,
ProcessImpl
))
{
THROW
(
env
,
"java/lang/ClassCastException"
,
"Unsupported process object. Only java.lang.ProcessManager$ProcessImpl is accepted."
);
return
-
1
;
}
jint
pid
=
env
->
GetIntField
(
process
,
ProcessImpl_pid
);
// Suppress "No such process" errors. We just want the process killed. It's fine if it's already killed.
return
kill
(
pid
,
SIGTERM
)
==
-
1
&&
errno
!=
ESRCH
?
errno
:
0
;
}
JNIEXPORT
jobject
JNICALL
Java_com_github_shadowsocks_JniHelper_getExitValue
(
JNIEnv
*
env
,
jobject
thiz
,
jobject
process
)
{
if
(
!
env
->
IsInstanceOf
(
process
,
ProcessImpl
))
{
THROW
(
env
,
"java/lang/ClassCastException"
,
"Unsupported process object. Only java.lang.ProcessManager$ProcessImpl is accepted."
);
return
NULL
;
}
return
env
->
GetObjectField
(
process
,
ProcessImpl_exitValue
);
}
JNIEXPORT
jobject
JNICALL
Java_com_github_shadowsocks_JniHelper_getExitValueMutex
(
JNIEnv
*
env
,
jobject
thiz
,
jobject
process
)
{
if
(
!
env
->
IsInstanceOf
(
process
,
ProcessImpl
))
{
THROW
(
env
,
"java/lang/ClassCastException"
,
"Unsupported process object. Only java.lang.ProcessManager$ProcessImpl is accepted."
);
return
NULL
;
}
return
env
->
GetObjectField
(
process
,
ProcessImpl_exitValueMutex
);
}
JNIEXPORT
jint
JNICALL
Java_com_github_shadowsocks_JniHelper_sendFd
(
JNIEnv
*
env
,
jobject
thiz
,
jint
tun_fd
,
jstring
path
)
{
int
fd
;
...
...
@@ -120,50 +72,7 @@ Java_com_github_shadowsocks_JniHelper_parseNumericAddress(JNIEnv *env, jobject t
/*
* This is called by the VM when the shared library is first loaded.
*/
typedef
union
{
JNIEnv
*
env
;
void
*
venv
;
}
UnionJNIEnvToVoid
;
#pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
jint
JNI_OnLoad
(
JavaVM
*
vm
,
void
*
reserved
)
{
UnionJNIEnvToVoid
uenv
;
uenv
.
venv
=
NULL
;
jint
result
=
-
1
;
JNIEnv
*
env
=
NULL
;
if
(
vm
->
GetEnv
(
&
uenv
.
venv
,
JNI_VERSION_1_6
)
!=
JNI_OK
)
{
THROW
(
env
,
"java/lang/RuntimeException"
,
"GetEnv failed"
);
goto
bail
;
}
env
=
uenv
.
env
;
char
version
[
PROP_VALUE_MAX
+
1
];
__system_property_get
(
"ro.build.version.sdk"
,
version
);
sdk_version
=
atoi
(
version
);
#define FIND_CLASS(out, name) \
if (!(out = env->FindClass(name))) { \
THROW(env, "java/lang/RuntimeException", name " not found"); \
goto bail; \
} \
out = reinterpret_cast<jclass>(env->NewGlobalRef(reinterpret_cast<jobject>(out)))
#define GET_FIELD(out, clazz, name, sig) \
if (!(out = env->GetFieldID(clazz, name, sig))) { \
THROW(env, "java/lang/RuntimeException", "Field " #clazz "." name " with type " sig " not found"); \
goto bail; \
}
if
(
sdk_version
<
24
)
{
FIND_CLASS
(
ProcessImpl
,
"java/lang/ProcessManager$ProcessImpl"
);
GET_FIELD
(
ProcessImpl_pid
,
ProcessImpl
,
"pid"
,
"I"
)
GET_FIELD
(
ProcessImpl_exitValue
,
ProcessImpl
,
"exitValue"
,
"Ljava/lang/Integer;"
)
GET_FIELD
(
ProcessImpl_exitValueMutex
,
ProcessImpl
,
"exitValueMutex"
,
"Ljava/lang/Object;"
)
}
result
=
JNI_VERSION_1_6
;
bail:
return
result
;
return
JNI_VERSION_1_6
;
}
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