< 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 >