/*
 * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#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 <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

#include <pwd.h>

#if defined(_AIX)
  #include <sys/procfs.h>
#endif

/**
 * This file contains the implementation of the native ProcessHandleImpl
 * functions which are common to all Unix variants.
 *
 * The currently supported Unix variants are Linux, MaxOS X and AIX.
 * The various similarities and differences between these systems make it hard
 * to find a clear boundary between platform specific and shared code.
 *
 * In order to ease code sharing between the platforms while still keeping the
 * code as clean as possible (i.e. free of preprocessor macros) we use the
 * following source code layout (remember that ProcessHandleImpl_unix.c will
 * be compiled on EVERY Unix platform while ProcessHandleImpl_<os>.c will be
 * only compiled on the specific OS):
 *
 * - all the JNI wrappers for the ProcessHandleImpl functions go into this file
 * - if their implementation is common on ALL the supported Unix platforms it
 *   goes right into the JNI wrappers
 * - if the whole function or substantial parts of it are platform dependent,
 *   the implementation goes into os_<function_name> functions in
 *   ProcessHandleImpl_<os>.c
 * - if at least two platforms implement an os_<function_name> function in the
 *   same way, this implementation is factored out into unix_<function_name>,
 *   placed into this file and called from the corresponding os_<function_name>
 *   function.
 * - For convenience, all the os_ and unix_ functions are declared in
 *   ProcessHandleImpl_unix.h which is included into every
 *   ProcessHandleImpl_<os>.c file.
 *
 * Example:
 * ----------
 * The implementation of Java_java_lang_ProcessHandleImpl_initNative()
 * is the same on all platforms except on Linux where it initializes one
 * additional field. So we place the implementation right into
 * Java_java_lang_ProcessHandleImpl_initNative() but add call to
 * os_init() at the end of the function which is empty on all platforms
 * except Linux where it performs the additionally initializations.
 *
 * The term "same implementation" is still a question of interpretation. It my
 * be acceptable to have a few ifdef'ed lines if that allows the sharing of a
 * huge function. On the other hand, if the platform specific code in a shared
 * function grows over a certain limit, it may be better to refactor that
 * functionality into corresponding, platform-specific os_ functions.
 */


#ifndef WIFEXITED
#define WIFEXITED(status) (((status)&0xFF) == 0)
#endif

#ifndef WEXITSTATUS
#define WEXITSTATUS(status) (((status)>>8)&0xFF)
#endif

#ifndef WIFSIGNALED
#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
#endif

#ifndef WTERMSIG
#define WTERMSIG(status) ((status)&0x7F)
#endif

/* The child exited because of a signal.
 * The best value to return is 0x80 + signal number,
 * because that is what all Unix shells do, and because
 * it allows callers to distinguish between process exit and
 * process death by signal.
 */
#define WTERMSIG_RETURN(status) (WTERMSIG(status) + 0x80)

/* Field id for jString 'command' in java.lang.ProcessHandleImpl.Info */
jfieldID ProcessHandleImpl_Info_commandID;

/* Field id for jString 'commandLine' in java.lang.ProcessHandleImpl.Info */
jfieldID ProcessHandleImpl_Info_commandLineID;

/* Field id for jString[] 'arguments' in java.lang.ProcessHandleImpl.Info */
jfieldID ProcessHandleImpl_Info_argumentsID;

/* Field id for jlong 'totalTime' in java.lang.ProcessHandleImpl.Info */
jfieldID ProcessHandleImpl_Info_totalTimeID;

/* Field id for jlong 'startTime' in java.lang.ProcessHandleImpl.Info */
jfieldID ProcessHandleImpl_Info_startTimeID;

/* Field id for jString 'user' in java.lang.ProcessHandleImpl.Info */
jfieldID ProcessHandleImpl_Info_userID;

/* Size of password or group entry when not available via sysconf */
#define ENT_BUF_SIZE   1024
/* The value for the size of the buffer used by getpwuid_r(). The result of */
/* sysconf(_SC_GETPW_R_SIZE_MAX) if available or ENT_BUF_SIZE otherwise. */
static long getpw_buf_size;

