Skip to content

Commit 1f7925c

Browse files
committed
8347270: Remove unix_getParentPidAndTimings, unix_getChildren and unix_getCmdlineAndUserInfo
Reviewed-by: rriggs, clanger, jkern
1 parent 9fafd63 commit 1f7925c

File tree

4 files changed

+189
-254
lines changed

4 files changed

+189
-254
lines changed

src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c

+60-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
2-
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2025 SAP SE. All rights reserved.
34
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45
*
56
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +31,7 @@
3031

3132
#include <sys/procfs.h>
3233
#include <procinfo.h>
34+
#include <string.h>
3335

3436
/*
3537
* Implementation of native ProcessHandleImpl functions for AIX.
@@ -182,6 +184,62 @@ pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *sta
182184
return (pid_t) ProcessBuffer.pi_ppid;
183185
}
184186

187+
/**
188+
* Helper function to get the 'psinfo_t' data from "/proc/%d/psinfo".
189+
* Returns 0 on success and -1 on error.
190+
*/
191+
static int getPsinfo(pid_t pid, psinfo_t *psinfo) {
192+
FILE* fp;
193+
char fn[32];
194+
size_t ret;
195+
196+
/*
197+
* Try to open /proc/%d/psinfo
198+
*/
199+
snprintf(fn, sizeof fn, "/proc/%d/psinfo", pid);
200+
fp = fopen(fn, "r");
201+
if (fp == NULL) {
202+
return -1;
203+
}
204+
205+
ret = fread(psinfo, 1, sizeof(psinfo_t), fp);
206+
fclose(fp);
207+
if (ret < sizeof(psinfo_t)) {
208+
return -1;
209+
}
210+
return 0;
211+
}
212+
185213
void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) {
186-
unix_getCmdlineAndUserInfo(env, jinfo, pid);
214+
psinfo_t psinfo;
215+
char prargs[PRARGSZ + 1];
216+
jstring cmdexe = NULL;
217+
218+
/*
219+
* Now try to open /proc/%d/psinfo
220+
*/
221+
if (getPsinfo(pid, &psinfo) < 0) {
222+
unix_fillArgArray(env, jinfo, 0, NULL, NULL, cmdexe, NULL);
223+
return;
224+
}
225+
226+
unix_getUserInfo(env, jinfo, psinfo.pr_uid);
227+
228+
/*
229+
* Now read psinfo.pr_psargs which contains the first PRARGSZ characters of the
230+
* argument list (i.e. arg[0] arg[1] ...). Unfortunately, PRARGSZ is usually set
231+
* to 80 characters only. Nevertheless it's better than nothing :)
232+
*/
233+
strncpy(prargs, psinfo.pr_psargs, PRARGSZ);
234+
prargs[PRARGSZ] = '\0';
235+
if (prargs[0] == '\0') {
236+
/* If psinfo.pr_psargs didn't contain any strings, use psinfo.pr_fname
237+
* (which only contains the last component of exec()ed pathname) as a
238+
* last resort. This is true for AIX kernel processes for example.
239+
*/
240+
strncpy(prargs, psinfo.pr_fname, PRARGSZ);
241+
prargs[PRARGSZ] = '\0';
242+
}
243+
unix_fillArgArray(env, jinfo, 0, NULL, NULL, cmdexe,
244+
prargs[0] == '\0' ? NULL : prargs);
187245
}

src/java.base/linux/native/libjava/ProcessHandleImpl_linux.c

+125-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
3030

3131
#include "ProcessHandleImpl_unix.h"
3232

33-
33+
#include <dirent.h>
3434
#include <fcntl.h>
3535
#include <limits.h>
3636
#include <stdlib.h>
@@ -60,9 +60,131 @@ void os_initNative(JNIEnv *env, jclass clazz) {
6060
pageSize = sysconf(_SC_PAGESIZE);
6161
}
6262

