1 /*
2 * Copyright 2016-2024 The OSHI Project Contributors
3 * SPDX-License-Identifier: MIT
4 */
5 package oshi.software.os;
6
7 import java.util.List;
8 import java.util.Map;
9
10 import oshi.annotation.concurrent.ThreadSafe;
11 import oshi.driver.windows.wmi.Win32ProcessCached;
12 import oshi.util.FileUtil;
13 import oshi.util.GlobalConfig;
14
15 /**
16 * Represents a Process on the operating system, which may contain multiple threads.
17 */
18 @ThreadSafe
19 public interface OSProcess {
20
21 /**
22 * Gets the name of the process, often the executable program.
23 *
24 * @return the name of the process.
25 */
26 String getName();
27
28 /**
29 * Gets the full filesystem path of the executing process.
30 *
31 * @return the full path of the executing process.
32 */
33 String getPath();
34
35 /**
36 * Gets the process command line used to start the process, including arguments if available to be determined. This
37 * method generally returns the same information as {@link #getArguments()} in a more user-readable format, and is
38 * more robust to non-elevated access.
39 * <p>
40 * The format of this string is platform-dependent, may be truncated, and may require the end user to parse the
41 * result. Users should generally prefer {@link #getArguments()} which already parses the results, and use this
42 * method as a backup.
43 * <p>
44 * On AIX and Solaris, the string may be truncated to 80 characters if there was insufficient permission to read the
45 * process memory.
46 * <p>
47 * On Windows, attempts to retrieve the value from process memory, which requires that the process be owned by the
48 * same user as the executing process, or elevated permissions, and additionally requires the target process to have
49 * the same bitness (e.g., this will fail on a 32-bit process if queried by 64-bit and vice versa). If reading
50 * process memory fails, by default, performs a single WMI query for this process, with some latency. If this method
51 * will be frequently called for multiple processes, see the configuration file to enable a batch query mode
52 * leveraging {@link Win32ProcessCached#getCommandLine} to improve performance, or setting that parameter via
53 * {@link GlobalConfig#set(String, Object)} before instantiating any {@link OSProcess} object.
54 *
55 * @return the process command line.
56 */
57 String getCommandLine();
58
59 /**
60 * Makes a best effort attempt to get a list of the the command-line arguments of the process. Returns the same
61 * information as {@link #getCommandLine()} but parsed to a list. May require elevated permissions or same-user
62 * ownership.
63 *
64 * @return A list of Strings representing the arguments. May return an empty list if there was a failure (for
65 * example, because the process is already dead or permission was denied).
66 */
67 List<String> getArguments();
68
69 /**
70 * Makes a best effort attempt to obtain the environment variables of the process. May require elevated permissions
71 * or same-user ownership.
72 *
73 * @return A map representing the environment variables and their values. May return an empty map if there was a
74 * failure (for example, because the process is already dead or permission was denied).
75 */
76 Map<String, String> getEnvironmentVariables();
77
78 /**
79 * Makes a best effort attempt to obtain the current working directory for the process.
80 *
81 * @return the process current working directory.
82 */
83 String getCurrentWorkingDirectory();
84
85 /**
86 * Gets the user name of the process owner.
87 *
88 * @return the user name. On Windows systems, also returns the domain prepended to the username.
89 */
90 String getUser();
91
92 /**
93 * Gets the user id of the process owner.
94 *
95 * @return the userID. On Windows systems, returns the Security ID (SID)
96 */
97 String getUserID();
98
99 /**
100 * Gets the group under which the process is executing.
101 * <p>
102 * On Windows systems, populating this value for processes other than the current user requires administrative
103 * privileges (and still may fail for some system processes) and can incur significant latency. When successful,
104 * returns a the default primary group with access to this process, corresponding to the SID in
105 * {@link #getGroupID()}.
106 *
107 * @return the group.
108 */
109 String getGroup();
110
111 /**
112 * Gets the group id under which the process is executing.
113 * <p>
114 * On Windows systems, populating this value for processes other than the current user requires administrative
115 * privileges (and still may fail for some system processes) and can incur significant latency. When successful,
116 * returns the default primary group SID with access to this process, corresponding to the name in
117 * {@link #getGroup()}.
118 *
119 * @return the groupID.
120 */
121 String getGroupID();
122
123 /**
124 * Gets the process state.
125 *
126 * @return the execution state of the process.
127 */
128 State getState();
129
130 /**
131 * Gets the process ID.
132 * <p>
133 * While this is a 32-bit value, it is unsigned on Windows and in extremely rare circumstances may return a negative
134 * value.
135 *
136 * @return the processID.
137 */
138 int getProcessID();
139
140 /**
141 * Gets the process ID of this process's parent.
142 *
143 * @return the parentProcessID, if any; 0 otherwise.
144 */
145 int getParentProcessID();
146
147 /**
148 * Gets the number of threads being executed by this process. More information is available using
149 * {@link #getThreadDetails()}.
150 *
151 * @return the number of threads in this process.
152 */
153 int getThreadCount();
154
155 /**
156 * Gets the priority of this process.
157 * <p>
158 * For Linux and Unix, priority is a value in the range -20 to 19 (20 on some systems). The default priority is 0;
159 * lower priorities cause more favorable scheduling.
160 * <p>
161 * For Windows, priority values can range from 0 (lowest priority) to 31 (highest priority).
162 * <p>
163 * macOS has 128 priority levels, ranging from 0 (lowest priority) to 127 (highest priority). They are divided into
164 * several major bands: 0 through 51 are the normal levels; the default priority is 31. 52 through 79 are the
165 * highest priority regular threads; 80 through 95 are for kernel mode threads; and 96 through 127 correspond to
166 * real-time threads, which are treated differently than other threads by the scheduler.
167 *
168 * @return the priority of this process.
169 */
170 int getPriority();
171
172 /**
173 * Gets the Virtual Memory Size (VSZ). Includes all memory that the process can access, including memory that is
174 * swapped out and memory that is from shared libraries.
175 *
176 * @return the Virtual Memory Size
177 */
178 long getVirtualSize();
179
180 /**
181 * Gets the Resident Set Size (RSS). Used to show how much memory is allocated to that process and is in RAM. It
182 * does not include memory that is swapped out. It does include memory from shared libraries as long as the pages
183 * from those libraries are actually in memory. It does include all stack and heap memory.
184 * <p>
185 * On Windows, returns the Private Working Set size, which should match the "Memory" column in the Windows Task
186 * Manager.
187 * <p>
188 * On Linux, returns the RSS value from {@code /proc/[pid]/stat}, which may be inaccurate because of a
189 * kernel-internal scalability optimization. If accurate values are required, read {@code /proc/[pid]/smaps} using
190 * {@link FileUtil#getKeyValueMapFromFile(String, String)}.
191 *
192 * @return the Resident Set Size
193 */
194 long getResidentSetSize();
195
196 /**
197 * Gets kernel/system (privileged) time used by the process.
198 *
199 * @return the number of milliseconds the process has executed in kernel/system mode.
200 */
201 long getKernelTime();
202
203 /**
204 * Gets user time used by the process.
205 *
206 * @return the number of milliseconds the process has executed in user mode.
207 */
208 long getUserTime();
209
210 /**
211 * Gets up time / elapsed time since the process started.
212 *
213 * @return the number of milliseconds since the process started.
214 */
215 long getUpTime();
216
217 /**
218 * Gets the process start time.
219 *
220 * @return the start time of the process in number of milliseconds since January 1, 1970 UTC.
221 */
222 long getStartTime();
223
224 /**
225 * Gets the bytes read by the process. This includes all I/O activity generated by the process to include file,
226 * network, and device I/Os.
227 * <p>
228 * On Solaris, includes both bytes read and written.
229 *
230 * @return the number of bytes the process has read.
231 */
232 long getBytesRead();
233
234 /**
235 * Gets the bytes written by the process. This includes all I/O activity generated by the process to include file,
236 * network, and device I/Os.
237 * <p>
238 * On Solaris, all IO bytes are included read bytes so this value is 0.
239 *
240 * @return the number of bytes the process has written to disk.
241 */
242 long getBytesWritten();
243
244 /**
245 * Gets the number of open file handles (or network connections) that belongs to the process.
246 * <p>
247 * On FreeBSD and Solaris, this value is only populated if information for a single process id is requested.
248 *
249 * @return open files or -1 if unknown or not supported
250 */
251 long getOpenFiles();
252
253 /**
254 * Gets the soft limit for open file handles (or network connections) of the given process.
255 * <p>
256 * Retrieving the soft limit for processes other than the calling process is only supported on Linux, FreeBsd and
257 * Solaris.
258 *
259 * @return the soft open file limit for the process if available. Returns -1 if the calling process is not the same
260 * as this OSProcess instance and the underlying operating system does not support retrieving the soft limit
261 * for other processes.
262 */
263 long getSoftOpenFileLimit();
264
265 /**
266 * Gets the hard limit for open file handles (or network connections) that belong to the given process.
267 * <p>
268 * Retrieving the hard limit for processes other than the calling process is only supported on Linux, FreeBsd and
269 * Solaris.
270 *
271 * @return the hard open file limit for the process if available. Returns -1 if the calling process is not the same
272 * as this OSProcess instance and the underlying operating system does not support retrieving the hard limit
273 * for other processes.
274 */
275 long getHardOpenFileLimit();
276
277 /**
278 * Gets cumulative CPU usage of this process.
279 * <p>
280 * This calculation sums CPU ticks across all processors and may exceed 100% for multi-threaded processes. This is
281 * consistent with the cumulative CPU presented by the "top" command on Linux/Unix machines.
282 *
283 * @return The proportion of up time that the process was executing in kernel or user mode.
284 */
285 double getProcessCpuLoadCumulative();
286
287 /**
288 * Gets CPU usage of this process since a previous snapshot of the same process, provided as a parameter.
289 * <p>
290 * This calculation sums CPU ticks across all processors and may exceed 100% for multi-threaded processes. This is
291 * consistent with process usage calulations on Linux/Unix machines, but should be divided by the number of logical
292 * processors to match the value displayed by the Windows Task Manager.
293 * <p>
294 * The accuracy of this calculation is dependent on both the number of threads on which the process is executing,
295 * and the precision of the Operating System's tick counters. A polling interval of at least a few seconds is
296 * recommended.
297 *
298 * @param proc An {@link OSProcess} object containing statistics for this same process collected at a prior point in
299 * time. May be null.
300 * @return If the prior snapshot is for the same process at a prior point in time, the proportion of elapsed up time
301 * between the current process snapshot and the previous one that the process was executing in kernel or
302 * user mode. Returns cumulative load otherwise.
303 */
304 double getProcessCpuLoadBetweenTicks(OSProcess proc);
305
306 /**
307 * Attempts to get the bitness (32 or 64) of the process.
308 *
309 * @return The bitness, if able to be determined, 0 otherwise.
310 */
311 int getBitness();
312
313 /**
314 * Gets the process affinity mask for this process.
315 * <p>
316 * On Windows systems with more than 64 processors, if the threads of the calling process are in a single processor
317 * group, returns the process affinity mask for that group (which may be zero if the specified process is running in
318 * a different group). If the calling process contains threads in multiple groups, returns zero.
319 * <p>
320 * Because macOS does not export interfaces that identify processors or control thread placement, explicit thread to
321 * processor binding is not supported and this method will return a bitmask of all logical processors.
322 * <p>
323 * If the Operating System fails to retrieve an affinity mask (e.g., the process has terminated), returns zero.
324 *
325 * @return a bit vector in which each bit represents the processors that a process is allowed to run on.
326 */
327 long getAffinityMask();
328
329 /**
330 * Attempts to update process attributes. Returns false if the update fails, which will occur if the process no
331 * longer exists.
332 *
333 * @return {@code true} if the update was successful, false if the update failed. In addition, on a failed update
334 * the process state will be changed to {@link State#INVALID}.
335 */
336 boolean updateAttributes();
337
338 /**
339 * Retrieves the threads of the process and their details.
340 * <p>
341 * The amount of returned information is operating-system dependent and may incur some latency.
342 *
343 * @return a list of threads
344 */
345 List<OSThread> getThreadDetails();
346
347 /**
348 * Gets the number of minor (soft) faults the process has made which have not required loading a memory page from
349 * disk. Sometimes called reclaims.
350 * <p>
351 * On Windows, this includes the total of major and minor faults.
352 * <p>
353 * Not available on AIX.
354 *
355 * @return minor page faults (reclaims).
356 */
357 default long getMinorFaults() {
358 return 0L;
359 }
360
361 /**
362 * Gets the number of major (hard) faults the process has made which have required loading a memory page from disk.
363 * <p>
364 * Windows does not distinguish major and minor faults at the process level, so this value returns 0 and major
365 * faults are included in {@link #getMinorFaults()}.
366 * <p>
367 * Not available on AIX.
368 *
369 * @return major page faults.
370 */
371 default long getMajorFaults() {
372 return 0L;
373 }
374
375 /**
376 * A snapshot of the context switches the process has done. Since the context switches could be voluntary and
377 * non-voluntary, this gives the sum of both.
378 * <p>
379 * Not available on Windows. An approximation may be made by summing associated values from
380 * {@link OSThread#getContextSwitches()}.
381 * <p>
382 * Not available on AIX.
383 *
384 * @return sum of both voluntary and involuntary context switches if available, 0 otherwise.
385 */
386 default long getContextSwitches() {
387 return 0L;
388 }
389
390 /**
391 * Process and Thread Execution States
392 */
393 enum State {
394 /**
395 * Intermediate state in process creation
396 */
397 NEW,
398 /**
399 * Actively executing process
400 */
401 RUNNING,
402 /**
403 * Interruptible sleep state
404 */
405 SLEEPING,
406 /**
407 * Blocked, uninterruptible sleep state
408 */
409 WAITING,
410 /**
411 * Intermediate state in process termination
412 */
413 ZOMBIE,
414 /**
415 * Stopped by the user, such as for debugging
416 */
417 STOPPED,
418 /**
419 * Other or unknown states not defined
420 */
421 OTHER,
422 /**
423 * The state resulting if the process fails to update statistics, probably due to termination.
424 */
425 INVALID,
426 /**
427 * Special case of waiting if the process has been intentionally suspended (Windows only)
428 */
429 SUSPENDED
430 }
431 }