/**************************************************************
 * 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_commandLineID =
            (*env)->GetFieldID(env, clazz, "commandLine", "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 platform dependent constants.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    initNative
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_java_lang_ProcessHandleImpl_initNative(JNIEnv *env, jclass clazz) {
    getpw_buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
    if (getpw_buf_size == -1) {
        getpw_buf_size = ENT_BUF_SIZE;
    }
    os_initNative(env, clazz);
}

/* Block until a child process exits and return its exit code.
 * Note, can only be called once for any given pid if reapStatus = true.
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    waitForProcessExit0
 * Signature: (JZ)I
 */
JNIEXPORT jint JNICALL
Java_java_lang_ProcessHandleImpl_waitForProcessExit0(JNIEnv* env,
                                                     jclass junk,
                                                     jlong jpid,
                                                     jboolean reapStatus) {
    pid_t pid = (pid_t)jpid;
    errno = 0;

    if (reapStatus != JNI_FALSE) {
        /* Wait for the child process to exit.
         * waitpid() is standard, so use it on all POSIX platforms.
         * It is known to work when blocking to wait for the pid
         * This returns immediately if the child has already exited.
         */
        int status;
        while (waitpid(pid, &status, 0) < 0) {
            switch (errno) {
                case ECHILD:
                    return java_lang_ProcessHandleImpl_NOT_A_CHILD; // No child
                case EINTR: break;
                default: return -1;
            }
        }

        if (WIFEXITED(status)) {
            return WEXITSTATUS(status);
        } else if (WIFSIGNALED(status)) {
            return WTERMSIG_RETURN(status);
        } else {
            return status;
        }
     } else {
        /*
         * Wait for the child process to exit without reaping the exitValue.
         * waitid() is standard on all POSIX platforms.
         * Note: waitid on Mac OS X 10.7 seems to be broken;
         * it does not return the exit status consistently.
         */
        siginfo_t siginfo;
        int options = WEXITED |  WNOWAIT;
        memset(&siginfo, 0, sizeof siginfo);
        while (waitid(P_PID, pid, &siginfo, options) < 0) {
            switch (errno) {
                case ECHILD:
                    return java_lang_ProcessHandleImpl_NOT_A_CHILD; // No child
                case EINTR: break;
                default: return -1;
            }
        }

        if (siginfo.si_code == CLD_EXITED) {
             /*
              * The child exited normally; get its exit code.
              */
             return siginfo.si_status;
        } else if (siginfo.si_code == CLD_KILLED || siginfo.si_code == CLD_DUMPED) {
             return WTERMSIG_RETURN(siginfo.si_status);
        } else {
             /*
              * Unknown exit code; pass it through.
              */
             return siginfo.si_status;
        }
    }
}

/*
 * Class:     java_lang_ProcessHandleImpl
 * Method:    getCurrentPid0
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL
Java_java_lang_ProcessHandleImpl_getCurrentPid0(JNIEnv *env, jclass clazz) {
    pid_t pid = getpid();
    return (jlong) pid;
}

/*
 * Class:     java_lang_ProcessHandleImpl
 * Method:    destroy0
 * Signature: (JJZ)Z
 */
JNIEXPORT jboolean JNICALL
Java_java_lang_ProcessHandleImpl_destroy0(JNIEnv *env,
                                          jobject obj,
                                          jlong jpid,
                                          jlong startTime,
                                          jboolean force) {
    pid_t pid = (pid_t) jpid;
    int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM;
    jlong start = Java_java_lang_ProcessHandleImpl_isAlive0(env, obj, jpid);

    if (start == startTime || start == 0 || startTime == 0) {
        return (kill(pid, sig) < 0) ? JNI_FALSE : JNI_TRUE;
    } else {
        return JNI_FALSE;
    }
}

/*
 * Returns the children of the requested pid and optionally each parent and
 * start time.
 * 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 negative of the desired length is returned.
 * Class:     java_lang_ProcessHandleImpl
 * Method:    getProcessPids0
 * Signature: (J[J[J[J)I
 */
JNIEXPORT jint JNICALL
Java_java_lang_ProcessHandleImpl_getProcessPids0(JNIEnv *env,
                                                 jclass clazz,
                                                 jlong jpid,
                                                 jlongArray jarray,
                                                 jlongArray jparentArray,
                                                 jlongArray jstimesArray) {
    return os_getChildren(env, jpid, jarray, jparentArray, jstimesArray);
}

