Migrate from ant to gradle
This commit is contained in:
211
src/main/java/com/sheepit/client/os/FreeBSD.java
Normal file
211
src/main/java/com/sheepit/client/os/FreeBSD.java
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 Laurent CLOUET
|
||||
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package com.sheepit.client.os;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import com.sheepit.client.Log;
|
||||
import com.sheepit.client.hardware.cpu.CPU;
|
||||
|
||||
public class FreeBSD extends OS {
|
||||
private final String NICE_BINARY_PATH = "nice";
|
||||
private Boolean hasNiceBinary;
|
||||
|
||||
public FreeBSD() {
|
||||
super();
|
||||
this.hasNiceBinary = null;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "freebsd";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderBinaryPath() {
|
||||
return "rend.exe";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPU getCPU() {
|
||||
CPU ret = new CPU();
|
||||
try {
|
||||
Runtime r = Runtime.getRuntime();
|
||||
Process p = r.exec("dmesg");
|
||||
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
String line = "";
|
||||
|
||||
while ((line = b.readLine()) != null) {
|
||||
if (line.startsWith("CPU:")) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 1) {
|
||||
ret.setName(buf[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (line.contains("Family=") && line.contains("Model=")) {
|
||||
String buf[] = line.split(" ");
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
if (buf[i].contains("Family")) {
|
||||
String family = buf[i].split("=")[1];
|
||||
ret.setFamily(family.split("x")[1]);
|
||||
}
|
||||
|
||||
if (buf[i].contains("Model")) {
|
||||
String model = buf[i].split("=")[1];
|
||||
ret.setModel(model.split("x")[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
b.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (ret.haveData() == false) {
|
||||
Log.getInstance(null).debug("OS::FreeBSD::getCPU failed to get CPU from dmesg, using partia sysctl");
|
||||
ret.setModel("0");
|
||||
ret.setFamily("0");
|
||||
try {
|
||||
Runtime run = Runtime.getRuntime();
|
||||
Process sysctl = run.exec("sysctl -n hw.model");
|
||||
BufferedReader buf = new BufferedReader(new InputStreamReader(sysctl.getInputStream()));
|
||||
String name = "";
|
||||
|
||||
name = buf.readLine();
|
||||
buf.close();
|
||||
if (name == "") {
|
||||
ret.setName("0");
|
||||
}
|
||||
else {
|
||||
ret.setName(name);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.getInstance(null).debug("OS::FreeBSD::getCPU exception " + e);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMemory() {
|
||||
try {
|
||||
Runtime r = Runtime.getRuntime();
|
||||
Process p = r.exec("sysctl -n hw.usermem");
|
||||
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
String line = "";
|
||||
|
||||
line = b.readLine();
|
||||
b.close();
|
||||
if (line.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
Long mem_byte = Long.parseLong(line.trim());
|
||||
return mem_byte / Long.valueOf(1024);
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.getInstance(null).debug("OS::FreeBSD::getMemory exception " + e);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreeMemory() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCUDALib() {
|
||||
return "cuda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
|
||||
// the renderer have a lib directory so add to the LD_LIBRARY_PATH
|
||||
// (even if we are not sure that it is the renderer who is launch
|
||||
|
||||
Map<String, String> new_env = new HashMap<String, String>();
|
||||
new_env.putAll(java.lang.System.getenv()); // clone the env
|
||||
Boolean has_ld_library_path = new_env.containsKey("LD_LIBRARY_PATH");
|
||||
|
||||
String lib_dir = (new File(command.get(0))).getParent() + File.separator + "lib";
|
||||
if (has_ld_library_path == false) {
|
||||
new_env.put("LD_LIBRARY_PATH", lib_dir);
|
||||
}
|
||||
else {
|
||||
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + lib_dir);
|
||||
}
|
||||
|
||||
List<String> actual_command = command;
|
||||
if (this.hasNiceBinary == null) {
|
||||
this.checkNiceAvailability();
|
||||
}
|
||||
if (this.hasNiceBinary.booleanValue()) {
|
||||
// launch the process in lowest priority
|
||||
if (env_overight != null) {
|
||||
actual_command.add(0, env_overight.get("PRIORITY"));
|
||||
}
|
||||
else {
|
||||
actual_command.add(0, "19");
|
||||
}
|
||||
actual_command.add(0, "-n");
|
||||
actual_command.add(0, NICE_BINARY_PATH);
|
||||
}
|
||||
else {
|
||||
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal priority");
|
||||
}
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder(actual_command);
|
||||
builder.redirectErrorStream(true);
|
||||
Map<String, String> env = builder.environment();
|
||||
env.putAll(new_env);
|
||||
if (env_overight != null) {
|
||||
env.putAll(env_overight);
|
||||
}
|
||||
return builder.start();
|
||||
}
|
||||
|
||||
private void checkNiceAvailability() {
|
||||
ProcessBuilder builder = new ProcessBuilder();
|
||||
builder.command(NICE_BINARY_PATH);
|
||||
builder.redirectErrorStream(true);
|
||||
Process process = null;
|
||||
try {
|
||||
process = builder.start();
|
||||
this.hasNiceBinary = true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
this.hasNiceBinary = false;
|
||||
Log.getInstance(null).error("Failed to find low priority binary, will not launch renderer in normal priority (" + e + ")");
|
||||
}
|
||||
finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
231
src/main/java/com/sheepit/client/os/Linux.java
Normal file
231
src/main/java/com/sheepit/client/os/Linux.java
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 Laurent CLOUET
|
||||
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package com.sheepit.client.os;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
import com.sheepit.client.Log;
|
||||
import com.sheepit.client.hardware.cpu.CPU;
|
||||
|
||||
public class Linux extends OS {
|
||||
private final String NICE_BINARY_PATH = "nice";
|
||||
private Boolean hasNiceBinary;
|
||||
|
||||
public Linux() {
|
||||
super();
|
||||
this.hasNiceBinary = null;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "linux";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderBinaryPath() {
|
||||
return "rend.exe";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPU getCPU() {
|
||||
CPU ret = new CPU();
|
||||
try {
|
||||
String filePath = "/proc/cpuinfo";
|
||||
Scanner scanner = new Scanner(new File(filePath));
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
if (line.startsWith("model name")) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 1) {
|
||||
ret.setName(buf[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (line.startsWith("cpu family")) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 1) {
|
||||
ret.setFamily(buf[1].trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (line.startsWith("model") && line.startsWith("model name") == false) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 1) {
|
||||
ret.setModel(buf[1].trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
}
|
||||
catch (java.lang.NoClassDefFoundError e) {
|
||||
System.err.println("OS.Linux::getCPU error " + e + " mostly because Scanner class was introduced by Java 5 and you are running a lower version");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMemory() {
|
||||
try {
|
||||
String filePath = "/proc/meminfo";
|
||||
Scanner scanner = new Scanner(new File(filePath));
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
|
||||
if (line.startsWith("MemTotal")) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 0) {
|
||||
Integer buf2 = new Integer(buf[1].trim().split(" ")[0]);
|
||||
return (((buf2 / 262144) + 1) * 262144); // 256*1024 = 262144
|
||||
}
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
}
|
||||
catch (java.lang.NoClassDefFoundError e) {
|
||||
System.err.println("Machine::type error " + e + " mostly because Scanner class was introducted by Java 5 and you are running a lower version");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreeMemory() {
|
||||
try {
|
||||
String filePath = "/proc/meminfo";
|
||||
Scanner scanner = new Scanner(new File(filePath));
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
|
||||
if (line.startsWith("MemAvailable")) {
|
||||
String buf[] = line.split(":");
|
||||
if (buf.length > 0) {
|
||||
Integer buf2 = new Integer(buf[1].trim().split(" ")[0]);
|
||||
return (((buf2 / 262144) + 1) * 262144); // 256*1024 = 262144
|
||||
}
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
}
|
||||
catch (java.lang.NoClassDefFoundError e) {
|
||||
System.err.println("OS::Linux::getFreeMemory error " + e + " mostly because Scanner class was introducted by Java 5 and you are running a lower version");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCUDALib() {
|
||||
return "cuda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process exec(List<String> command, Map<String, String> env_overight) throws IOException {
|
||||
// the renderer have a lib directory so add to the LD_LIBRARY_PATH
|
||||
// (even if we are not sure that it is the renderer who is launch
|
||||
|
||||
Map<String, String> new_env = new HashMap<String, String>();
|
||||
new_env.putAll(java.lang.System.getenv()); // clone the env
|
||||
Boolean has_ld_library_path = new_env.containsKey("LD_LIBRARY_PATH");
|
||||
|
||||
String lib_dir = (new File(command.get(0))).getParent() + File.separator + "lib";
|
||||
if (has_ld_library_path == false) {
|
||||
new_env.put("LD_LIBRARY_PATH", lib_dir);
|
||||
}
|
||||
else {
|
||||
new_env.put("LD_LIBRARY_PATH", new_env.get("LD_LIBRARY_PATH") + ":" + lib_dir);
|
||||
}
|
||||
|
||||
List<String> actual_command = command;
|
||||
if (this.hasNiceBinary == null) {
|
||||
this.checkNiceAvailability();
|
||||
}
|
||||
if (this.hasNiceBinary.booleanValue()) {
|
||||
// launch the process in lowest priority
|
||||
if (env_overight != null) {
|
||||
actual_command.add(0, env_overight.get("PRIORITY"));
|
||||
}
|
||||
else {
|
||||
actual_command.add(0, "19");
|
||||
}
|
||||
actual_command.add(0, "-n");
|
||||
actual_command.add(0, NICE_BINARY_PATH);
|
||||
}
|
||||
else {
|
||||
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal priority");
|
||||
}
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder(actual_command);
|
||||
builder.redirectErrorStream(true);
|
||||
Map<String, String> env = builder.environment();
|
||||
env.putAll(new_env);
|
||||
if (env_overight != null) {
|
||||
env.putAll(env_overight);
|
||||
}
|
||||
return builder.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSupportHighPriority() {
|
||||
// only the root user can create process with high (negative nice) value
|
||||
String logname = System.getenv("LOGNAME");
|
||||
String user = System.getenv("USER");
|
||||
|
||||
if ((logname != null && logname.equals("root")) || (user != null && user.equals("root"))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void checkNiceAvailability() {
|
||||
ProcessBuilder builder = new ProcessBuilder();
|
||||
builder.command(NICE_BINARY_PATH);
|
||||
builder.redirectErrorStream(true);
|
||||
Process process = null;
|
||||
try {
|
||||
process = builder.start();
|
||||
this.hasNiceBinary = true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
this.hasNiceBinary = false;
|
||||
Log.getInstance(null).error("Failed to find low priority binary, will not launch renderer in normal priority (" + e + ")");
|
||||
}
|
||||
finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
200
src/main/java/com/sheepit/client/os/Mac.java
Normal file
200
src/main/java/com/sheepit/client/os/Mac.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 Laurent CLOUET
|
||||
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package com.sheepit.client.os;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sheepit.client.Log;
|
||||
import com.sheepit.client.hardware.cpu.CPU;
|
||||
|
||||
public class Mac extends OS {
|
||||
private final String NICE_BINARY_PATH = "nice";
|
||||
private Boolean hasNiceBinary;
|
||||
|
||||
public Mac() {
|
||||
super();
|
||||
this.hasNiceBinary = null;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "mac";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderBinaryPath() {
|
||||
return "Blender" + File.separator + "blender.app" + File.separator + "Contents" + File.separator + "MacOS" + File.separator + "blender";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPU getCPU() {
|
||||
CPU ret = new CPU();
|
||||
|
||||
String command = "sysctl machdep.cpu.family machdep.cpu.brand_string";
|
||||
|
||||
Process p = null;
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
String line;
|
||||
p = Runtime.getRuntime().exec(command);
|
||||
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
|
||||
while ((line = input.readLine()) != null) {
|
||||
String option_cpu_family = "machdep.cpu.family:";
|
||||
String option_model_name = "machdep.cpu.brand_string:";
|
||||
if (line.startsWith(option_model_name)) {
|
||||
ret.setName(line.substring(option_model_name.length()).trim());
|
||||
}
|
||||
if (line.startsWith(option_cpu_family)) {
|
||||
ret.setFamily(line.substring(option_cpu_family.length()).trim());
|
||||
}
|
||||
}
|
||||
input.close();
|
||||
input = null;
|
||||
}
|
||||
catch (Exception err) {
|
||||
System.out.println("exception " + err);
|
||||
err.printStackTrace();
|
||||
ret.setName("Unknown Mac name");
|
||||
ret.setFamily("Unknown Mac family");
|
||||
}
|
||||
finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
ret.setModel("Unknown");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMemory() {
|
||||
String command = "sysctl hw.memsize";
|
||||
|
||||
Process p = null;
|
||||
BufferedReader input = null;
|
||||
try {
|
||||
String line;
|
||||
p = Runtime.getRuntime().exec(command);
|
||||
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
|
||||
while ((line = input.readLine()) != null) {
|
||||
String option = "hw.memsize:";
|
||||
if (line.startsWith(option)) {
|
||||
String memory = line.substring(option.length()).trim(); // memory in bytes
|
||||
|
||||
return Long.parseLong(memory) / 1024;
|
||||
}
|
||||
}
|
||||
input.close();
|
||||
input = null;
|
||||
}
|
||||
catch (Exception err) {
|
||||
System.out.println("exception " + err);
|
||||
err.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreeMemory() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process exec(List<String> command, Map<String, String> env) throws IOException {
|
||||
List<String> actual_command = command;
|
||||
if (this.hasNiceBinary == null) {
|
||||
this.checkNiceAvailability();
|
||||
}
|
||||
if (this.hasNiceBinary.booleanValue()) {
|
||||
// launch the process in lowest priority
|
||||
if (env != null) {
|
||||
actual_command.add(0, env.get("PRIORITY"));
|
||||
}
|
||||
else {
|
||||
actual_command.add(0, "19");
|
||||
}
|
||||
actual_command.add(0, "-n");
|
||||
actual_command.add(0, NICE_BINARY_PATH);
|
||||
}
|
||||
else {
|
||||
Log.getInstance(null).error("No low priority binary, will not launch renderer in normal priority");
|
||||
}
|
||||
ProcessBuilder builder = new ProcessBuilder(actual_command);
|
||||
builder.redirectErrorStream(true);
|
||||
if (env != null) {
|
||||
builder.environment().putAll(env);
|
||||
}
|
||||
return builder.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCUDALib() {
|
||||
return "/usr/local/cuda/lib/libcuda.dylib";
|
||||
}
|
||||
|
||||
protected void checkNiceAvailability() {
|
||||
ProcessBuilder builder = new ProcessBuilder();
|
||||
builder.command(NICE_BINARY_PATH);
|
||||
builder.redirectErrorStream(true);
|
||||
Process process = null;
|
||||
try {
|
||||
process = builder.start();
|
||||
this.hasNiceBinary = true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
this.hasNiceBinary = false;
|
||||
Log.getInstance(null).error("Failed to find low priority binary, will not launch renderer in normal priority (" + e + ")");
|
||||
}
|
||||
finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/main/java/com/sheepit/client/os/OS.java
Normal file
84
src/main/java/com/sheepit/client/os/OS.java
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 Laurent CLOUET
|
||||
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package com.sheepit.client.os;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sheepit.client.hardware.cpu.CPU;
|
||||
|
||||
public abstract class OS {
|
||||
private static OS instance = null;
|
||||
|
||||
public abstract String name();
|
||||
|
||||
public abstract CPU getCPU();
|
||||
|
||||
public abstract long getMemory();
|
||||
|
||||
public abstract long getFreeMemory();
|
||||
|
||||
public abstract String getRenderBinaryPath();
|
||||
|
||||
public String getCUDALib() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean getSupportHighPriority() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Process exec(List<String> command, Map<String, String> env) throws IOException {
|
||||
ProcessBuilder builder = new ProcessBuilder(command);
|
||||
builder.redirectErrorStream(true);
|
||||
if (env != null) {
|
||||
builder.environment().putAll(env);
|
||||
}
|
||||
return builder.start();
|
||||
}
|
||||
|
||||
public boolean kill(Process proc) {
|
||||
if (proc != null) {
|
||||
proc.destroy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static OS getOS() {
|
||||
if (instance == null) {
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
if (os.contains("win")) {
|
||||
instance = new Windows();
|
||||
}
|
||||
else if (os.contains("mac")) {
|
||||
instance = new Mac();
|
||||
}
|
||||
else if (os.contains("nix") || os.contains("nux")) {
|
||||
instance = new Linux();
|
||||
}
|
||||
else if (os.contains("freebsd")) {
|
||||
instance = new FreeBSD();
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
228
src/main/java/com/sheepit/client/os/Windows.java
Normal file
228
src/main/java/com/sheepit/client/os/Windows.java
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2014 Laurent CLOUET
|
||||
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
package com.sheepit.client.os;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sheepit.client.hardware.cpu.CPU;
|
||||
import com.sheepit.client.os.windows.Kernel32Lib;
|
||||
import com.sheepit.client.os.windows.WinProcess;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.platform.win32.Advapi32Util;
|
||||
import com.sun.jna.platform.win32.Kernel32;
|
||||
import com.sun.jna.platform.win32.WinBase.MEMORYSTATUSEX;
|
||||
import com.sun.jna.platform.win32.WinReg;
|
||||
|
||||
public class Windows extends OS {
|
||||
|
||||
public String name() {
|
||||
return "windows";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderBinaryPath() {
|
||||
return "rend.exe";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPU getCPU() {
|
||||
CPU ret = new CPU();
|
||||
try {
|
||||
String[] identifier = java.lang.System.getenv("PROCESSOR_IDENTIFIER").split(" ");
|
||||
for (int i = 0; i < (identifier.length - 1); i++) {
|
||||
if (identifier[i].equals("Family")) {
|
||||
ret.setFamily(identifier[i + 1]);
|
||||
}
|
||||
if (identifier[i].equals("Model")) {
|
||||
ret.setModel(identifier[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
final String cpuRegistryRoot = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
|
||||
String[] processorIds = Advapi32Util.registryGetKeys(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryRoot);
|
||||
if (processorIds.length > 0) {
|
||||
String processorId = processorIds[0];
|
||||
String cpuRegistryPath = cpuRegistryRoot + "\\" + processorId;
|
||||
ret.setName(Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryPath, "ProcessorNameString").trim());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// override the arch
|
||||
String env_arch = java.lang.System.getenv("PROCESSOR_ARCHITEW6432");
|
||||
if (env_arch == null || env_arch.compareTo("") == 0) {
|
||||
env_arch = java.lang.System.getenv("PROCESSOR_ARCHITECTURE");
|
||||
}
|
||||
if (env_arch.compareTo("AMD64") == 0) {
|
||||
ret.setArch("64bit");
|
||||
}
|
||||
else {
|
||||
ret.setArch("32bit");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMemory() {
|
||||
try {
|
||||
MEMORYSTATUSEX _memory = new MEMORYSTATUSEX();
|
||||
if (Kernel32.INSTANCE.GlobalMemoryStatusEx(_memory)) {
|
||||
return _memory.ullTotalPhys.longValue() / 1024; // size in KB
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreeMemory() {
|
||||
try {
|
||||
MEMORYSTATUSEX _memory = new MEMORYSTATUSEX();
|
||||
if (Kernel32.INSTANCE.GlobalMemoryStatusEx(_memory)) {
|
||||
return _memory.ullAvailPhys.longValue() / 1024; // size in KB
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCUDALib() {
|
||||
return "nvcuda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process exec(List<String> command, Map<String, String> env) throws IOException {
|
||||
// disable a popup because the renderer might crash (seg fault)
|
||||
Kernel32Lib kernel32lib = null;
|
||||
try {
|
||||
kernel32lib = (Kernel32Lib) Native.loadLibrary(Kernel32Lib.path, Kernel32Lib.class);
|
||||
kernel32lib.SetErrorMode(Kernel32Lib.SEM_NOGPFAULTERRORBOX);
|
||||
}
|
||||
catch (java.lang.UnsatisfiedLinkError e) {
|
||||
System.out.println("OS.Windows::exec failed to load kernel32lib " + e);
|
||||
}
|
||||
catch (java.lang.ExceptionInInitializerError e) {
|
||||
System.out.println("OS.Windows::exec failed to load kernel32lib " + e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("OS.Windows::exec failed to load kernel32lib " + e);
|
||||
}
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder(command);
|
||||
builder.redirectErrorStream(true);
|
||||
if (env != null) {
|
||||
builder.environment().putAll(env);
|
||||
}
|
||||
Process p = builder.start();
|
||||
WinProcess wproc = new WinProcess(p);
|
||||
if (env != null) {
|
||||
String priority = env.get("PRIORITY");
|
||||
wproc.setPriority(getPriorityClass(Integer.parseInt(priority)));
|
||||
}
|
||||
else {
|
||||
wproc.setPriority(WinProcess.PRIORITY_BELOW_NORMAL);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int getPriorityClass(int priority) {
|
||||
int process_class = WinProcess.PRIORITY_IDLE;
|
||||
switch (priority) {
|
||||
case 19:
|
||||
case 18:
|
||||
case 17:
|
||||
case 16:
|
||||
case 15:
|
||||
process_class = WinProcess.PRIORITY_IDLE;
|
||||
break;
|
||||
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8:
|
||||
case 7:
|
||||
case 6:
|
||||
case 5:
|
||||
process_class = WinProcess.PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
case 4:
|
||||
case 3:
|
||||
case 2:
|
||||
case 1:
|
||||
case 0:
|
||||
case -1:
|
||||
case -2:
|
||||
case -3:
|
||||
process_class = WinProcess.PRIORITY_NORMAL;
|
||||
break;
|
||||
case -4:
|
||||
case -5:
|
||||
case -6:
|
||||
case -7:
|
||||
case -8:
|
||||
case -9:
|
||||
process_class = WinProcess.PRIORITY_ABOVE_NORMAL;
|
||||
break;
|
||||
case -10:
|
||||
case -11:
|
||||
case -12:
|
||||
case -13:
|
||||
case -14:
|
||||
process_class = WinProcess.PRIORITY_HIGH;
|
||||
break;
|
||||
case -15:
|
||||
case -16:
|
||||
case -17:
|
||||
case -18:
|
||||
case -19:
|
||||
process_class = WinProcess.PRIORITY_REALTIME;
|
||||
break;
|
||||
}
|
||||
return process_class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kill(Process process) {
|
||||
if (process != null) {
|
||||
WinProcess wproc = new WinProcess(process);
|
||||
wproc.kill();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
214
src/main/java/com/sheepit/client/os/windows/Kernel32Lib.java
Normal file
214
src/main/java/com/sheepit/client/os/windows/Kernel32Lib.java
Normal file
@@ -0,0 +1,214 @@
|
||||
/* This file was originally taken from JNA project (https://github.com/twall/jna)
|
||||
* filename: contrib/platform/src/com/sun/jna/platform/win32/Tlhelp32.java
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
package com.sheepit.client.os.windows;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.BaseTSD;
|
||||
import com.sun.jna.platform.win32.WinDef;
|
||||
import com.sun.jna.platform.win32.WinDef.DWORD;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
|
||||
public interface Kernel32Lib extends Library {
|
||||
public static final String path = "kernel32";
|
||||
|
||||
/**
|
||||
* Includes all heaps of the process specified in th32ProcessID in the snapshot. To enumerate the heaps, see
|
||||
* Heap32ListFirst.
|
||||
*/
|
||||
WinDef.DWORD TH32CS_SNAPHEAPLIST = new WinDef.DWORD(0x00000001);
|
||||
|
||||
/**
|
||||
* Includes all processes in the system in the snapshot. To enumerate the processes, see Process32First.
|
||||
*/
|
||||
WinDef.DWORD TH32CS_SNAPPROCESS = new WinDef.DWORD(0x00000002);
|
||||
|
||||
/**
|
||||
* Includes all threads in the system in the snapshot. To enumerate the threads, see Thread32First.
|
||||
*/
|
||||
WinDef.DWORD TH32CS_SNAPTHREAD = new WinDef.DWORD(0x00000004);
|
||||
|
||||
/**
|
||||
* Includes all modules of the process specified in th32ProcessID in the snapshot. To enumerate the modules, see
|
||||
* Module32First. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds.
|
||||
*/
|
||||
WinDef.DWORD TH32CS_SNAPMODULE = new WinDef.DWORD(0x00000008);
|
||||
|
||||
/**
|
||||
* Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit
|
||||
* process. This flag can be combined with TH32CS_SNAPMODULE or TH32CS_SNAPALL. If the function fails with
|
||||
* ERROR_BAD_LENGTH, retry the function until it succeeds.
|
||||
*/
|
||||
WinDef.DWORD TH32CS_SNAPMODULE32 = new WinDef.DWORD(0x00000010);
|
||||
|
||||
/**
|
||||
* Includes all processes and threads in the system, plus the heaps and modules of the process specified in th32ProcessID.
|
||||
*/
|
||||
WinDef.DWORD TH32CS_SNAPALL = new WinDef.DWORD((TH32CS_SNAPHEAPLIST.intValue() | TH32CS_SNAPPROCESS.intValue() | TH32CS_SNAPTHREAD.intValue() | TH32CS_SNAPMODULE.intValue()));
|
||||
|
||||
/**
|
||||
* Indicates that the snapshot handle is to be inheritable.
|
||||
*/
|
||||
WinDef.DWORD TH32CS_INHERIT = new WinDef.DWORD(0x80000000);
|
||||
|
||||
/**
|
||||
* The system does not display the Windows Error Reporting dialog.
|
||||
* See: http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx
|
||||
*/
|
||||
WinDef.DWORD SEM_NOGPFAULTERRORBOX = new WinDef.DWORD(0x0002);
|
||||
|
||||
/**
|
||||
* Describes an entry from a list of the processes residing in the system address space when a snapshot was taken.
|
||||
*/
|
||||
public static class PROCESSENTRY32 extends Structure {
|
||||
|
||||
public static class ByReference extends PROCESSENTRY32 implements Structure.ByReference {
|
||||
public ByReference() {
|
||||
}
|
||||
|
||||
public ByReference(Pointer memory) {
|
||||
super(memory);
|
||||
}
|
||||
}
|
||||
|
||||
public PROCESSENTRY32() {
|
||||
dwSize = new WinDef.DWORD(size());
|
||||
}
|
||||
|
||||
public PROCESSENTRY32(Pointer memory) {
|
||||
useMemory(memory);
|
||||
read();
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the structure, in bytes. Before calling the Process32First function, set this member to
|
||||
* sizeof(PROCESSENTRY32). If you do not initialize dwSize, Process32First fails.
|
||||
*/
|
||||
public WinDef.DWORD dwSize;
|
||||
|
||||
/**
|
||||
* This member is no longer used and is always set to zero.
|
||||
*/
|
||||
public WinDef.DWORD cntUsage;
|
||||
|
||||
/**
|
||||
* The process identifier.
|
||||
*/
|
||||
public WinDef.DWORD th32ProcessID;
|
||||
|
||||
/**
|
||||
* This member is no longer used and is always set to zero.
|
||||
*/
|
||||
public BaseTSD.ULONG_PTR th32DefaultHeapID;
|
||||
|
||||
/**
|
||||
* This member is no longer used and is always set to zero.
|
||||
*/
|
||||
public WinDef.DWORD th32ModuleID;
|
||||
|
||||
/**
|
||||
* The number of execution threads started by the process.
|
||||
*/
|
||||
public WinDef.DWORD cntThreads;
|
||||
|
||||
/**
|
||||
* The identifier of the process that created this process (its parent process).
|
||||
*/
|
||||
public WinDef.DWORD th32ParentProcessID;
|
||||
|
||||
/**
|
||||
* The base priority of any threads created by this process.
|
||||
*/
|
||||
public WinDef.LONG pcPriClassBase;
|
||||
|
||||
/**
|
||||
* This member is no longer used, and is always set to zero.
|
||||
*/
|
||||
public WinDef.DWORD dwFlags;
|
||||
|
||||
/**
|
||||
* The name of the executable file for the process. To retrieve the full path to the executable file, call the
|
||||
* Module32First function and check the szExePath member of the MODULEENTRY32 structure that is returned.
|
||||
* However, if the calling process is a 32-bit process, you must call the QueryFullProcessImageName function to
|
||||
* retrieve the full path of the executable file for a 64-bit process.
|
||||
*/
|
||||
public char[] szExeFile = new char[WinDef.MAX_PATH];
|
||||
|
||||
@Override
|
||||
protected List getFieldOrder() {
|
||||
return Arrays.asList(new String[] { "dwSize", "cntUsage", "th32ProcessID", "th32DefaultHeapID", "th32ModuleID", "cntThreads", "th32ParentProcessID", "pcPriClassBase", "dwFlags", "szExeFile" });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.
|
||||
*
|
||||
* @param dwFlags The portions of the system to be included in the snapshot.
|
||||
* @param th32ProcessID The process identifier of the process to be included in the snapshot. This parameter can be zero to indicate
|
||||
* the current process. This parameter is used when the TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE,
|
||||
* TH32CS_SNAPMODULE32, or TH32CS_SNAPALL value is specified. Otherwise, it is ignored and all processes are
|
||||
* included in the snapshot.
|
||||
* <p/>
|
||||
* If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last
|
||||
* error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.
|
||||
* <p/>
|
||||
* If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the
|
||||
* last error code is ERROR_PARTIAL_COPY (299).
|
||||
* @return If the function succeeds, it returns an open handle to the specified snapshot.
|
||||
* <p/>
|
||||
* If the function fails, it returns INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
|
||||
* Possible error codes include ERROR_BAD_LENGTH.
|
||||
*/
|
||||
public WinNT.HANDLE CreateToolhelp32Snapshot(WinDef.DWORD dwFlags, WinDef.DWORD th32ProcessID);
|
||||
|
||||
/**
|
||||
* Retrieves information about the first process encountered in a system snapshot.
|
||||
*
|
||||
* @param hSnapshot A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
|
||||
* @param lppe A pointer to a PROCESSENTRY32 structure. It contains process information such as the name of the
|
||||
* executable file, the process identifier, and the process identifier of the parent process.
|
||||
* @return Returns TRUE if the first entry of the process list has been copied to the buffer or FALSE otherwise. The
|
||||
* ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot
|
||||
* does not contain process information.
|
||||
*/
|
||||
public boolean Process32First(WinNT.HANDLE hSnapshot, Kernel32Lib.PROCESSENTRY32.ByReference lppe);
|
||||
|
||||
/**
|
||||
* Retrieves information about the next process recorded in a system snapshot.
|
||||
*
|
||||
* @param hSnapshot A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
|
||||
* @param lppe A pointer to a PROCESSENTRY32 structure.
|
||||
* @return Returns TRUE if the next entry of the process list has been copied to the buffer or FALSE otherwise. The
|
||||
* ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot
|
||||
* does not contain process information.
|
||||
*/
|
||||
public boolean Process32Next(WinNT.HANDLE hSnapshot, Kernel32Lib.PROCESSENTRY32.ByReference lppe);
|
||||
|
||||
public boolean SetPriorityClass(HANDLE hProcess, int dwPriorityClass);
|
||||
|
||||
/**
|
||||
* Controls whether the system will handle the specified types of serious errors or whether the process will handle them.
|
||||
* See: http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx
|
||||
*
|
||||
* @param uMode The process error mode. This parameter can be one or more of the following values.
|
||||
*/
|
||||
public int SetErrorMode(DWORD uMode);
|
||||
|
||||
}
|
||||
194
src/main/java/com/sheepit/client/os/windows/WinProcess.java
Normal file
194
src/main/java/com/sheepit/client/os/windows/WinProcess.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Laurent CLOUET
|
||||
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package com.sheepit.client.os.windows;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.Kernel32;
|
||||
import com.sun.jna.platform.win32.Kernel32Util;
|
||||
import com.sun.jna.platform.win32.WinDef.DWORD;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
|
||||
public class WinProcess {
|
||||
public static final int PRIORITY_IDLE = 0x40;
|
||||
public static final int PRIORITY_BELOW_NORMAL = 0x4000;
|
||||
public static final int PRIORITY_NORMAL = 0x20;
|
||||
public static final int PRIORITY_ABOVE_NORMAL = 0x8000;
|
||||
public static final int PRIORITY_HIGH = 0x80;
|
||||
public static final int PRIORITY_REALTIME = 0x100;
|
||||
|
||||
private WinNT.HANDLE handle;
|
||||
private int pid;
|
||||
Kernel32Lib kernel32lib;
|
||||
|
||||
public WinProcess() {
|
||||
this.handle = null;
|
||||
this.pid = -1;
|
||||
this.kernel32lib = null;
|
||||
try {
|
||||
this.kernel32lib = (Kernel32Lib) Native.loadLibrary(Kernel32Lib.path, Kernel32Lib.class);
|
||||
}
|
||||
catch (java.lang.UnsatisfiedLinkError e) {
|
||||
System.out.println("WinProcess::construct " + e);
|
||||
}
|
||||
catch (java.lang.ExceptionInInitializerError e) {
|
||||
System.out.println("WinProcess::construct " + e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("WinProcess::construct " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean processHasGetPid() {
|
||||
try {
|
||||
if (Process.class.getMethod("pid", null) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException | SecurityException e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static long getPid(Process process) {
|
||||
try {
|
||||
return (long) Process.class.getMethod("pid", null).invoke(process, null);
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static WinNT.HANDLE getHandleByPid(int pid_) throws IOException {
|
||||
WinNT.HANDLE handle = Kernel32.INSTANCE.OpenProcess(0x0400 | // PROCESS_QUERY_INFORMATION
|
||||
0x0800 | // PROCESS_SUSPEND_RESUME
|
||||
0x0001 | // PROCESS_TERMINATE
|
||||
0x0200 | // PROCESS_SET_INFORMATION
|
||||
0x00100000, // SYNCHRONIZE
|
||||
false, pid_);
|
||||
if (handle == null) {
|
||||
throw new IOException("OpenProcess failed: " + Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE.GetLastError()) + " (pid: " + pid_ + ")");
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
public WinProcess(Process process) {
|
||||
this();
|
||||
if (processHasGetPid()) {
|
||||
int _pid = (int) getPid(process);
|
||||
try {
|
||||
this.handle = getHandleByPid(_pid);
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
this.pid = _pid;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Field f = process.getClass().getDeclaredField("handle");
|
||||
f.setAccessible(true);
|
||||
long val = f.getLong(process);
|
||||
this.handle = new WinNT.HANDLE();
|
||||
this.handle.setPointer(Pointer.createConstant(val));
|
||||
this.pid = Kernel32.INSTANCE.GetProcessId(this.handle);
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public WinProcess(int pid_) throws IOException {
|
||||
this();
|
||||
this.handle = getHandleByPid(pid_);
|
||||
this.pid = pid_;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (this.handle != null) {
|
||||
// Kernel32.INSTANCE.CloseHandle(this.handle); // do not close the handle because the parent Process object might still be alive
|
||||
this.handle = null;
|
||||
}
|
||||
this.pid = -1;
|
||||
}
|
||||
|
||||
public boolean kill() {
|
||||
try {
|
||||
List<WinProcess> children = this.getChildren();
|
||||
this.terminate();
|
||||
for (WinProcess child : children) {
|
||||
child.kill();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setPriority(int priority) {
|
||||
return this.kernel32lib.SetPriorityClass(this.handle, priority);
|
||||
}
|
||||
|
||||
private void terminate() {
|
||||
Kernel32.INSTANCE.TerminateProcess(this.handle, 0);
|
||||
Kernel32.INSTANCE.CloseHandle(this.handle); // we are sure that the parent Process object is dead
|
||||
}
|
||||
|
||||
private List<WinProcess> getChildren() throws IOException {
|
||||
ArrayList<WinProcess> result = new ArrayList<WinProcess>();
|
||||
|
||||
WinNT.HANDLE hSnap = this.kernel32lib.CreateToolhelp32Snapshot(Kernel32Lib.TH32CS_SNAPPROCESS, new DWORD(0));
|
||||
Kernel32Lib.PROCESSENTRY32.ByReference ent = new Kernel32Lib.PROCESSENTRY32.ByReference();
|
||||
if (!this.kernel32lib.Process32First(hSnap, ent)) {
|
||||
return result;
|
||||
}
|
||||
do {
|
||||
if (ent.th32ParentProcessID.intValue() == this.pid) {
|
||||
try {
|
||||
result.add(new WinProcess(ent.th32ProcessID.intValue()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println("WinProcess::getChildren, IOException " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (this.kernel32lib.Process32Next(hSnap, ent));
|
||||
|
||||
Kernel32.INSTANCE.CloseHandle(hSnap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "WinProcess(pid: " + this.pid + ", handle " + this.handle + ")";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user