diff --git a/CHANGELOG.md b/CHANGELOG.md index 195be4bc8da..674305314a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ [@phillips0616](https://github.com/phillips0616), [@BooSandy1994](https://github.com/BooSandy1994). [@dbwiddis](https://github.com/dbwiddis). +* [#960](https://github.com/oshi/oshi/pull/960): OSProcess constructor with PID. - [@Potat0x](https://github.com/Potat0x). * [#962](https://github.com/oshi/oshi/pull/962): Properly handle null WMI DateTime results. - [@dbwiddis](https://github.com/dbwiddis). * Your contribution here diff --git a/oshi-core/src/main/java/oshi/software/os/OSProcess.java b/oshi-core/src/main/java/oshi/software/os/OSProcess.java index 23e16fbf531..db7e7e15321 100644 --- a/oshi-core/src/main/java/oshi/software/os/OSProcess.java +++ b/oshi-core/src/main/java/oshi/software/os/OSProcess.java @@ -25,6 +25,9 @@ import java.io.Serializable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * A process is an instance of a computer program that is being executed. It * contains the program code and its current activity. Depending on the @@ -35,6 +38,10 @@ public class OSProcess implements Serializable { private static final long serialVersionUID = 3L; + private static final Logger LOG = LoggerFactory.getLogger(OSProcess.class); + + private final OperatingSystem operatingSystem; + private String name = ""; private String path = ""; private String commandLine = ""; @@ -95,6 +102,60 @@ public enum State { OTHER } + /** + *
+ * Constructor for OSProcess. + *
+ * + * @param operatingSystem + * a {@link oshi.software.os.OperatingSystem} instance + */ + public OSProcess(OperatingSystem operatingSystem) { + this.operatingSystem = operatingSystem; + } + + /** + *+ * Constructor for OSProcess given a Process ID. Instantiates an object with + * current statistics for that process ID, and is equivalent to + * {@link oshi.software.os.OperatingSystem#getProcess(int)}. + *
+ *+ * If a process with that ID does not exist, this constructor will throw an + * {@link java.lang.InstantiationException}. + *
+ * + * @param operatingSystem + * a {@link oshi.software.os.OperatingSystem} instance + * @param processID + * process ID + * @throws InstantiationException + * If a process by that ID does not exist. + */ + public OSProcess(OperatingSystem operatingSystem, int processID) throws InstantiationException { + this.processID = processID; + this.operatingSystem = operatingSystem; + if (!updateAttributes()) { + throw new InstantiationException("A process with ID " + processID + " does not exist."); + } + } + + /** + * Attempts to updates all process attributes. Returns false if the update + * fails, which will occur if the process no longer exists. + * + * @return True if the update was successful, false if the update failed + */ + public boolean updateAttributes() { + OSProcess process = operatingSystem.getProcess(this.processID); + if (process == null) { + LOG.debug("No process found: {}", this.processID); + return false; + } + copyValuesToThisProcess(process); + return true; + } + /** *
* Getter for the field name
.
@@ -123,13 +184,15 @@ public String getPath() {
*
user
.
*
*
- * @return Returns the user name. On Windows systems, also returns the domain
- * prepended to the username.
+ * @return Returns the user name. On Windows systems, also returns the
+ * domain prepended to the username.
*/
public String getUser() {
return this.user;
@@ -165,7 +228,8 @@ public String getUser() {
* Getter for the field userID
.
*
*
- * @return Returns the userID. On Windows systems, returns the Security ID (SID)
+ * @return Returns the userID. On Windows systems, returns the Security ID
+ * (SID)
*/
public String getUserID() {
return this.userID;
@@ -178,13 +242,15 @@ public String getUserID() {
*
* @return Returns the group.
*
- * On Windows systems, populating this value for processes other than
- * the current user requires administrative privileges (and still may
- * fail for some system processes) and can incur significant latency.
- * The value is only calculated for single process queries using
+ * On Windows systems, populating this value for processes other
+ * than the current user requires administrative privileges (and
+ * still may fail for some system processes) and can incur
+ * significant latency. The value is only calculated for single
+ * process queries using
* {@link oshi.software.os.OperatingSystem#getProcess(int)}. When
- * successful, returns a comma-delimited list of groups with access to
- * this process, corresponding to the SIDs in {@link #getGroupID()}.
+ * successful, returns a comma-delimited list of groups with access
+ * to this process, corresponding to the SIDs in
+ * {@link #getGroupID()}.
*/
public String getGroup() {
return this.group;
@@ -197,13 +263,15 @@ public String getGroup() {
*
* @return Returns the groupID.
*
- * On Windows systems, populating this value for processes other than
- * the current user requires administrative privileges (and still may
- * fail for some system processes) and can incur significant latency.
- * The value is only calculated for single process queries using
+ * On Windows systems, populating this value for processes other
+ * than the current user requires administrative privileges (and
+ * still may fail for some system processes) and can incur
+ * significant latency. The value is only calculated for single
+ * process queries using
* {@link oshi.software.os.OperatingSystem#getProcess(int)}. When
- * successful, returns a comma-delimited list of group SIDs with access
- * to this process, corresponding to the names in {@link #getGroup()}.
+ * successful, returns a comma-delimited list of group SIDs with
+ * access to this process, corresponding to the names in
+ * {@link #getGroup()}.
*/
public String getGroupID() {
return this.groupID;
@@ -260,20 +328,20 @@ public int getThreadCount() {
*
* @return Returns the priority of this process.
*
- * For Linux and Unix, priority is a value in the range -20 to 19 (20 on
- * some systems). The default priority is 0; lower priorities cause more
- * favorable scheduling.
+ * For Linux and Unix, priority is a value in the range -20 to 19
+ * (20 on some systems). The default priority is 0; lower priorities
+ * cause more favorable scheduling.
*
- * For Windows, priority values can range from 0 (lowest priority) to 31
- * (highest priority).
+ * For Windows, priority values can range from 0 (lowest priority)
+ * to 31 (highest priority).
*
- * Mac OS X has 128 priority levels, ranging from 0 (lowest priority) to
- * 127 (highest priority). They are divided into several major bands: 0
- * through 51 are the normal levels; the default priority is 31. 52
- * through 79 are the highest priority regular threads; 80 through 95
- * are for kernel mode threads; and 96 through 127 correspond to
- * real-time threads, which are treated differently than other threads
- * by the scheduler.
+ * Mac OS X has 128 priority levels, ranging from 0 (lowest
+ * priority) to 127 (highest priority). They are divided into
+ * several major bands: 0 through 51 are the normal levels; the
+ * default priority is 31. 52 through 79 are the highest priority
+ * regular threads; 80 through 95 are for kernel mode threads; and
+ * 96 through 127 correspond to real-time threads, which are treated
+ * differently than other threads by the scheduler.
*/
public int getPriority() {
return this.priority;
@@ -284,9 +352,9 @@ public int getPriority() {
* Getter for the field virtualSize
.
*
*
- * @return Returns the Virtual Memory Size (VSZ). It includes all memory that
- * the process can access, including memory that is swapped out and
- * memory that is from shared libraries.
+ * @return Returns the Virtual Memory Size (VSZ). It includes all memory
+ * that the process can access, including memory that is swapped out
+ * and memory that is from shared libraries.
*/
public long getVirtualSize() {
return this.virtualSize;
@@ -297,12 +365,12 @@ public long getVirtualSize() {
* Getter for the field residentSetSize
.
*
*
- * @return Returns the Resident Set Size (RSS). On Windows, returns the Private
- * Working Set size. It is used to show how much memory is allocated to
- * that process and is in RAM. It does not include memory that is
- * swapped out. It does include memory from shared libraries as long as
- * the pages from those libraries are actually in memory. It does
- * include all stack and heap memory.
+ * @return Returns the Resident Set Size (RSS). On Windows, returns the
+ * Private Working Set size. It is used to show how much memory is
+ * allocated to that process and is in RAM. It does not include
+ * memory that is swapped out. It does include memory from shared
+ * libraries as long as the pages from those libraries are actually
+ * in memory. It does include all stack and heap memory.
*/
public long getResidentSetSize() {
return this.residentSetSize;
@@ -325,8 +393,8 @@ public long getKernelTime() {
* Getter for the field userTime
.
*
*
- * @return Returns the number of milliseconds the process has executed in user
- * mode.
+ * @return Returns the number of milliseconds the process has executed in
+ * user mode.
*/
public long getUserTime() {
return this.userTime;
@@ -348,8 +416,8 @@ public long getUpTime() {
* Getter for the field startTime
.
*
*
- * @return Returns the start time of the process in number of milliseconds since
- * January 1, 1970.
+ * @return Returns the start time of the process in number of milliseconds
+ * since January 1, 1970.
*/
public long getStartTime() {
return this.startTime;
@@ -500,18 +568,19 @@ public void setThreadCount(int threadCount) {
/**
* Set the priority of this process.
*
- * For Linux, priority is a value in the range -20 to 19 (20 on some systems).
- * The default priority is 0; lower priorities cause more favorable scheduling.
+ * For Linux, priority is a value in the range -20 to 19 (20 on some
+ * systems). The default priority is 0; lower priorities cause more
+ * favorable scheduling.
*
* For Windows, priority values can range from 0 (lowest priority) to 31
* (highest priority).
*
* Mac OS X has 128 priority levels, ranging from 0 (lowest priority) to 127
- * (highest priority). They are divided into several major bands: 0 through 51
- * are the normal levels; the default priority is 31. 52 through 79 are the
- * highest priority regular threads; 80 through 95 are for kernel mode threads;
- * and 96 through 127 correspond to real-time threads, which are treated
- * differently than other threads by the scheduler.
+ * (highest priority). They are divided into several major bands: 0 through
+ * 51 are the normal levels; the default priority is 31. 52 through 79 are
+ * the highest priority regular threads; 80 through 95 are for kernel mode
+ * threads; and 96 through 127 correspond to real-time threads, which are
+ * treated differently than other threads by the scheduler.
*
* @param priority
* priority
@@ -521,9 +590,9 @@ public void setPriority(int priority) {
}
/**
- * Set the Virtual Memory Size (VSZ). It includes all memory that the process
- * can access, including memory that is swapped out and memory that is from
- * shared libraries.
+ * Set the Virtual Memory Size (VSZ). It includes all memory that the
+ * process can access, including memory that is swapped out and memory that
+ * is from shared libraries.
*
* @param virtualSize
* virtual size
@@ -534,10 +603,10 @@ public void setVirtualSize(long virtualSize) {
/**
* Set the Resident Set Size (RSS). It is used to show how much memory is
- * allocated to that process and is in RAM. It does not include memory that is
- * swapped out. It does include memory from shared libraries as long as the
- * pages from those libraries are actually in memory. It does include all stack
- * and heap memory.
+ * allocated to that process and is in RAM. It does not include memory that
+ * is swapped out. It does include memory from shared libraries as long as
+ * the pages from those libraries are actually in memory. It does include
+ * all stack and heap memory.
*
* @param residentSetSize
* resident set size
@@ -567,8 +636,8 @@ public void setUserTime(long userTime) {
}
/**
- * Set the start time of the process in number of milliseconds since January 1,
- * 1970.
+ * Set the start time of the process in number of milliseconds since January
+ * 1, 1970.
*
* @param startTime
* start time
@@ -608,8 +677,8 @@ public void setBytesWritten(long bytesWritten) {
}
/**
- * Sets the number of open file handles (or network connections) that belongs to
- * the process
+ * Sets the number of open file handles (or network connections) that
+ * belongs to the process
*
* @param count
* The number of handles
@@ -619,8 +688,8 @@ public void setOpenFiles(long count) {
}
/**
- * Sets the number of open file handles (or network connections) that belongs to
- * the process
+ * Sets the number of open file handles (or network connections) that
+ * belongs to the process
*
* On FreeBSD and Solaris, this value is only populated if information for a
* single process id is requested.
@@ -634,8 +703,8 @@ public long getOpenFiles() {
/**
* Calculates CPU usage of this process.
*
- * @return The proportion of up time that the process was executing in kernel or
- * user mode.
+ * @return The proportion of up time that the process was executing in
+ * kernel or user mode.
*/
public double calculateCpuPercent() {
if (this.cpuPercent < 0d) {
@@ -674,4 +743,31 @@ public int getBitness() {
public void setBitness(int bitness) {
this.bitness = bitness;
}
+
+ private void copyValuesToThisProcess(OSProcess sourceProcess) {
+ this.name = sourceProcess.name;
+ this.path = sourceProcess.path;
+ this.commandLine = sourceProcess.commandLine;
+ this.currentWorkingDirectory = sourceProcess.currentWorkingDirectory;
+ this.user = sourceProcess.user;
+ this.userID = sourceProcess.userID;
+ this.group = sourceProcess.group;
+ this.groupID = sourceProcess.groupID;
+ this.state = sourceProcess.state;
+ this.processID = sourceProcess.processID;
+ this.parentProcessID = sourceProcess.parentProcessID;
+ this.threadCount = sourceProcess.threadCount;
+ this.priority = sourceProcess.priority;
+ this.virtualSize = sourceProcess.virtualSize;
+ this.residentSetSize = sourceProcess.residentSetSize;
+ this.kernelTime = sourceProcess.kernelTime;
+ this.userTime = sourceProcess.userTime;
+ this.startTime = sourceProcess.startTime;
+ this.upTime = sourceProcess.upTime;
+ this.bytesRead = sourceProcess.bytesRead;
+ this.bytesWritten = sourceProcess.bytesWritten;
+ this.openFiles = sourceProcess.openFiles;
+ this.bitness = sourceProcess.bitness;
+ this.cpuPercent = sourceProcess.cpuPercent;
+ }
}
diff --git a/oshi-core/src/main/java/oshi/software/os/linux/LinuxOperatingSystem.java b/oshi-core/src/main/java/oshi/software/os/linux/LinuxOperatingSystem.java
index e16b22c1c06..e9d9014db60 100644
--- a/oshi-core/src/main/java/oshi/software/os/linux/LinuxOperatingSystem.java
+++ b/oshi-core/src/main/java/oshi/software/os/linux/LinuxOperatingSystem.java
@@ -231,7 +231,7 @@ private OSProcess getProcess(int pid, LinuxUserGroupInfo userGroupInfo, boolean
// call later, so just get the numeric bits here
long[] statArray = ParseUtil.parseStringToLongArray(stat, PROC_PID_STAT_ORDERS, PROC_PID_STAT_LENGTH, ' ');
// Fetch cached process if it exists
- OSProcess proc = new OSProcess();
+ OSProcess proc = new OSProcess(this);
proc.setProcessID(pid);
// The /proc/pid/cmdline value is null-delimited
proc.setCommandLine(FileUtil.getStringFromFile(String.format("/proc/%d/cmdline", pid)));
diff --git a/oshi-core/src/main/java/oshi/software/os/mac/MacOperatingSystem.java b/oshi-core/src/main/java/oshi/software/os/mac/MacOperatingSystem.java
index 0fbbd62abe9..ab3421e4de5 100644
--- a/oshi-core/src/main/java/oshi/software/os/mac/MacOperatingSystem.java
+++ b/oshi-core/src/main/java/oshi/software/os/mac/MacOperatingSystem.java
@@ -195,7 +195,7 @@ private OSProcess getProcess(int pid, boolean slowFields) { // NOSONAR squid:S11
}
}
long now = System.currentTimeMillis();
- OSProcess proc = new OSProcess();
+ OSProcess proc = new OSProcess(this);
proc.setName(name);
proc.setPath(path);
switch (taskAllInfo.pbsd.pbi_status) {
diff --git a/oshi-core/src/main/java/oshi/software/os/unix/freebsd/FreeBsdOperatingSystem.java b/oshi-core/src/main/java/oshi/software/os/unix/freebsd/FreeBsdOperatingSystem.java
index 011ca81ba2f..168cbde7a67 100644
--- a/oshi-core/src/main/java/oshi/software/os/unix/freebsd/FreeBsdOperatingSystem.java
+++ b/oshi-core/src/main/java/oshi/software/os/unix/freebsd/FreeBsdOperatingSystem.java
@@ -144,7 +144,7 @@ private List