< prev index next >
src/java.base/solaris/native/libjava/ProcessHandleImpl_solaris.c
Print this page
rev 12414 : 8131168: Refactor ProcessHandleImpl_*.c and add implememtation for AIX
*** 26,233 ****
#include "jni.h"
#include "jni_util.h"
#include "java_lang_ProcessHandleImpl.h"
#include "java_lang_ProcessHandleImpl_Info.h"
#include <stdio.h>
- #include <ctype.h>
- #include <dirent.h>
- #include <errno.h>
- #include <fcntl.h>
#include <procfs.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <limits.h>
-
- /**
- * Implementations of ProcessHandleImpl functions that are
- * NOT common to all Unix variants:
- * - getProcessPids0(pid, pidArray)
- *
- * Implementations of ProcessHandleImpl_Info
- * - totalTime, startTime
- * - Command
- * - Arguments
- */
/*
! * Signatures for internal OS specific functions.
! */
! static pid_t parentPid(JNIEnv *env, pid_t pid);
! static void getStatInfo(JNIEnv *env, jobject jinfo, pid_t pid);
! static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid);
!
! extern jstring uidToUser(JNIEnv* env, uid_t uid);
!
! /* Field id for jString 'command' in java.lang.ProcessHandle.Info */
! static jfieldID ProcessHandleImpl_Info_commandID;
!
! /* Field id for jString[] 'arguments' in java.lang.ProcessHandle.Info */
! static jfieldID ProcessHandleImpl_Info_argumentsID;
!
! /* Field id for jlong 'totalTime' in java.lang.ProcessHandle.Info */
! static jfieldID ProcessHandleImpl_Info_totalTimeID;
!
! /* Field id for jlong 'startTime' in java.lang.ProcessHandle.Info */
! static jfieldID ProcessHandleImpl_Info_startTimeID;
!
! /* Field id for jString 'user' in java.lang.ProcessHandleImpl.Info */
! static jfieldID ProcessHandleImpl_Info_userID;
!
! /* static value for clock ticks per second. */
! static long clock_ticks_per_second;
!
! /**************************************************************
! * Static method to initialize field IDs and the ticks per second rate.
! *
! * Class: java_lang_ProcessHandleImpl_Info
! * Method: initIDs
! * Signature: ()V
! */
! JNIEXPORT void JNICALL Java_java_lang_ProcessHandleImpl_00024Info_initIDs
! (JNIEnv *env, jclass clazz) {
!
! CHECK_NULL(ProcessHandleImpl_Info_commandID = (*env)->GetFieldID(env,
! clazz, "command", "Ljava/lang/String;"));
! CHECK_NULL(ProcessHandleImpl_Info_argumentsID = (*env)->GetFieldID(env,
! clazz, "arguments", "[Ljava/lang/String;"));
! CHECK_NULL(ProcessHandleImpl_Info_totalTimeID = (*env)->GetFieldID(env,
! clazz, "totalTime", "J"));
! CHECK_NULL(ProcessHandleImpl_Info_startTimeID = (*env)->GetFieldID(env,
! clazz, "startTime", "J"));
! CHECK_NULL(ProcessHandleImpl_Info_userID = (*env)->GetFieldID(env,
! clazz, "user", "Ljava/lang/String;"));
! clock_ticks_per_second = sysconf(_SC_CLK_TCK);
! }
!
! /*
! * Returns the parent pid of the requested pid.
! *
! * Class: java_lang_ProcessHandleImpl
! * Method: parent0
! * Signature: (J)J
! */
! JNIEXPORT jlong JNICALL Java_java_lang_ProcessHandleImpl_parent0
! (JNIEnv *env, jobject obj, jlong jpid) {
! pid_t pid = (pid_t) jpid;
! pid_t ppid = -1;
!
! if (pid == getpid()) {
! ppid = getppid();
! } else {
! ppid = parentPid(env, pid);
! }
! return (jlong) ppid;
! }
!
! /*
! * Returns the children of the requested pid and optionally each parent.
! *
! * Class: java_lang_ProcessHandleImpl
! * Method: getChildPids
! * Signature: (J[J)I
! *
! * Reads /proc and accumulates any process who parent pid matches.
! * The resulting pids are stored into the array of longs.
! * The number of pids is returned if they all fit.
! * If the array is too short, the desired length is returned.
! */
! JNIEXPORT jint JNICALL Java_java_lang_ProcessHandleImpl_getProcessPids0
! (JNIEnv *env, jclass clazz, jlong jpid,
! jlongArray jarray, jlongArray jparentArray)
! {
! DIR* dir;
! struct dirent* ptr;
! pid_t pid = (pid_t) jpid;
! size_t count = 0;
! jlong* pids = NULL;
! jlong* ppids = NULL;
! size_t parentArraySize = 0;
! size_t arraySize = 0;
!
! arraySize = (*env)->GetArrayLength(env, jarray);
! JNU_CHECK_EXCEPTION_RETURN(env, 0);
! if (jparentArray != NULL) {
! parentArraySize = (*env)->GetArrayLength(env, jparentArray);
! JNU_CHECK_EXCEPTION_RETURN(env, 0);
!
! if (arraySize != parentArraySize) {
! JNU_ThrowIllegalArgumentException(env, "array sizes not equal");
! return 0;
! }
! }
!
! /*
! * To locate the children we scan /proc looking for files that have a
! * positive integer as a filename.
*/
- if ((dir = opendir("/proc")) == NULL) {
- JNU_ThrowByNameWithLastError(env,
- "java/lang/Runtime", "Unable to open /proc");
- return 0;
- }
-
- do { // Block to break out of on Exception
- pids = (*env)->GetLongArrayElements(env, jarray, NULL);
- if (pids == NULL) {
- break;
- }
- if (jparentArray != NULL) {
- ppids = (*env)->GetLongArrayElements(env, jparentArray, NULL);
- if (ppids == NULL) {
- break;
- }
- }
-
- while ((ptr = readdir(dir)) != NULL) {
- pid_t ppid;
! /* skip files that aren't numbers */
! pid_t childpid = (pid_t) atoi(ptr->d_name);
! if ((int) childpid <= 0) {
! continue;
! }
! ppid = 0;
! if (pid != 0 || jparentArray != NULL) {
! // parentPid opens and reads /proc/pid/stat
! ppid = parentPid(env, childpid);
! }
! if (pid == 0 || ppid == pid) {
! if (count < arraySize) {
! // Only store if it fits
! pids[count] = (jlong) childpid;
!
! if (ppids != NULL) {
! // Store the parentPid
! ppids[count] = (jlong) ppid;
! }
! }
! count++; // Count to tabulate size needed
! }
! }
! } while (0);
!
! if (pids != NULL) {
! (*env)->ReleaseLongArrayElements(env, jarray, pids, 0);
! }
! if (ppids != NULL) {
! (*env)->ReleaseLongArrayElements(env, jparentArray, ppids, 0);
! }
!
! closedir(dir);
! // If more pids than array had size for; count will be greater than array size
! return count;
}
/*
* Returns the parent pid of a given pid, or -1 if not found
*/
! static pid_t parentPid(JNIEnv *env, pid_t pid) {
FILE* fp;
pstatus_t pstatus;
int statlen;
char fn[32];
int i, p;
--- 26,57 ----
#include "jni.h"
#include "jni_util.h"
#include "java_lang_ProcessHandleImpl.h"
#include "java_lang_ProcessHandleImpl_Info.h"
+ #include "ProcessHandleImpl_unix.h"
+
#include <stdio.h>
#include <procfs.h>
/*
! * Implementation of native ProcessHandleImpl functions for Solaris.
! * See ProcessHandleImpl_unix.c for more details.
*/
! void os_init(JNIEnv *env, jclass clazz) {}
! jint os_getChildren(JNIEnv *env, jlong jpid,
! jlongArray jarray, jlongArray jparentArray) {
! return unix_getChildren(env, jpid, jarray, jparentArray);
}
/*
* Returns the parent pid of a given pid, or -1 if not found
*/
! pid_t os_parentPid(JNIEnv *env, pid_t pid) {
FILE* fp;
pstatus_t pstatus;
int statlen;
char fn[32];
int i, p;
*** 240,371 ****
fp = fopen(fn, "r");
if (fp == NULL) {
return -1;
}
- /*
- * The format is: pid (command) state ppid ...
- * As the command could be anything we must find the right most
- * ")" and then skip the white spaces that follow it.
- */
statlen = fread(&pstatus, 1, (sizeof pstatus), fp);
fclose(fp);
if (statlen < 0) {
return -1;
}
return (pid_t) pstatus.pr_ppid;
}
! /**************************************************************
! * Implementation of ProcessHandleImpl_Info native methods.
! */
!
! /*
! * Fill in the Info object from the OS information about the process.
! *
! * Class: java_lang_ProcessHandleImpl_Info
! * Method: info0
! * Signature: (J)V
! */
! JNIEXPORT void JNICALL Java_java_lang_ProcessHandleImpl_00024Info_info0
! (JNIEnv *env, jobject jinfo, jlong jpid) {
! pid_t pid = (pid_t) jpid;
! getStatInfo(env, jinfo, pid);
! getCmdlineInfo(env, jinfo, pid);
! }
!
! /**
! * Read /proc/<pid>/stat and fill in the fields of the Info object.
! * Gather the user and system times.
! */
! static void getStatInfo(JNIEnv *env, jobject jinfo, pid_t pid) {
! FILE* fp;
! pstatus_t pstatus;
! struct stat stat_buf;
! int ret;
! char fn[32];
! int i, p;
! char* s;
! jlong totalTime;
!
! /*
! * Try to open /proc/%d/status
! */
! snprintf(fn, sizeof fn, "/proc/%d/status", pid);
!
! if (stat(fn, &stat_buf) < 0) {
! return;
! }
!
! fp = fopen(fn, "r");
! if (fp == NULL) {
! return;
! }
!
! ret = fread(&pstatus, 1, (sizeof pstatus), fp);
! fclose(fp);
! if (ret < 0) {
! return;
! }
!
! totalTime = pstatus.pr_utime.tv_sec * 1000000000L + pstatus.pr_utime.tv_nsec +
! pstatus.pr_stime.tv_sec * 1000000000L + pstatus.pr_stime.tv_nsec;
!
! (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_totalTimeID, totalTime);
! JNU_CHECK_EXCEPTION(env);
}
! static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) {
! FILE* fp;
! psinfo_t psinfo;
! int ret;
! char fn[32];
! char exePath[PATH_MAX];
! int i, p;
! jlong startTime;
! jobjectArray cmdArray;
! jstring str = NULL;
!
! /*
! * try to open /proc/%d/psinfo
! */
! snprintf(fn, sizeof fn, "/proc/%d/psinfo", pid);
! fp = fopen(fn, "r");
! if (fp == NULL) {
! return;
! }
!
! /*
! * The format is: pid (command) state ppid ...
! * As the command could be anything we must find the right most
! * ")" and then skip the white spaces that follow it.
! */
! ret = fread(&psinfo, 1, (sizeof psinfo), fp);
! fclose(fp);
! if (ret < 0) {
! return;
! }
!
! CHECK_NULL((str = uidToUser(env, psinfo.pr_uid)));
! (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, str);
! JNU_CHECK_EXCEPTION(env);
!
! startTime = (jlong)psinfo.pr_start.tv_sec * (jlong)1000 +
! (jlong)psinfo.pr_start.tv_nsec / 1000000;
! (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_startTimeID, startTime);
! JNU_CHECK_EXCEPTION(env);
!
! /*
! * The path to the executable command is the link in /proc/<pid>/paths/a.out.
! */
! snprintf(fn, sizeof fn, "/proc/%d/path/a.out", pid);
! if ((ret = readlink(fn, exePath, PATH_MAX - 1)) < 0) {
! return;
! }
!
! // null terminate and create String to store for command
! exePath[ret] = '\0';
! CHECK_NULL(str = JNU_NewStringPlatform(env, exePath));
! (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandID, str);
! JNU_CHECK_EXCEPTION(env);
}
--- 64,84 ----
fp = fopen(fn, "r");
if (fp == NULL) {
return -1;
}
statlen = fread(&pstatus, 1, (sizeof pstatus), fp);
fclose(fp);
if (statlen < 0) {
return -1;
}
return (pid_t) pstatus.pr_ppid;
}
! void os_getStatInfo(JNIEnv *env, jobject jinfo, pid_t pid) {
! unix_getStatInfo(env, jinfo, pid);
}
! void os_getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) {
! unix_getCmdlineInfo(env, jinfo, pid);
}
< prev index next >