Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backup for process name and state #1368

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
================
* [#1359](https://github.com/oshi/oshi/pull/1359): Set suppressed network filesystem types and pseudo filesystem types via config - [@J-Jimmy](https://github.com/J-Jimmy).
* [#1362](https://github.com/oshi/oshi/pull/1362): Correct invalid Windows processor bitmask logic on 64th core - [@J-Jimmy](https://github.com/J-Jimmy).
* [#1368](https://github.com/oshi/oshi/pull/1368): Backup for getting process name and state - [@J-Jimmy](https://github.com/J-Jimmy).
* Your contribution here

5.3.0 (2020-10-11)
Expand Down
39 changes: 39 additions & 0 deletions oshi-core/src/main/java/oshi/software/os/linux/LinuxOSProcess.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import oshi.util.ExecutingCommand;
import oshi.util.FileUtil;
import oshi.util.ParseUtil;
import oshi.util.Util;
import oshi.util.platform.linux.ProcPath;

@ThreadSafe
Expand Down Expand Up @@ -294,6 +295,10 @@ public boolean updateAttributes() {
this.state = INVALID;
return false;
}
// If some details couldn't be read from ProcPath.PID_STATUS try reading it from
// ProcPath.PID_STAT
getMissingDetails(status, stat);

long now = System.currentTimeMillis();

// We can get name and status more easily from /proc/pid/status which we
Expand Down Expand Up @@ -339,6 +344,40 @@ public boolean updateAttributes() {
return true;
}

/**
* If some details couldn't be read from ProcPath.PID_STATUS try reading it from
* ProcPath.PID_STAT
*
* @param status
* status map to fill.
* @param stat
* string to read from.
*/
private static void getMissingDetails(Map<String, String> status, String stat) {
if (status == null || stat == null) {
return;
}

int nameStart = stat.indexOf("(");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scrutinzer says using the character '(' is faster than "(". I'm not sure it matters but why not? :)

int nameEnd = stat.indexOf(")");
Copy link
Member

@dbwiddis dbwiddis Oct 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But benchmarks show only a tiny difference so I don't care that much. Still, if you're making other changes, the character version will make the CI tests happy and be a few unnoticed nanoseconds faster.

if (Util.isBlank(status.get("Name")) && nameStart < nameEnd) {
dbwiddis marked this conversation as resolved.
Show resolved Hide resolved
// remove leading and trailing parentheses
String statName = stat.substring(nameStart, nameEnd + 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be nameStart + 1 to exclude the leading parenthesis and nameEnd (which is exclusive) to exclude the ending parenthesis?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did output the original name from the status map and the name I extract here, the indexes are right as they are (on Ubuntu 20.04 LTS with Java 1.8_265)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see what you're doing. In this line you're capturing the full string with both parentheses, but then in the next line you're starting the substring from 1, and going to length-1 (which, since it's exclusive, has length-2 as last character), effectively removing the two parenthesis. If you just use start+1, end on this line, you don't need a second line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, thats still in because I had the string split at first, obviously can be put together. I just woke up so I could do it in half an hour.

statName = statName.substring(1, statName.length() - 1);
status.put("Name", statName);
}

// get the rest of the string from after the name
// (the name may contain whitespaces and destroy the index)
String statEnd = stat.substring(nameEnd + 2);
String[] statSplit = ParseUtil.whitespaces.split(statEnd);
dbwiddis marked this conversation as resolved.
Show resolved Hide resolved
// As per man, the next item after the name is the state
if (Util.isBlank(status.get("State")) && statSplit.length > 0) {
String statState = statSplit[0];
status.put("State", statState);
}
}

/**
* Enum used to update attributes. The order field represents the 1-indexed
* numeric order of the stat in /proc/pid/stat per the man file.
Expand Down