< prev index next >

src/java.base/solaris/native/libjava/ProcessHandleImpl_solaris.c

Print this page
rev 12437 : 8131168: Refactor ProcessHandleImpl_*.c and add implememtation for AIX

@@ -26,366 +26,35 @@
 #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 <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 <sys/types.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 getStatInfo(JNIEnv *env, pid_t pid,
-                                     jlong *totalTime, jlong* startTime,
-                                     uid_t *uid);
-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;"));
-}
-
-/**************************************************************
- * Static method to initialize the ticks per second rate.
- *
- * Class:     java_lang_ProcessHandleImpl
- * Method:    initNative
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_java_lang_ProcessHandleImpl_initNative(JNIEnv *env, jclass clazz) {
-    clock_ticks_per_second = sysconf(_SC_CLK_TCK);
-}
-
-/*
- * Check if a process is alive.
- * Return the start time (ms since 1970) if it is available.
- * If the start time is not available return 0.
- * If the pid is invalid, return -1.
- *
- * Class:     java_lang_ProcessHandleImpl
- * Method:    isAlive0
- * Signature: (J)J
- */
-JNIEXPORT jlong JNICALL
-Java_java_lang_ProcessHandleImpl_isAlive0(JNIEnv *env, jobject obj, jlong jpid) {
-    pid_t pid = (pid_t) jpid;
-    jlong startTime = 0L;
-    jlong totalTime = 0L;
-    uid_t uid = -1;
-    pid_t ppid = getStatInfo(env, pid, &totalTime, &startTime, &uid);
-    return (ppid < 0) ? -1 : startTime;
-}
-
-/*
- * 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,
-                                         jlong startTime) {
-    pid_t pid = (pid_t) jpid;
-    pid_t ppid = -1;
-
-    if (pid == getpid()) {
-        ppid = getppid();
-    } else {
-        jlong start = 0L;
-        jlong total = 0L;
-        uid_t uid = -1;
-
-        pid_t ppid = getStatInfo(env, pid, &total, &start, &uid);
-        if (start != startTime
-            && start != 0
-            && startTime != 0) {
-            ppid = -1;
-        }
-    }
-    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.
+ * Implementation of native ProcessHandleImpl functions for Solaris.
+ * See ProcessHandleImpl_unix.c for more details.
  */
-JNIEXPORT jint JNICALL
-Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env,
-                                                 jclass clazz,
-                                                 jlong jpid,
-                                                 jlongArray jarray,
-                                                 jlongArray jparentArray,
-                                                 jlongArray jstimesArray) {
-    DIR* dir;
-    struct dirent* ptr;
-    pid_t pid = (pid_t) jpid;
-    jlong* pids = NULL;
-    jlong* ppids = NULL;
-    jlong* stimes = NULL;
-    jsize parentArraySize = 0;
-    jsize arraySize = 0;
-    jsize stimesSize = 0;
-    jsize count = 0;
-    char procname[32];
 
-    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);
+void os_initNative(JNIEnv *env, jclass clazz) {}
 
-        if (arraySize != parentArraySize) {
-            JNU_ThrowIllegalArgumentException(env, "array sizes not equal");
-            return 0;
-        }
-    }
-    if (jstimesArray != NULL) {
-        stimesSize = (*env)->GetArrayLength(env, jstimesArray);
-        JNU_CHECK_EXCEPTION_RETURN(env, -1);
-
-        if (arraySize != stimesSize) {
-            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;
-            }
-        }
-        if (jstimesArray != NULL) {
-            stimes  = (*env)->GetLongArrayElements(env, jstimesArray, NULL);
-            if (stimes == NULL) {
-                break;
-            }
-        }
-
-        while ((ptr = readdir(dir)) != NULL) {
-            pid_t ppid = 0;
-            jlong totalTime = 0L;
-            jlong startTime = 0L;
-            uid_t uid; // value unused
-
-            /* skip files that aren't numbers */
-            pid_t childpid = (pid_t) atoi(ptr->d_name);
-            if ((int) childpid <= 0) {
-                continue;
-            }
-
-            // Read /proc/pid/stat and get the parent pid, and start time
-            ppid = getStatInfo(env, childpid, &totalTime, &startTime, &uid);
-            if (ppid >= 0 && (pid == 0 || ppid == pid)) {
-                if (count < arraySize) {
-                    // Only store if it fits
-                    pids[count] = (jlong) childpid;
-
-                    if (ppids != NULL) {
-                        // Store the parent Pid
-                        ppids[count] = (jlong) ppid;
-                    }
-                    if (stimes != NULL) {
-                        // Store the process start time
-                        stimes[count] = startTime;
-                    }
-                }
-                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);
-    }
-    if (stimes != NULL) {
-        (*env)->ReleaseLongArrayElements(env, jstimesArray, stimes, 0);
-    }
-
-    closedir(dir);
-    // If more pids than array had size for; count will be greater than array size
-    return count;
+uid_t os_getUID(pid_t pid) {
+    return unix_getUID(pid);
 }
 
-/**************************************************************
- * 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;
-    jlong startTime = 0L;
-    jlong totalTime = 0L;
-    uid_t uid = -1;
-    pid_t ppid = getStatInfo(env, pid, &totalTime, &startTime, &uid);
-
-    getCmdlineInfo(env, jinfo, pid);
-
-    if (ppid > 0) {
-        jstring str;
-        (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_startTimeID, startTime);
-        JNU_CHECK_EXCEPTION(env);
-
-        (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_totalTimeID, totalTime);
-        JNU_CHECK_EXCEPTION(env);
-
-        CHECK_NULL((str = uidToUser(env, uid)));
-        (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, str);
-        JNU_CHECK_EXCEPTION(env);
-    }
+jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray,
+                    jlongArray jparentArray, jlongArray jstimesArray) {
+    return unix_getChildren(env, jpid, jarray, jparentArray, jstimesArray);
 }
 
-/**
- * Read /proc/<pid>/status and return the ppid, total cputime and start time.
- * Return: -1 is fail;  zero is unknown; >  0 is parent pid
- */
-static pid_t getStatInfo(JNIEnv *env, pid_t pid,
-                                      jlong *totalTime, jlong* startTime,
-                                      uid_t* uid) {
-    FILE* fp;
-    psinfo_t psinfo;
-    char fn[32];
-    int ret;
-
-    /*
-     * Try to open /proc/%d/status
-     */
-    snprintf(fn, sizeof fn, "/proc/%d/psinfo", pid);
-    fp = fopen(fn, "r");
-    if (fp == NULL) {
-        return -1;
-    }
-
-    ret = fread(&psinfo, 1, (sizeof psinfo), fp);
-    fclose(fp);
-    if (ret < (sizeof psinfo)) {
-        return -1;
-    }
-
-    *totalTime = psinfo.pr_time.tv_sec * 1000000000L + psinfo.pr_time.tv_nsec;
-
-    *startTime = psinfo.pr_start.tv_sec * (jlong)1000 +
-                 psinfo.pr_start.tv_nsec / 1000000;
-
-    *uid = psinfo.pr_uid;
-
-    return (pid_t) psinfo.pr_ppid;
+pid_t os_getParentPid(JNIEnv *env, pid_t pid, jlong *total, jlong *start) {
+    return unix_getParentPid(env, pid, total, start);
 }
 
-static void getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) {
-    char fn[32];
-    char exePath[PATH_MAX];
-    jstring str = NULL;
-    int ret;
-
-    /*
-     * 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);
+void os_getCmdlineInfo(JNIEnv *env, jobject jinfo, pid_t pid) {
+    unix_getCmdlineInfo(env, jinfo, pid);
 }
 
< prev index next >