63+
/*
64+
* Return pids of active processes, and optionally parent pids and
65+
* start times for each process.
66+
* For a specific non-zero pid, only the direct children are returned.
67+
* If the pid is zero, all active processes are returned.
68+
* Reads /proc and accumulates any process following the rules above.
69+
* The resulting pids are stored into an array of longs named jarray.
70+
* The number of pids is returned if they all fit.
71+
* If the parentArray is non-null, store also the parent pid.
72+
* In this case the parentArray must have the same length as the result pid array.
73+
* Of course in the case of a given non-zero pid all entries in the parentArray
74+
* will contain this pid, so this array does only make sense in the case of a given
75+
* zero pid.
76+
* If the jstimesArray is non-null, store also the start time of the pid.
77+
* In this case the jstimesArray must have the same length as the result pid array.
78+
* If the array(s) (is|are) too short, excess pids are not stored and
79+
* the desired length is returned.
80+
*/
6381
jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray,
6482
jlongArray jparentArray, jlongArray jstimesArray) {
65-
return unix_getChildren(env, jpid, jarray, jparentArray, jstimesArray);
83+
DIR* dir;
84+
struct dirent* ptr;
85+
pid_t pid = (pid_t) jpid;
86+
jlong* pids = NULL;
87+
jlong* ppids = NULL;
88+
jlong* stimes = NULL;
89+
jsize parentArraySize = 0;
90+
jsize arraySize = 0;
91+
jsize stimesSize = 0;
92+
jsize count = 0;
93+
94+
arraySize = (*env)->GetArrayLength(env, jarray);
95+
JNU_CHECK_EXCEPTION_RETURN(env, -1);
96+
if (jparentArray != NULL) {
97+
parentArraySize = (*env)->GetArrayLength(env, jparentArray);
98+
JNU_CHECK_EXCEPTION_RETURN(env, -1);
99+
100+
if (arraySize != parentArraySize) {
101+
JNU_ThrowIllegalArgumentException(env, "array sizes not equal");
102+
return 0;
103+
}
104+
}
105+
if (jstimesArray != NULL) {
106+
stimesSize = (*env)->GetArrayLength(env, jstimesArray);
107+
JNU_CHECK_EXCEPTION_RETURN(env, -1);
108+
109+
if (arraySize != stimesSize) {
110+
JNU_ThrowIllegalArgumentException(env, "array sizes not equal");
111+
return 0;
112+
}
113+
}
114+
115+
/*
116+
* To locate the children we scan /proc looking for files that have a
117+
* position integer as a filename.
118+
*/
119+
if ((dir = opendir("/proc")) == NULL) {
120+
JNU_ThrowByNameWithMessageAndLastError(env,
121+
"java/lang/RuntimeException", "Unable to open /proc");
122+
return -1;
123+
}
124+
125+
do { // Block to break out of on Exception
126+
pids = (*env)->GetLongArrayElements(env, jarray, NULL);
127+
if (pids == NULL) {
128+
break;
129+
}
130+
if (jparentArray != NULL) {
131+
ppids = (*env)->GetLongArrayElements(env, jparentArray, NULL);
132+
if (ppids == NULL) {
133+
break;
134+
}
135+
}
136+
if (jstimesArray != NULL) {
137+
stimes = (*env)->GetLongArrayElements(env, jstimesArray, NULL);
138+
if (stimes == NULL) {
139+
break;
140+
}
141+
}
142+
143+
while ((ptr = readdir(dir)) != NULL) {
144+
pid_t ppid = 0;
145+
jlong totalTime = 0L;
146+
jlong startTime = 0L;
147+
148+
/* skip files that aren't numbers */
149+
pid_t childpid = (pid_t) atoi(ptr->d_name);
150+
if ((int) childpid <= 0) {
151+
continue;
152+
}
153+
154+
// Get the parent pid, and start time
155+
ppid = os_getParentPidAndTimings(env, childpid, &totalTime, &startTime);
156+
if (ppid >= 0 && (pid == 0 || ppid == pid)) {
157+
if (count < arraySize) {
158+
// Only store if it fits
159+
pids[count] = (jlong) childpid;
160+
161+
if (ppids != NULL) {
162+
// Store the parentPid
163+
ppids[count] = (jlong) ppid;
164+
}
165+
if (stimes != NULL) {
166+
// Store the process start time
167+
stimes[count] = startTime;
168+
}
169+
}
170+
count++; // Count to tabulate size needed
171+
}
172+
}
173+
} while (0);
174+
175+
if (pids != NULL) {
176+
(*env)->ReleaseLongArrayElements(env, jarray, pids, 0);
177+
}
178+
if (ppids != NULL) {
179+
(*env)->ReleaseLongArrayElements(env, jparentArray, ppids, 0);
180+
}
181+
if (stimes != NULL) {
182+
(*env)->ReleaseLongArrayElements(env, jstimesArray, stimes, 0);
183+
}
184+
185+
closedir(dir);
186+
// If more pids than array had size for; count will be greater than array size
187+
return count;
66188
}
67189

68190
/**

0 commit comments

Comments
 (0)