/*
 * Fill in the Info object from the OS information about the process.
 *
 * Class:     java_lang_ProcessHandleImpl_Info
 * Method:    info0
 * Signature: (Ljava/lang/ProcessHandle/Info;J)I
 */
JNIEXPORT void JNICALL
Java_java_lang_ProcessHandleImpl_00024Info_info0(JNIEnv *env,
                                                 jobject jinfo,
                                                 jlong jpid) {
    pid_t pid = (pid_t) jpid;
    pid_t ppid;
    jlong totalTime = -1L;
    jlong startTime = -1L;

    ppid = os_getParentPidAndTimings(env, pid,  &totalTime, &startTime);
    if (ppid >= 0) {
        (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_totalTimeID, totalTime);
        JNU_CHECK_EXCEPTION(env);

        (*env)->SetLongField(env, jinfo, ProcessHandleImpl_Info_startTimeID, startTime);
        JNU_CHECK_EXCEPTION(env);
    }
    os_getCmdlineAndUserInfo(env, jinfo, pid);
}

/*
 * 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;
    pid_t ppid = os_getParentPidAndTimings(env, pid, &totalTime, &startTime);
    return (ppid < 0) ? -1 : startTime;
}

/*
 * Returns the parent pid of the requested pid.
 * The start time of the process must match (or be ANY).
 *
 * Class:     java_lang_ProcessHandleImpl
 * Method:    parent0
 * Signature: (JJ)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;

    if (pid == getpid()) {
        ppid = getppid();
    } else {
        jlong start = 0L;
        jlong total = 0L;        // unused
        ppid = os_getParentPidAndTimings(env, pid, &total, &start);
        if (start != startTime && start != 0 && startTime != 0) {
            ppid = -1;
        }
    }
    return (jlong) ppid;
}

/**
 * Construct the argument array by parsing the arguments from the sequence
 * of arguments.
 */
void unix_fillArgArray(JNIEnv *env, jobject jinfo, int nargs, char *cp,
                       char *argsEnd, jstring cmdexe, char *cmdline) {
    jobject argsArray;
    int i;

    (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandID, cmdexe);
    JNU_CHECK_EXCEPTION(env);

    if (nargs >= 1) {
        // Create a String array for nargs-1 elements
        jclass clazzString = JNU_ClassString(env);
        CHECK_NULL(clazzString);
        argsArray = (*env)->NewObjectArray(env, nargs - 1, clazzString, NULL);
        CHECK_NULL(argsArray);

        for (i = 0; i < nargs - 1; i++) {
            jstring str = NULL;

            cp += strlen(cp) + 1;
            if (cp > argsEnd || *cp == '\0') {
                return;  // Off the end pointer or an empty argument is an error
            }

            CHECK_NULL((str = JNU_NewStringPlatform(env, cp)));

            (*env)->SetObjectArrayElement(env, argsArray, i, str);
            JNU_CHECK_EXCEPTION(env);
        }
        (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_argumentsID, argsArray);
        JNU_CHECK_EXCEPTION(env);
    }
    if (cmdline != NULL) {
        jstring commandLine = NULL;
        CHECK_NULL((commandLine = JNU_NewStringPlatform(env, cmdline)));
        (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_commandLineID, commandLine);
        JNU_CHECK_EXCEPTION(env);
    }
}

void unix_getUserInfo(JNIEnv* env, jobject jinfo, uid_t uid) {
    int result = 0;
    char* pwbuf;
    jstring name = NULL;

    /* allocate buffer for password record */
    pwbuf = (char*)malloc(getpw_buf_size);
    if (pwbuf == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Unable to open getpwent");
    } else {
        struct passwd pwent;
        struct passwd* p = NULL;
        RESTARTABLE(getpwuid_r(uid, &pwent, pwbuf, (size_t)getpw_buf_size, &p), result);

        // Create the Java String if a name was found
        if (result == 0 && p != NULL &&
            p->pw_name != NULL && *(p->pw_name) != '\0') {
            name = JNU_NewStringPlatform(env, p->pw_name);
        }
        free(pwbuf);
    }
    if (name != NULL) {
        (*env)->SetObjectField(env, jinfo, ProcessHandleImpl_Info_userID, name);
    }
}

