1618 lines
40 KiB
C
1618 lines
40 KiB
C
/*
|
|
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
|
* This file is part of SIGAR.
|
|
*
|
|
* SIGAR is free software; you can redistribute it and/or modify
|
|
* it under the terms version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation. This program 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 for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
* USA.
|
|
*/
|
|
|
|
#include <jni.h>
|
|
#include "sigar.h"
|
|
#include "sigar_fileinfo.h"
|
|
#include "sigar_log.h"
|
|
#include "sigar_private.h"
|
|
#include "sigar_ptql.h"
|
|
#include "sigar_util.h"
|
|
#include "sigar_os.h"
|
|
#include "sigar_format.h"
|
|
|
|
#include <string.h>
|
|
|
|
#ifdef WIN32
|
|
#include <winsock.h>
|
|
#else
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include "javasigar_generated.h"
|
|
#include "javasigar.h"
|
|
|
|
#ifdef SIGAR_64BIT
|
|
#define SIGAR_POINTER_LONG
|
|
#endif
|
|
|
|
typedef struct {
|
|
jclass classref;
|
|
jfieldID *ids;
|
|
} jsigar_field_cache_t;
|
|
|
|
typedef struct {
|
|
JNIEnv *env;
|
|
jobject logger;
|
|
sigar_t *sigar;
|
|
jsigar_field_cache_t *fields[JSIGAR_FIELDS_MAX];
|
|
int open_status;
|
|
jthrowable not_impl;
|
|
} jni_sigar_t;
|
|
|
|
#define dSIGAR_GET \
|
|
jni_sigar_t *jsigar = sigar_get_jpointer(env, sigar_obj); \
|
|
sigar_t *sigar
|
|
|
|
#define dSIGAR_VOID \
|
|
dSIGAR_GET; \
|
|
if (!jsigar) return; \
|
|
sigar = jsigar->sigar; \
|
|
jsigar->env = env
|
|
|
|
#define dSIGAR(val) \
|
|
dSIGAR_GET; \
|
|
if (!jsigar) return val; \
|
|
sigar = jsigar->sigar; \
|
|
jsigar->env = env
|
|
|
|
JNIEXPORT jint JNICALL
|
|
JNI_OnLoad(JavaVM *vm, void *reserved)
|
|
{
|
|
#ifdef DMALLOC
|
|
char *options =
|
|
getenv("DMALLOC_OPTIONS");
|
|
if (!options) {
|
|
options =
|
|
"debug=0x4f47d03,"
|
|
"lockon=20,"
|
|
"log=dmalloc-sigar.log";
|
|
}
|
|
dmalloc_debug_setup(options);
|
|
#endif
|
|
return JNI_VERSION_1_2;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JNI_OnUnload(JavaVM *vm, void *reserved)
|
|
{
|
|
#ifdef DMALLOC
|
|
dmalloc_shutdown();
|
|
#endif
|
|
}
|
|
|
|
static void sigar_throw_exception(JNIEnv *env, char *msg)
|
|
{
|
|
jclass errorClass = SIGAR_FIND_CLASS("SigarException");
|
|
|
|
JENV->ThrowNew(env, errorClass, msg);
|
|
}
|
|
|
|
#define SIGAR_NOTIMPL_EX "SigarNotImplementedException"
|
|
|
|
static void sigar_throw_notimpl(JNIEnv *env, char *msg)
|
|
{
|
|
jclass errorClass = SIGAR_FIND_CLASS(SIGAR_NOTIMPL_EX);
|
|
|
|
JENV->ThrowNew(env, errorClass, msg);
|
|
}
|
|
|
|
static void sigar_throw_ptql_malformed(JNIEnv *env, char *msg)
|
|
{
|
|
jclass errorClass = SIGAR_FIND_CLASS("ptql/MalformedQueryException");
|
|
|
|
JENV->ThrowNew(env, errorClass, msg);
|
|
}
|
|
|
|
static void sigar_throw_error(JNIEnv *env, jni_sigar_t *jsigar, int err)
|
|
{
|
|
jclass errorClass;
|
|
int err_type = err;
|
|
|
|
/*
|
|
* support:
|
|
* #define SIGAR_EPERM_KMEM (SIGAR_OS_START_ERROR+EACCES)
|
|
* this allows for os impl specific message
|
|
* (e.g. Failed to open /dev/kmem) but still map to the proper
|
|
* Sigar*Exception
|
|
*/
|
|
if (err_type > SIGAR_OS_START_ERROR) {
|
|
err_type -= SIGAR_OS_START_ERROR;
|
|
}
|
|
|
|
switch (err_type) {
|
|
case SIGAR_ENOENT:
|
|
errorClass = SIGAR_FIND_CLASS("SigarFileNotFoundException");
|
|
break;
|
|
|
|
case SIGAR_EACCES:
|
|
errorClass = SIGAR_FIND_CLASS("SigarPermissionDeniedException");
|
|
break;
|
|
|
|
case SIGAR_ENOTIMPL:
|
|
if (jsigar->not_impl == NULL) {
|
|
jfieldID id;
|
|
jthrowable not_impl;
|
|
|
|
errorClass = SIGAR_FIND_CLASS(SIGAR_NOTIMPL_EX);
|
|
|
|
id = JENV->GetStaticFieldID(env, errorClass,
|
|
"INSTANCE",
|
|
SIGAR_CLASS_SIG(SIGAR_NOTIMPL_EX));
|
|
|
|
not_impl = JENV->GetStaticObjectField(env, errorClass, id);
|
|
|
|
jsigar->not_impl = JENV->NewGlobalRef(env, not_impl);
|
|
}
|
|
|
|
JENV->Throw(env, jsigar->not_impl);
|
|
return;
|
|
default:
|
|
errorClass = SIGAR_FIND_CLASS("SigarException");
|
|
break;
|
|
}
|
|
|
|
JENV->ThrowNew(env, errorClass,
|
|
sigar_strerror(jsigar->sigar, err));
|
|
}
|
|
|
|
static void *sigar_get_pointer(JNIEnv *env, jobject obj) {
|
|
jfieldID pointer_field;
|
|
jclass cls = JENV->GetObjectClass(env, obj);
|
|
|
|
#ifdef SIGAR_POINTER_LONG
|
|
pointer_field = JENV->GetFieldID(env, cls, "longSigarWrapper", "J");
|
|
return (void *)JENV->GetLongField(env, obj, pointer_field);
|
|
#else
|
|
pointer_field = JENV->GetFieldID(env, cls, "sigarWrapper", "I");
|
|
return (void *)JENV->GetIntField(env, obj, pointer_field);
|
|
#endif
|
|
}
|
|
|
|
static jni_sigar_t *sigar_get_jpointer(JNIEnv *env, jobject obj) {
|
|
jni_sigar_t *jsigar =
|
|
(jni_sigar_t *)sigar_get_pointer(env, obj);
|
|
|
|
if (!jsigar) {
|
|
sigar_throw_exception(env, "sigar has been closed");
|
|
return NULL;
|
|
}
|
|
|
|
if (jsigar->open_status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar,
|
|
jsigar->open_status);
|
|
return NULL;
|
|
}
|
|
|
|
return jsigar;
|
|
}
|
|
|
|
static void sigar_set_pointer(JNIEnv *env, jobject obj, const void *ptr) {
|
|
jfieldID pointer_field;
|
|
jclass cls = JENV->GetObjectClass(env, obj);
|
|
|
|
#ifdef SIGAR_POINTER_LONG
|
|
pointer_field = JENV->GetFieldID(env, cls, "longSigarWrapper", "J");
|
|
JENV->SetLongField(env, obj, pointer_field, (jlong)ptr);
|
|
#else
|
|
pointer_field = JENV->GetFieldID(env, cls, "sigarWrapper", "I");
|
|
JENV->SetIntField(env, obj, pointer_field, (int)ptr);
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNIx(formatSize)
|
|
(JNIEnv *env, jclass cls, jlong size)
|
|
{
|
|
char buf[56];
|
|
sigar_format_size(size, buf);
|
|
return JENV->NewStringUTF(env, buf);
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNIx(getNativeVersion)
|
|
(JNIEnv *env, jclass cls)
|
|
{
|
|
sigar_version_t *version = sigar_version_get();
|
|
return JENV->NewStringUTF(env, version->version);
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNIx(getNativeBuildDate)
|
|
(JNIEnv *env, jclass cls)
|
|
{
|
|
sigar_version_t *version = sigar_version_get();
|
|
return JENV->NewStringUTF(env, version->build_date);
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNIx(open)
|
|
(JNIEnv *env, jobject obj)
|
|
{
|
|
jni_sigar_t *jsigar = malloc(sizeof(*jsigar));
|
|
|
|
memset(jsigar, '\0', sizeof(*jsigar));
|
|
|
|
sigar_set_pointer(env, obj, jsigar);
|
|
|
|
/* this method is called by the constructor.
|
|
* if != SIGAR_OK save status and throw exception
|
|
* when methods are invoked (see sigar_get_pointer).
|
|
*/
|
|
if ((jsigar->open_status = sigar_open(&jsigar->sigar)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, jsigar->open_status);
|
|
return;
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jint SIGAR_JNIx(nativeClose)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
jint status;
|
|
int i;
|
|
dSIGAR(0);
|
|
|
|
/* only place it is possible this would be something other than
|
|
* SIGAR_OK is on win32 if RegCloseKey fails, which i don't think
|
|
* is possible either.
|
|
*/
|
|
status = sigar_close(sigar);
|
|
|
|
if (jsigar->logger != NULL) {
|
|
JENV->DeleteGlobalRef(env, jsigar->logger);
|
|
}
|
|
|
|
if (jsigar->not_impl != NULL) {
|
|
JENV->DeleteGlobalRef(env, jsigar->not_impl);
|
|
}
|
|
|
|
for (i=0; i<JSIGAR_FIELDS_MAX; i++) {
|
|
if (jsigar->fields[i]) {
|
|
JENV->DeleteGlobalRef(env,
|
|
jsigar->fields[i]->classref);
|
|
free(jsigar->fields[i]->ids);
|
|
free(jsigar->fields[i]);
|
|
}
|
|
}
|
|
|
|
free(jsigar);
|
|
sigar_set_pointer(env, sigar_obj, NULL);
|
|
|
|
return status;
|
|
}
|
|
|
|
JNIEXPORT jlong SIGAR_JNIx(getPid)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
dSIGAR(0);
|
|
|
|
return sigar_pid_get(sigar);
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNIx(kill)
|
|
(JNIEnv *env, jobject sigar_obj, jlong pid, jint signum)
|
|
{
|
|
int status;
|
|
dSIGAR_VOID;
|
|
|
|
if ((status = sigar_proc_kill(pid, signum)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jint SIGAR_JNIx(getSigNum)
|
|
(JNIEnv *env, jclass cls_obj, jstring jname)
|
|
{
|
|
jboolean is_copy;
|
|
const char *name;
|
|
int num;
|
|
|
|
name = JENV->GetStringUTFChars(env, jname, &is_copy);
|
|
|
|
num = sigar_signum_get((char *)name);
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, jname, name);
|
|
}
|
|
|
|
return num;
|
|
}
|
|
|
|
#define SetStringField(env, obj, fieldID, val) \
|
|
SetObjectField(env, obj, fieldID, JENV->NewStringUTF(env, val))
|
|
|
|
static jstring jnet_address_to_string(JNIEnv *env, sigar_t *sigar, sigar_net_address_t *val) {
|
|
char addr_str[SIGAR_INET6_ADDRSTRLEN];
|
|
sigar_net_address_to_string(sigar, val, addr_str);
|
|
return JENV->NewStringUTF(env, addr_str);
|
|
}
|
|
|
|
#define SetNetAddressField(env, obj, fieldID, val) \
|
|
SetObjectField(env, obj, fieldID, jnet_address_to_string(env, sigar, &val))
|
|
|
|
#include "javasigar_generated.c"
|
|
|
|
#define SIGAR_ALLOC_OBJECT(name) \
|
|
JENV->AllocObject(env, SIGAR_FIND_CLASS(name))
|
|
|
|
enum {
|
|
FS_FIELD_DIRNAME,
|
|
FS_FIELD_DEVNAME,
|
|
FS_FIELD_SYS_TYPENAME,
|
|
FS_FIELD_TYPE,
|
|
FS_FIELD_TYPENAME,
|
|
FS_FIELD_MAX
|
|
};
|
|
|
|
#define STRING_SIG "Ljava/lang/String;"
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getFileSystemListNative)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
sigar_file_system_list_t fslist;
|
|
jobjectArray fsarray;
|
|
jfieldID ids[FS_FIELD_MAX];
|
|
jclass nfs_cls=NULL, cls = SIGAR_FIND_CLASS("FileSystem");
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_file_system_list_get(sigar, &fslist)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
ids[FS_FIELD_DIRNAME] =
|
|
JENV->GetFieldID(env, cls, "dirName", STRING_SIG);
|
|
|
|
ids[FS_FIELD_DEVNAME] =
|
|
JENV->GetFieldID(env, cls, "devName", STRING_SIG);
|
|
|
|
ids[FS_FIELD_TYPENAME] =
|
|
JENV->GetFieldID(env, cls, "typeName", STRING_SIG);
|
|
|
|
ids[FS_FIELD_SYS_TYPENAME] =
|
|
JENV->GetFieldID(env, cls, "sysTypeName", STRING_SIG);
|
|
|
|
ids[FS_FIELD_TYPE] =
|
|
JENV->GetFieldID(env, cls, "type", "I");
|
|
|
|
fsarray = JENV->NewObjectArray(env, fslist.number, cls, 0);
|
|
|
|
for (i=0; i<fslist.number; i++) {
|
|
sigar_file_system_t *fs = &(fslist.data)[i];
|
|
jobject fsobj;
|
|
jclass obj_cls;
|
|
|
|
#ifdef WIN32
|
|
obj_cls = cls;
|
|
#else
|
|
if ((fs->type == SIGAR_FSTYPE_NETWORK) &&
|
|
(strcmp(fs->sys_type_name, "nfs") == 0) &&
|
|
strstr(fs->dev_name, ":/"))
|
|
{
|
|
if (!nfs_cls) {
|
|
nfs_cls = SIGAR_FIND_CLASS("NfsFileSystem");
|
|
}
|
|
obj_cls = nfs_cls;
|
|
}
|
|
else {
|
|
obj_cls = cls;
|
|
}
|
|
#endif
|
|
|
|
fsobj = JENV->AllocObject(env, obj_cls);
|
|
|
|
JENV->SetStringField(env, fsobj,
|
|
ids[FS_FIELD_DIRNAME],
|
|
fs->dir_name);
|
|
|
|
JENV->SetStringField(env, fsobj,
|
|
ids[FS_FIELD_DEVNAME],
|
|
fs->dev_name);
|
|
|
|
JENV->SetStringField(env, fsobj,
|
|
ids[FS_FIELD_SYS_TYPENAME],
|
|
fs->sys_type_name);
|
|
|
|
JENV->SetStringField(env, fsobj,
|
|
ids[FS_FIELD_TYPENAME],
|
|
fs->type_name);
|
|
|
|
JENV->SetIntField(env, fsobj,
|
|
ids[FS_FIELD_TYPE],
|
|
fs->type);
|
|
|
|
JENV->SetObjectArrayElement(env, fsarray, i, fsobj);
|
|
}
|
|
|
|
sigar_file_system_list_destroy(sigar, &fslist);
|
|
|
|
return fsarray;
|
|
}
|
|
|
|
JNIEXPORT jint SIGAR_JNI(RPC_ping)
|
|
(JNIEnv *env, jclass cls_obj, jstring jhostname,
|
|
jint protocol, jlong program, jlong version)
|
|
{
|
|
#ifdef WIN32
|
|
return JNI_FALSE; /*XXX*/
|
|
#else
|
|
jboolean is_copy;
|
|
const char *hostname;
|
|
int status;
|
|
|
|
if (!jhostname) {
|
|
return 13; /* RPC_UNKNOWNHOST */
|
|
}
|
|
|
|
hostname = JENV->GetStringUTFChars(env, jhostname, &is_copy);
|
|
|
|
status =
|
|
sigar_rpc_ping((char *)hostname,
|
|
protocol, program, version);
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, jhostname, hostname);
|
|
}
|
|
|
|
return status;
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(RPC_strerror)
|
|
(JNIEnv *env, jclass cls_obj, jint err)
|
|
{
|
|
#ifdef WIN32
|
|
return NULL;
|
|
#else
|
|
return JENV->NewStringUTF(env, sigar_rpc_strerror(err));
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getCpuInfoList)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
sigar_cpu_info_list_t cpu_infos;
|
|
jobjectArray cpuarray;
|
|
jclass cls = SIGAR_FIND_CLASS("CpuInfo");
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_cpu_info_list_get(sigar, &cpu_infos)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
JAVA_SIGAR_INIT_FIELDS_CPUINFO(cls);
|
|
|
|
cpuarray = JENV->NewObjectArray(env, cpu_infos.number, cls, 0);
|
|
|
|
for (i=0; i<cpu_infos.number; i++) {
|
|
jobject info_obj = JENV->AllocObject(env, cls);
|
|
JAVA_SIGAR_SET_FIELDS_CPUINFO(cls, info_obj,
|
|
cpu_infos.data[i]);
|
|
JENV->SetObjectArrayElement(env, cpuarray, i, info_obj);
|
|
}
|
|
|
|
sigar_cpu_info_list_destroy(sigar, &cpu_infos);
|
|
|
|
return cpuarray;
|
|
}
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getCpuListNative)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
sigar_cpu_list_t cpulist;
|
|
jobjectArray cpuarray;
|
|
jclass cls = SIGAR_FIND_CLASS("Cpu");
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_cpu_list_get(sigar, &cpulist)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
JAVA_SIGAR_INIT_FIELDS_CPU(cls);
|
|
|
|
cpuarray = JENV->NewObjectArray(env, cpulist.number, cls, 0);
|
|
|
|
for (i=0; i<cpulist.number; i++) {
|
|
jobject info_obj = JENV->AllocObject(env, cls);
|
|
JAVA_SIGAR_SET_FIELDS_CPU(cls, info_obj,
|
|
cpulist.data[i]);
|
|
JENV->SetObjectArrayElement(env, cpuarray, i, info_obj);
|
|
}
|
|
|
|
sigar_cpu_list_destroy(sigar, &cpulist);
|
|
|
|
return cpuarray;
|
|
}
|
|
|
|
JNIEXPORT jlongArray SIGAR_JNIx(getProcList)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
jlongArray procarray;
|
|
sigar_proc_list_t proclist;
|
|
jlong *pids = NULL;
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_proc_list_get(sigar, &proclist)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
procarray = JENV->NewLongArray(env, proclist.number);
|
|
|
|
if (sizeof(jlong) == sizeof(sigar_pid_t)) {
|
|
pids = (jlong *)proclist.data;
|
|
}
|
|
else {
|
|
unsigned int i;
|
|
pids = (jlong *)malloc(sizeof(jlong) * proclist.number);
|
|
|
|
for (i=0; i<proclist.number; i++) {
|
|
pids[i] = proclist.data[i];
|
|
}
|
|
}
|
|
|
|
JENV->SetLongArrayRegion(env, procarray, 0,
|
|
proclist.number, pids);
|
|
|
|
if (pids != (jlong *)proclist.data) {
|
|
free(pids);
|
|
}
|
|
|
|
sigar_proc_list_destroy(sigar, &proclist);
|
|
|
|
return procarray;
|
|
}
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getProcArgs)
|
|
(JNIEnv *env, jobject sigar_obj, jlong pid)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
sigar_proc_args_t procargs;
|
|
jobjectArray argsarray;
|
|
jclass stringclass = JENV->FindClass(env, "java/lang/String");
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_proc_args_get(sigar, pid, &procargs)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
argsarray = JENV->NewObjectArray(env, procargs.number, stringclass, 0);
|
|
|
|
for (i=0; i<procargs.number; i++) {
|
|
jstring s = JENV->NewStringUTF(env, procargs.data[i]);
|
|
JENV->SetObjectArrayElement(env, argsarray, i, s);
|
|
}
|
|
|
|
sigar_proc_args_destroy(sigar, &procargs);
|
|
|
|
return argsarray;
|
|
}
|
|
|
|
typedef struct {
|
|
JNIEnv *env;
|
|
jobject map;
|
|
jmethodID id;
|
|
} jni_env_put_t;
|
|
|
|
static int jni_env_getall(void *data,
|
|
const char *key, int klen,
|
|
char *val, int vlen)
|
|
{
|
|
jni_env_put_t *put = (jni_env_put_t *)data;
|
|
JNIEnv *env = put->env;
|
|
|
|
JENV->CallObjectMethod(env, put->map, put->id,
|
|
JENV->NewStringUTF(env, key),
|
|
JENV->NewStringUTF(env, val));
|
|
|
|
return SIGAR_OK;
|
|
}
|
|
|
|
JNIEXPORT jobject SIGAR_JNI(ProcEnv_getAll)
|
|
(JNIEnv *env, jobject cls, jobject sigar_obj, jlong pid)
|
|
{
|
|
int status;
|
|
sigar_proc_env_t procenv;
|
|
jobject hashmap;
|
|
jni_env_put_t put;
|
|
jclass mapclass =
|
|
JENV->FindClass(env, "java/util/HashMap");
|
|
jmethodID mapid =
|
|
JENV->GetMethodID(env, mapclass, "<init>", "()V");
|
|
jmethodID putid =
|
|
JENV->GetMethodID(env, mapclass, "put",
|
|
"(Ljava/lang/Object;Ljava/lang/Object;)"
|
|
"Ljava/lang/Object;");
|
|
dSIGAR(NULL);
|
|
|
|
hashmap = JENV->NewObject(env, mapclass, mapid);
|
|
|
|
put.env = env;
|
|
put.id = putid;
|
|
put.map = hashmap;
|
|
|
|
procenv.type = SIGAR_PROC_ENV_ALL;
|
|
procenv.env_getter = jni_env_getall;
|
|
procenv.data = &put;
|
|
|
|
if ((status = sigar_proc_env_get(sigar, pid, &procenv)) != SIGAR_OK) {
|
|
JENV->DeleteLocalRef(env, hashmap);
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
return hashmap;
|
|
}
|
|
|
|
typedef struct {
|
|
JNIEnv *env;
|
|
const char *key;
|
|
int klen;
|
|
jstring val;
|
|
} jni_env_get_t;
|
|
|
|
static int jni_env_getvalue(void *data,
|
|
const char *key, int klen,
|
|
char *val, int vlen)
|
|
{
|
|
jni_env_get_t *get = (jni_env_get_t *)data;
|
|
JNIEnv *env = get->env;
|
|
|
|
if ((get->klen == klen) &&
|
|
(strcmp(get->key, key) == 0))
|
|
{
|
|
get->val = JENV->NewStringUTF(env, val);
|
|
return !SIGAR_OK; /* foundit; stop iterating */
|
|
}
|
|
|
|
return SIGAR_OK;
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(ProcEnv_getValue)
|
|
(JNIEnv *env, jobject cls, jobject sigar_obj, jlong pid, jstring key)
|
|
{
|
|
int status;
|
|
sigar_proc_env_t procenv;
|
|
jni_env_get_t get;
|
|
dSIGAR(NULL);
|
|
|
|
get.env = env;
|
|
get.key = JENV->GetStringUTFChars(env, key, 0);
|
|
get.klen = JENV->GetStringUTFLength(env, key);
|
|
get.val = NULL;
|
|
|
|
procenv.type = SIGAR_PROC_ENV_KEY;
|
|
procenv.key = get.key;
|
|
procenv.klen = get.klen;
|
|
procenv.env_getter = jni_env_getvalue;
|
|
procenv.data = &get;
|
|
|
|
if ((status = sigar_proc_env_get(sigar, pid, &procenv)) != SIGAR_OK) {
|
|
JENV->ReleaseStringUTFChars(env, key, get.key);
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
JENV->ReleaseStringUTFChars(env, key, get.key);
|
|
|
|
return get.val;
|
|
}
|
|
|
|
typedef struct {
|
|
JNIEnv *env;
|
|
jobject listobj;
|
|
jmethodID id;
|
|
} jni_proc_module_t;
|
|
|
|
static int jni_proc_module_get(void *data,
|
|
char *name, int len)
|
|
{
|
|
jni_proc_module_t *module = (jni_proc_module_t *)data;
|
|
JNIEnv *env = module->env;
|
|
|
|
JENV->CallBooleanMethod(env, module->listobj, module->id,
|
|
JENV->NewStringUTF(env, name));
|
|
|
|
return SIGAR_OK;
|
|
}
|
|
|
|
JNIEXPORT jobject SIGAR_JNIx(getProcModulesNative)
|
|
(JNIEnv *env, jobject sigar_obj, jlong pid)
|
|
{
|
|
int status;
|
|
sigar_proc_modules_t procmods;
|
|
jobject listobj;
|
|
jni_proc_module_t module;
|
|
jclass listclass =
|
|
JENV->FindClass(env, "java/util/ArrayList");
|
|
jmethodID listid =
|
|
JENV->GetMethodID(env, listclass, "<init>", "()V");
|
|
jmethodID addid =
|
|
JENV->GetMethodID(env, listclass, "add",
|
|
"(Ljava/lang/Object;)"
|
|
"Z");
|
|
dSIGAR(NULL);
|
|
|
|
listobj = JENV->NewObject(env, listclass, listid);
|
|
|
|
module.env = env;
|
|
module.id = addid;
|
|
module.listobj = listobj;
|
|
|
|
procmods.module_getter = jni_proc_module_get;
|
|
procmods.data = &module;
|
|
|
|
if ((status = sigar_proc_modules_get(sigar, pid, &procmods)) != SIGAR_OK) {
|
|
JENV->DeleteLocalRef(env, listobj);
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
return listobj;
|
|
}
|
|
|
|
JNIEXPORT jdoubleArray SIGAR_JNIx(getLoadAverage)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
jlongArray avgarray;
|
|
sigar_loadavg_t loadavg;
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_loadavg_get(sigar, &loadavg)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
avgarray = JENV->NewDoubleArray(env, 3);
|
|
|
|
JENV->SetDoubleArrayRegion(env, avgarray, 0,
|
|
3, loadavg.loadavg);
|
|
|
|
return avgarray;
|
|
}
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getNetRouteList)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
jarray routearray;
|
|
jclass cls = SIGAR_FIND_CLASS("NetRoute");
|
|
sigar_net_route_list_t routelist;
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_net_route_list_get(sigar, &routelist)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
JAVA_SIGAR_INIT_FIELDS_NETROUTE(cls);
|
|
|
|
routearray = JENV->NewObjectArray(env, routelist.number, cls, 0);
|
|
|
|
for (i=0; i<routelist.number; i++) {
|
|
jobject obj = JENV->AllocObject(env, cls);
|
|
JAVA_SIGAR_SET_FIELDS_NETROUTE(cls, obj, routelist.data[i]);
|
|
JENV->SetObjectArrayElement(env, routearray, i, obj);
|
|
}
|
|
|
|
sigar_net_route_list_destroy(sigar, &routelist);
|
|
|
|
return routearray;
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(NetFlags_getIfFlagsString)
|
|
(JNIEnv *env, jclass cls, jlong flags)
|
|
{
|
|
char buf[1024];
|
|
sigar_net_interface_flags_to_string(flags, buf);
|
|
return JENV->NewStringUTF(env, buf);
|
|
}
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getNetConnectionList)
|
|
(JNIEnv *env, jobject sigar_obj, jint flags)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
jarray connarray;
|
|
jclass cls = SIGAR_FIND_CLASS("NetConnection");
|
|
sigar_net_connection_list_t connlist;
|
|
dSIGAR(NULL);
|
|
|
|
status = sigar_net_connection_list_get(sigar, &connlist, flags);
|
|
|
|
if (status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
JAVA_SIGAR_INIT_FIELDS_NETCONNECTION(cls);
|
|
|
|
connarray = JENV->NewObjectArray(env, connlist.number, cls, 0);
|
|
|
|
for (i=0; i<connlist.number; i++) {
|
|
jobject obj = JENV->AllocObject(env, cls);
|
|
JAVA_SIGAR_SET_FIELDS_NETCONNECTION(cls, obj, connlist.data[i]);
|
|
JENV->SetObjectArrayElement(env, connarray, i, obj);
|
|
}
|
|
|
|
sigar_net_connection_list_destroy(sigar, &connlist);
|
|
|
|
return connarray;
|
|
}
|
|
|
|
static int jbyteArray_to_sigar_net_address(JNIEnv *env, jbyteArray jaddress,
|
|
sigar_net_address_t *address)
|
|
{
|
|
jsize len = JENV->GetArrayLength(env, jaddress);
|
|
|
|
JENV->GetByteArrayRegion(env, jaddress, 0, len,
|
|
(jbyte *)&address->addr.in6);
|
|
|
|
switch (len) {
|
|
case 4:
|
|
address->family = SIGAR_AF_INET;
|
|
break;
|
|
case 4*4:
|
|
address->family = SIGAR_AF_INET6;
|
|
break;
|
|
default:
|
|
return EINVAL;
|
|
}
|
|
|
|
return SIGAR_OK;
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(NetStat_stat)
|
|
(JNIEnv *env, jobject obj, jobject sigar_obj, jint flags,
|
|
jbyteArray jaddress, jlong port)
|
|
{
|
|
int status;
|
|
sigar_net_stat_t netstat;
|
|
jclass cls;
|
|
jfieldID id;
|
|
jintArray states;
|
|
jint tcp_states[SIGAR_TCP_UNKNOWN];
|
|
sigar_net_address_t address;
|
|
jboolean has_port = (port != -1);
|
|
dSIGAR_VOID;
|
|
|
|
if (has_port) {
|
|
status = jbyteArray_to_sigar_net_address(env, jaddress, &address);
|
|
if (status == SIGAR_OK) {
|
|
status = sigar_net_stat_port_get(sigar, &netstat, flags,
|
|
&address, port);
|
|
}
|
|
}
|
|
else {
|
|
status = sigar_net_stat_get(sigar, &netstat, flags);
|
|
}
|
|
|
|
if (status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return;
|
|
}
|
|
|
|
cls = JENV->GetObjectClass(env, obj);
|
|
|
|
JAVA_SIGAR_INIT_FIELDS_NETSTAT(cls);
|
|
JAVA_SIGAR_SET_FIELDS_NETSTAT(cls, obj, netstat);
|
|
|
|
if (sizeof(tcp_states[0]) == sizeof(netstat.tcp_states[0])) {
|
|
memcpy(&tcp_states[0], &netstat.tcp_states[0],
|
|
sizeof(netstat.tcp_states));
|
|
}
|
|
else {
|
|
int i;
|
|
for (i=0; i<SIGAR_TCP_UNKNOWN; i++) {
|
|
tcp_states[i] = netstat.tcp_states[i];
|
|
}
|
|
}
|
|
|
|
states = JENV->NewIntArray(env, SIGAR_TCP_UNKNOWN);
|
|
JENV->SetIntArrayRegion(env, states, 0,
|
|
SIGAR_TCP_UNKNOWN,
|
|
tcp_states);
|
|
|
|
id = JENV->GetFieldID(env, cls, "tcpStates", "[I");
|
|
JENV->SetObjectField(env, obj, id, states);
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNIx(getNetListenAddress)
|
|
(JNIEnv *env, jobject sigar_obj, jlong port)
|
|
{
|
|
int status;
|
|
sigar_net_address_t address;
|
|
dSIGAR(NULL);
|
|
|
|
status = sigar_net_listen_address_get(sigar, port, &address);
|
|
if (status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
return jnet_address_to_string(env, sigar, &address);
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNIx(getNetServicesName)
|
|
(JNIEnv *env, jobject sigar_obj, jint protocol, jlong port)
|
|
{
|
|
char *name;
|
|
dSIGAR(NULL);
|
|
|
|
if ((name = sigar_net_services_name_get(sigar, protocol, port))) {
|
|
return JENV->NewStringUTF(env, name);
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(NetConnection_getTypeString)
|
|
(JNIEnv *env, jobject obj)
|
|
{
|
|
jclass cls = JENV->GetObjectClass(env, obj);
|
|
jfieldID field = JENV->GetFieldID(env, cls, "type", "I");
|
|
jint type = JENV->GetIntField(env, obj, field);
|
|
return JENV->NewStringUTF(env,
|
|
sigar_net_connection_type_get(type));
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(NetConnection_getStateString)
|
|
(JNIEnv *env, jobject cls, jint state)
|
|
{
|
|
return JENV->NewStringUTF(env,
|
|
sigar_net_connection_state_get(state));
|
|
}
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getWhoList)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
sigar_who_list_t wholist;
|
|
jobjectArray whoarray;
|
|
jclass cls = SIGAR_FIND_CLASS("Who");
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_who_list_get(sigar, &wholist)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
JAVA_SIGAR_INIT_FIELDS_WHO(cls);
|
|
|
|
whoarray = JENV->NewObjectArray(env, wholist.number, cls, 0);
|
|
|
|
for (i=0; i<wholist.number; i++) {
|
|
jobject info_obj = JENV->AllocObject(env, cls);
|
|
JAVA_SIGAR_SET_FIELDS_WHO(cls, info_obj,
|
|
wholist.data[i]);
|
|
JENV->SetObjectArrayElement(env, whoarray, i, info_obj);
|
|
}
|
|
|
|
sigar_who_list_destroy(sigar, &wholist);
|
|
|
|
return whoarray;
|
|
}
|
|
|
|
/* XXX perhaps it would be better to duplicate these strings
|
|
* in java land as static final so we dont create a new String
|
|
* everytime.
|
|
*/
|
|
JNIEXPORT jstring SIGAR_JNI(FileInfo_getTypeString)
|
|
(JNIEnv *env, jclass cls, jint type)
|
|
{
|
|
return JENV->NewStringUTF(env,
|
|
sigar_file_attrs_type_string_get(type));
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(FileInfo_getPermissionsString)
|
|
(JNIEnv *env, jclass cls, jlong perms)
|
|
{
|
|
char str[24];
|
|
return JENV->NewStringUTF(env,
|
|
sigar_file_attrs_permissions_string_get(perms,
|
|
str));
|
|
}
|
|
|
|
JNIEXPORT jint SIGAR_JNI(FileInfo_getMode)
|
|
(JNIEnv *env, jclass cls, jlong perms)
|
|
{
|
|
return sigar_file_attrs_mode_get(perms);
|
|
}
|
|
|
|
|
|
/*
|
|
* copy of the generated FileAttrs_gather function
|
|
* but we call the lstat wrapper instead.
|
|
*/
|
|
JNIEXPORT void SIGAR_JNI(FileInfo_gatherLink)
|
|
(JNIEnv *env, jobject obj, jobject sigar_obj, jstring name)
|
|
{
|
|
sigar_file_attrs_t s;
|
|
int status;
|
|
jclass cls = JENV->GetObjectClass(env, obj);
|
|
const char *utf;
|
|
dSIGAR_VOID;
|
|
|
|
utf = JENV->GetStringUTFChars(env, name, 0);
|
|
|
|
status = sigar_link_attrs_get(sigar, utf, &s);
|
|
|
|
JENV->ReleaseStringUTFChars(env, name, utf);
|
|
|
|
if (status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return;
|
|
}
|
|
|
|
JAVA_SIGAR_INIT_FIELDS_FILEATTRS(cls);
|
|
|
|
JAVA_SIGAR_SET_FIELDS_FILEATTRS(cls, obj, s);
|
|
}
|
|
|
|
JNIEXPORT jlong SIGAR_JNIx(getProcPort)
|
|
(JNIEnv *env, jobject sigar_obj, jint protocol, jlong port)
|
|
{
|
|
int status;
|
|
sigar_pid_t pid;
|
|
dSIGAR(0);
|
|
|
|
status = sigar_proc_port_get(sigar, protocol,
|
|
(unsigned long)port, &pid);
|
|
if (status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return -1;
|
|
}
|
|
|
|
return pid;
|
|
}
|
|
|
|
JNIEXPORT jobjectArray SIGAR_JNIx(getNetInterfaceList)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
unsigned int i;
|
|
sigar_net_interface_list_t iflist;
|
|
jobjectArray ifarray;
|
|
jclass stringclass = JENV->FindClass(env, "java/lang/String");
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_net_interface_list_get(sigar, &iflist)) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
ifarray = JENV->NewObjectArray(env, iflist.number, stringclass, 0);
|
|
|
|
for (i=0; i<iflist.number; i++) {
|
|
jstring s = JENV->NewStringUTF(env, iflist.data[i]);
|
|
JENV->SetObjectArrayElement(env, ifarray, i, s);
|
|
}
|
|
|
|
sigar_net_interface_list_destroy(sigar, &iflist);
|
|
|
|
return ifarray;
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNIx(getPasswordNative)
|
|
(JNIEnv *env, jclass classinstance, jstring prompt)
|
|
{
|
|
const char *prompt_str;
|
|
char *password;
|
|
|
|
if (getenv("NO_NATIVE_GETPASS")) {
|
|
sigar_throw_notimpl(env, "disabled with $NO_NATIVE_GETPASS");
|
|
return NULL;
|
|
}
|
|
|
|
prompt_str = JENV->GetStringUTFChars(env, prompt, 0);
|
|
|
|
password = sigar_password_get(prompt_str);
|
|
|
|
JENV->ReleaseStringUTFChars(env, prompt, prompt_str);
|
|
|
|
return JENV->NewStringUTF(env, password);
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNIx(getFQDN)
|
|
(JNIEnv *env, jobject sigar_obj)
|
|
{
|
|
char fqdn[SIGAR_FQDN_LEN];
|
|
int status;
|
|
dSIGAR(NULL);
|
|
|
|
if ((status = sigar_fqdn_get(sigar, fqdn, sizeof(fqdn))) != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
return JENV->NewStringUTF(env, fqdn);
|
|
}
|
|
|
|
typedef struct {
|
|
JNIEnv *env;
|
|
jobject obj;
|
|
jclass cls;
|
|
jmethodID id;
|
|
} jni_ptql_re_data_t;
|
|
|
|
static int jsigar_ptql_re_impl(void *data,
|
|
char *haystack, char *needle)
|
|
{
|
|
jni_ptql_re_data_t *re = (jni_ptql_re_data_t *)data;
|
|
JNIEnv *env = re->env;
|
|
|
|
if (!re->cls) {
|
|
re->cls = JENV->GetObjectClass(env, re->obj);
|
|
re->id =
|
|
JENV->GetStaticMethodID(env, re->cls, "re",
|
|
"(Ljava/lang/String;Ljava/lang/String;)"
|
|
"Z");
|
|
if (!re->id) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return JENV->CallStaticBooleanMethod(env, re->cls, re->id,
|
|
JENV->NewStringUTF(env, haystack),
|
|
JENV->NewStringUTF(env, needle));
|
|
}
|
|
|
|
static void re_impl_set(JNIEnv *env, sigar_t *sigar, jobject obj, jni_ptql_re_data_t *re)
|
|
{
|
|
re->env = env;
|
|
re->cls = NULL;
|
|
re->obj = obj;
|
|
re->id = NULL;
|
|
|
|
sigar_ptql_re_impl_set(sigar, re, jsigar_ptql_re_impl);
|
|
}
|
|
|
|
JNIEXPORT jboolean SIGAR_JNI(ptql_SigarProcessQuery_match)
|
|
(JNIEnv *env, jobject obj, jobject sigar_obj, jlong pid)
|
|
{
|
|
int status;
|
|
jni_ptql_re_data_t re;
|
|
sigar_ptql_query_t *query =
|
|
(sigar_ptql_query_t *)sigar_get_pointer(env, obj);
|
|
dSIGAR(JNI_FALSE);
|
|
|
|
re_impl_set(env, sigar, obj, &re);
|
|
|
|
status = sigar_ptql_query_match(sigar, query, pid);
|
|
|
|
sigar_ptql_re_impl_set(sigar, NULL, NULL);
|
|
|
|
if (status == SIGAR_OK) {
|
|
return JNI_TRUE;
|
|
}
|
|
else {
|
|
return JNI_FALSE;
|
|
}
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(ptql_SigarProcessQuery_create)
|
|
(JNIEnv *env, jobject obj, jstring jptql)
|
|
{
|
|
int status;
|
|
jboolean is_copy;
|
|
const char *ptql;
|
|
sigar_ptql_query_t *query;
|
|
|
|
ptql = JENV->GetStringUTFChars(env, jptql, &is_copy);
|
|
status = sigar_ptql_query_create(&query, (char *)ptql);
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, jptql, ptql);
|
|
}
|
|
|
|
if (status != SIGAR_OK) {
|
|
char buf[1024], *msg=buf;
|
|
if (status == SIGAR_PTQL_MALFORMED_QUERY) {
|
|
msg = "Malformed query";
|
|
}
|
|
else {
|
|
sigar_strerror_get(status, buf, sizeof(buf));
|
|
}
|
|
|
|
sigar_throw_ptql_malformed(env, msg);
|
|
}
|
|
else {
|
|
sigar_set_pointer(env, obj, query);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(ptql_SigarProcessQuery_destroy)
|
|
(JNIEnv *env, jobject obj)
|
|
{
|
|
sigar_ptql_query_t *query =
|
|
(sigar_ptql_query_t *)sigar_get_pointer(env, obj);
|
|
|
|
if (query) {
|
|
sigar_ptql_query_destroy(query);
|
|
sigar_set_pointer(env, obj, 0);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jlong SIGAR_JNI(ptql_SigarProcessQuery_findProcess)
|
|
(JNIEnv *env, jobject obj, jobject sigar_obj)
|
|
{
|
|
sigar_pid_t pid;
|
|
int status;
|
|
jni_ptql_re_data_t re;
|
|
sigar_ptql_query_t *query =
|
|
(sigar_ptql_query_t *)sigar_get_pointer(env, obj);
|
|
dSIGAR(0);
|
|
|
|
re_impl_set(env, sigar, obj, &re);
|
|
|
|
status = sigar_ptql_query_find_process(sigar, query, &pid);
|
|
|
|
sigar_ptql_re_impl_set(sigar, NULL, NULL);
|
|
|
|
if (status < 0) {
|
|
sigar_throw_exception(env, sigar->errbuf);
|
|
}
|
|
else if (status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
}
|
|
|
|
return pid;
|
|
}
|
|
|
|
JNIEXPORT jlongArray SIGAR_JNI(ptql_SigarProcessQuery_find)
|
|
(JNIEnv *env, jobject obj, jobject sigar_obj)
|
|
{
|
|
int status;
|
|
jlongArray procarray;
|
|
sigar_proc_list_t proclist;
|
|
jlong *pids = NULL;
|
|
jni_ptql_re_data_t re;
|
|
sigar_ptql_query_t *query =
|
|
(sigar_ptql_query_t *)sigar_get_pointer(env, obj);
|
|
dSIGAR(NULL);
|
|
|
|
re_impl_set(env, sigar, obj, &re);
|
|
|
|
status = sigar_ptql_query_find(sigar, query, &proclist);
|
|
|
|
sigar_ptql_re_impl_set(sigar, NULL, NULL);
|
|
|
|
if (status < 0) {
|
|
sigar_throw_exception(env, sigar->errbuf);
|
|
return NULL;
|
|
}
|
|
else if (status != SIGAR_OK) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
return NULL;
|
|
}
|
|
|
|
procarray = JENV->NewLongArray(env, proclist.number);
|
|
|
|
if (sizeof(jlong) == sizeof(sigar_pid_t)) {
|
|
pids = (jlong *)proclist.data;
|
|
}
|
|
else {
|
|
unsigned int i;
|
|
pids = (jlong *)malloc(sizeof(jlong) * proclist.number);
|
|
|
|
for (i=0; i<proclist.number; i++) {
|
|
pids[i] = proclist.data[i];
|
|
}
|
|
}
|
|
|
|
JENV->SetLongArrayRegion(env, procarray, 0,
|
|
proclist.number, pids);
|
|
|
|
if (pids != (jlong *)proclist.data) {
|
|
free(pids);
|
|
}
|
|
|
|
sigar_proc_list_destroy(sigar, &proclist);
|
|
|
|
return procarray;
|
|
}
|
|
|
|
#include "sigar_getline.h"
|
|
|
|
JNIEXPORT jboolean SIGAR_JNI(util_Getline_isatty)
|
|
(JNIEnv *env, jclass cls)
|
|
{
|
|
return sigar_isatty(sigar_fileno(stdin)) ? JNI_TRUE : JNI_FALSE;
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(util_Getline_getline)
|
|
(JNIEnv *env, jobject sigar_obj, jstring prompt)
|
|
{
|
|
const char *prompt_str;
|
|
char *line;
|
|
jboolean is_copy;
|
|
|
|
prompt_str = JENV->GetStringUTFChars(env, prompt, &is_copy);
|
|
|
|
line = sigar_getline((char *)prompt_str);
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, prompt, prompt_str);
|
|
}
|
|
|
|
if ((line == NULL) ||
|
|
sigar_getline_eof())
|
|
{
|
|
jclass eof_ex = JENV->FindClass(env, "java/io/EOFException");
|
|
JENV->ThrowNew(env, eof_ex, "");
|
|
return NULL;
|
|
}
|
|
|
|
return JENV->NewStringUTF(env, line);
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(util_Getline_histadd)
|
|
(JNIEnv *env, jobject sigar_obj, jstring hist)
|
|
{
|
|
const char *hist_str;
|
|
jboolean is_copy;
|
|
|
|
hist_str = JENV->GetStringUTFChars(env, hist, &is_copy);
|
|
|
|
sigar_getline_histadd((char *)hist_str);
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, hist, hist_str);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(util_Getline_histinit)
|
|
(JNIEnv *env, jobject sigar_obj, jstring hist)
|
|
{
|
|
const char *hist_str;
|
|
jboolean is_copy;
|
|
|
|
hist_str = JENV->GetStringUTFChars(env, hist, &is_copy);
|
|
|
|
sigar_getline_histinit((char *)hist_str);
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, hist, hist_str);
|
|
}
|
|
}
|
|
|
|
static struct {
|
|
JNIEnv *env;
|
|
jobject obj;
|
|
jmethodID id;
|
|
jclass clazz;
|
|
} jsigar_completer;
|
|
|
|
static int jsigar_getline_completer(char *buffer, int offset, int *pos)
|
|
{
|
|
JNIEnv *env = jsigar_completer.env;
|
|
jstring jbuffer;
|
|
jstring completion;
|
|
const char *line;
|
|
int len, cur;
|
|
jboolean is_copy;
|
|
|
|
jbuffer = JENV->NewStringUTF(env, buffer);
|
|
|
|
completion =
|
|
JENV->CallObjectMethod(env, jsigar_completer.obj,
|
|
jsigar_completer.id, jbuffer);
|
|
|
|
if (JENV->ExceptionOccurred(env)) {
|
|
JENV->ExceptionDescribe(env);
|
|
return 0;
|
|
}
|
|
|
|
if (!completion) {
|
|
return 0;
|
|
}
|
|
|
|
line = JENV->GetStringUTFChars(env, completion, &is_copy);
|
|
len = JENV->GetStringUTFLength(env, completion);
|
|
|
|
cur = *pos;
|
|
|
|
if (len != cur) {
|
|
strcpy(buffer, line);
|
|
*pos = len;
|
|
}
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, completion, line);
|
|
}
|
|
|
|
return cur;
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(util_Getline_setCompleter)
|
|
(JNIEnv *env, jclass classinstance, jobject completer)
|
|
{
|
|
if (completer == NULL) {
|
|
sigar_getline_completer_set(NULL);
|
|
return;
|
|
}
|
|
|
|
jsigar_completer.env = env;
|
|
jsigar_completer.obj = completer;
|
|
jsigar_completer.clazz = JENV->GetObjectClass(env, completer);
|
|
jsigar_completer.id =
|
|
JENV->GetMethodID(env, jsigar_completer.clazz,
|
|
"complete",
|
|
"(Ljava/lang/String;)Ljava/lang/String;");
|
|
|
|
sigar_getline_completer_set(jsigar_getline_completer);
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(util_Getline_redraw)
|
|
(JNIEnv *env, jobject obj)
|
|
{
|
|
sigar_getline_redraw();
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(util_Getline_reset)
|
|
(JNIEnv *env, jobject obj)
|
|
{
|
|
sigar_getline_reset();
|
|
}
|
|
|
|
static const char *log_methods[] = {
|
|
"fatal", /* SIGAR_LOG_FATAL */
|
|
"error", /* SIGAR_LOG_ERROR */
|
|
"warn", /* SIGAR_LOG_WARN */
|
|
"info", /* SIGAR_LOG_INFO */
|
|
"debug", /* SIGAR_LOG_DEBUG */
|
|
/* XXX trace is only in commons-logging??? */
|
|
"debug", /* SIGAR_LOG_TRACE */
|
|
};
|
|
|
|
static void jsigar_log_impl(sigar_t *sigar, void *data,
|
|
int level, char *message)
|
|
{
|
|
jni_sigar_t *jsigar = (jni_sigar_t *)data;
|
|
JNIEnv *env = jsigar->env;
|
|
jobject logger = jsigar->logger;
|
|
jobject message_obj;
|
|
|
|
/* XXX should cache method id lookups */
|
|
jmethodID id =
|
|
JENV->GetMethodID(env, JENV->GetObjectClass(env, logger),
|
|
log_methods[level],
|
|
"(Ljava/lang/Object;)V");
|
|
|
|
if (JENV->ExceptionOccurred(env)) {
|
|
JENV->ExceptionDescribe(env);
|
|
return;
|
|
}
|
|
|
|
message_obj = (jobject)JENV->NewStringUTF(env, message);
|
|
|
|
JENV->CallVoidMethod(env, logger, id, message_obj);
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(SigarLog_setLogger)
|
|
(JNIEnv *env, jclass classinstance, jobject sigar_obj, jobject logger)
|
|
{
|
|
dSIGAR_VOID;
|
|
|
|
if (jsigar->logger != NULL) {
|
|
JENV->DeleteGlobalRef(env, jsigar->logger);
|
|
jsigar->logger = NULL;
|
|
}
|
|
|
|
if (logger) {
|
|
jsigar->logger = JENV->NewGlobalRef(env, logger);
|
|
|
|
sigar_log_impl_set(sigar, jsigar, jsigar_log_impl);
|
|
}
|
|
else {
|
|
sigar_log_impl_set(sigar, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT void SIGAR_JNI(SigarLog_setLevel)
|
|
(JNIEnv *env, jclass classinstance, jobject sigar_obj, jint level)
|
|
{
|
|
dSIGAR_VOID;
|
|
|
|
sigar_log_level_set(sigar, level);
|
|
}
|
|
|
|
JNIEXPORT jlong SIGAR_JNIx(getServicePid)
|
|
(JNIEnv *env, jobject sigar_obj, jstring jname)
|
|
{
|
|
#ifdef WIN32
|
|
const char *name;
|
|
jboolean is_copy;
|
|
jlong pid = 0;
|
|
int status;
|
|
dSIGAR(0);
|
|
|
|
name = JENV->GetStringUTFChars(env, jname, &is_copy);
|
|
|
|
status =
|
|
sigar_service_pid_get(sigar, (char *)name, &pid);
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, jname, name);
|
|
}
|
|
|
|
if (status != ERROR_SUCCESS) {
|
|
sigar_throw_error(env, jsigar, status);
|
|
}
|
|
|
|
return pid;
|
|
#else
|
|
dSIGAR(0);
|
|
sigar_throw_error(env, jsigar, SIGAR_ENOTIMPL);
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jlong SIGAR_JNI(ResourceLimit_INFINITY)
|
|
(JNIEnv *env, jclass cls)
|
|
{
|
|
#ifdef WIN32
|
|
return 0x7fffffff;
|
|
#else
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
return RLIM_INFINITY;
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jstring SIGAR_JNI(win32_Win32_findExecutable)
|
|
(JNIEnv *env, jclass sigar_class, jstring jname)
|
|
{
|
|
#ifdef WIN32
|
|
#include "shellapi.h"
|
|
const char *name;
|
|
jboolean is_copy;
|
|
char exe[MAX_PATH];
|
|
LONG result;
|
|
jstring jexe = NULL;
|
|
|
|
name = JENV->GetStringUTFChars(env, jname, &is_copy);
|
|
|
|
if ((result = (LONG)FindExecutable(name, ".", exe)) > 32) {
|
|
jexe = JENV->NewStringUTF(env, exe);
|
|
}
|
|
|
|
if (is_copy) {
|
|
JENV->ReleaseStringUTFChars(env, jname, name);
|
|
}
|
|
|
|
return jexe;
|
|
#else
|
|
sigar_throw_notimpl(env, "win32 only");
|
|
return NULL;
|
|
#endif
|
|
}
|