1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2024-12-23 11:21:29 +00:00

Kill the Syncthing Process before resorting to shell-based kill

Conflicts:
	src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingRunnable.java
This commit is contained in:
Lode Hoste 2015-05-04 10:05:17 +02:00
parent b32ac0b13e
commit 767177e28d

View file

@ -13,6 +13,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/** /**
* Runs the syncthing binary from command line, and prints its output to logcat. * Runs the syncthing binary from command line, and prints its output to logcat.
@ -29,11 +30,15 @@ public class SyncthingRunnable implements Runnable {
public static final String UNIT_TEST_PATH = "was running"; public static final String UNIT_TEST_PATH = "was running";
private static final AtomicReference<Process> mSyncthing = new AtomicReference<>();
private final Context mContext; private final Context mContext;
private boolean mGenerate; private boolean mGenerate;
private String mCommand; private String mSyncthingBinary;
private String[] mCommand;
public enum Command { public enum Command {
generate, // Generate keys, a config file and immediately exit. generate, // Generate keys, a config file and immediately exit.
@ -48,16 +53,16 @@ public class SyncthingRunnable implements Runnable {
*/ */
public SyncthingRunnable(Context context, Command command) { public SyncthingRunnable(Context context, Command command) {
mContext = context; mContext = context;
String syncthing = mContext.getApplicationInfo().dataDir + "/" + SyncthingService.BINARY_NAME; mSyncthingBinary = mContext.getApplicationInfo().dataDir + "/" + SyncthingService.BINARY_NAME;
switch (command) { switch (command) {
case generate: case generate:
mCommand = syncthing + " -generate='" + mContext.getFilesDir() + "' -no-browser"; mCommand = new String[]{ mSyncthingBinary, "-generate", mContext.getFilesDir().toString() };
break; break;
case main: case main:
mCommand = syncthing + " -home='" + mContext.getFilesDir() + "' -no-browser"; mCommand = new String[]{ mSyncthingBinary, "-home", mContext.getFilesDir().toString(), "-no-browser" };
break; break;
case reset: case reset:
mCommand = syncthing + " -home='" + mContext.getFilesDir() + "' -reset"; mCommand = new String[]{ mSyncthingBinary, "-home", mContext.getFilesDir().toString(), "-reset" };
break; break;
default: default:
Log.w(TAG, "Unknown command option"); Log.w(TAG, "Unknown command option");
@ -72,14 +77,21 @@ public class SyncthingRunnable implements Runnable {
*/ */
public SyncthingRunnable(Context context, String manualCommand) { public SyncthingRunnable(Context context, String manualCommand) {
mContext = context; mContext = context;
mCommand = manualCommand; mCommand = new String[] { manualCommand };
} }
@Override @Override
public void run() { public void run() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
DataOutputStream dos = null;
int ret = 1; int ret = 1;
// Make sure Syncthing is executable
try {
ProcessBuilder pb = new ProcessBuilder("chmod", "+x", mSyncthingBinary);
pb.start().waitFor();
} catch (IOException|InterruptedException e) {
Log.w(TAG, "Failed to chmod Syncthing", e);
}
// Loop Syncthing
Process process = null; Process process = null;
try { try {
// Loop to handle Syncthing restarts (these always have an error code of 3). // Loop to handle Syncthing restarts (these always have an error code of 3).
@ -94,16 +106,7 @@ public class SyncthingRunnable implements Runnable {
env.put("STGUIAUTH", sp.getString("gui_user", "") + ":" + env.put("STGUIAUTH", sp.getString("gui_user", "") + ":" +
sp.getString("gui_password", "")); sp.getString("gui_password", ""));
process = pb.start(); process = pb.start();
mSyncthing.set(process);
dos = new DataOutputStream(process.getOutputStream());
// Set (Android) home directory to data folder for syncthing to use.
dos.writeBytes("HOME=" + Environment.getExternalStorageDirectory() + " ");
dos.writeBytes("STTRACE=" + pm.getString("sttrace", "") + " ");
dos.writeBytes("STNORESTART=1 ");
dos.writeBytes("STNOUPGRADE=1 ");
dos.writeBytes(mCommand);
dos.writeBytes("\nexit\n");
dos.flush();
log(process.getInputStream(), Log.INFO); log(process.getInputStream(), Log.INFO);
log(process.getErrorStream(), Log.WARN); log(process.getErrorStream(), Log.WARN);
@ -111,6 +114,7 @@ public class SyncthingRunnable implements Runnable {
niceSyncthing(); niceSyncthing();
ret = process.waitFor(); ret = process.waitFor();
mSyncthing.set(null);
if (ret == 3) { if (ret == 3) {
Log.i(TAG, "Restarting syncthing"); Log.i(TAG, "Restarting syncthing");
@ -121,12 +125,6 @@ public class SyncthingRunnable implements Runnable {
} catch (IOException | InterruptedException e) { } catch (IOException | InterruptedException e) {
Log.e(TAG, "Failed to execute syncthing binary or read output", e); Log.e(TAG, "Failed to execute syncthing binary or read output", e);
} finally { } finally {
try {
if (dos != null)
dos.close();
} catch (IOException e) {
Log.w(TAG, "Failed to close shell stream", e);
}
if (process != null) if (process != null)
process.destroy(); process.destroy();
if (ret != 0) { if (ret != 0) {
@ -149,7 +147,7 @@ public class SyncthingRunnable implements Runnable {
Thread.sleep(1000); // Wait a second before getting the pid Thread.sleep(1000); // Wait a second before getting the pid
nice = Runtime.getRuntime().exec("sh"); nice = Runtime.getRuntime().exec("sh");
niceOut = new DataOutputStream(nice.getOutputStream()); niceOut = new DataOutputStream(nice.getOutputStream());
niceOut.writeBytes("set `ps |grep libsyncthing.so`\n"); niceOut.writeBytes("set `ps | grep libsyncthing.so`\n");
niceOut.writeBytes("ionice $2 be 7\n"); // best-effort, low priority niceOut.writeBytes("ionice $2 be 7\n"); // best-effort, low priority
niceOut.writeBytes("exit\n"); niceOut.writeBytes("exit\n");
log(nice.getErrorStream(), Log.WARN); log(nice.getErrorStream(), Log.WARN);
@ -183,6 +181,18 @@ public class SyncthingRunnable implements Runnable {
* *
*/ */
public static void killSyncthing() { public static void killSyncthing() {
final Process p = mSyncthing.get();
if (p != null) {
mSyncthing.set(null);
p.destroy();
try {
p.waitFor();
} catch (InterruptedException e) {
Log.w(TAG_KILL, "Failed to kill Syncthing's process", e);
}
}
// Ensure kill
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
Process ps = null; Process ps = null;
DataOutputStream psOut = null; DataOutputStream psOut = null;