mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 23:05:47 +02:00
Fix some memory leaks.
This commit is contained in:
parent
cbcaf432bb
commit
367ffc2972
1 changed files with 116 additions and 111 deletions
|
@ -17,115 +17,122 @@ typedef JNIEXPORT char * (JNICALL * JVM_NativePath)(const char *);
|
||||||
void ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
void ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||||
void * GetJVMProc(char * vmlib, char * procName);
|
void * GetJVMProc(char * vmlib, char * procName);
|
||||||
|
|
||||||
|
static void * hVM = NULL; /* Java Virtual Machine handler. */
|
||||||
static void * hVM = NULL; // Java Virtual Machine handler
|
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
(JNIEnv * env, jobject proc, jobjectArray cmdArray, jobjectArray envp, jstring dir, jintArray channels)
|
(JNIEnv * env, jobject proc, jobjectArray cmdArray, jobjectArray envp, jstring dir, jintArray channels)
|
||||||
{
|
{
|
||||||
int fd_map[3]; // File descriptors
|
int fd_map[3]; /* File descriptors. */
|
||||||
int fd_ret[3]; // File descriptors that we return to Java
|
int fd_ret[3]; /* File descriptors that we return to Java. */
|
||||||
int fd[2]; // Pipe open structure
|
int fd[2]; /* Pipe open structure. */
|
||||||
int i;
|
int i;
|
||||||
int nParms = 0;// Number of parameters
|
int nParms = 0;/* Number of parameters. */
|
||||||
int nEnvs = 0;// Number of environment variables
|
int nEnvs = 0;/* Number of environment variables. */
|
||||||
char ** pParms = NULL; // Parameters
|
char ** pParms = NULL; /* Parameters. */
|
||||||
char ** pEnvs = NULL; // Environment variables
|
char ** pEnvs = NULL; /* Environment variables. */
|
||||||
char * pCommand = NULL; // Command to execute
|
char * pCommand = NULL; /* Command to execute. */
|
||||||
char * pwd = 0; // Process working directory
|
char cwd[PATH_MAX + 1]; /* Current working directory. */
|
||||||
char cwd[PATH_MAX + 1]; // Current working directory
|
pid_t pid; /* Process ID. */
|
||||||
pid_t pid; // Process ID
|
struct inheritance inherit;
|
||||||
struct inheritance inherit;
|
|
||||||
|
|
||||||
|
if ((cmdArray == NULL) || ((nParms = (*env)->GetArrayLength(env, cmdArray)) == 0))
|
||||||
|
ThrowByName(env, "java/lang/IOException", "No command line specified");
|
||||||
if ((cmdArray == 0) || ((nParms = (*env) -> GetArrayLength(env, cmdArray)) == 0))
|
|
||||||
ThrowByName(env, "java/lang/NullPointerException", "No command line specified");
|
|
||||||
for(i = 0; i < 3; ++i)
|
|
||||||
{
|
|
||||||
if(EOK != pipe(fd))
|
|
||||||
ThrowByName(env, "java/io/IOException", "Cannot create pipe for spawner");
|
|
||||||
if(0 ==i)
|
|
||||||
{
|
|
||||||
fd_map[i] = fd[0];
|
|
||||||
fd_ret[i] = fd[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fd_map[i] = fd[1];
|
|
||||||
fd_ret[i] = fd[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(nParms > 0)
|
|
||||||
{
|
|
||||||
pParms = malloc(sizeof(char *) * (nParms + 1));
|
|
||||||
for(i = 0; i < nParms; ++i)
|
|
||||||
{
|
|
||||||
jobject item = (*env) -> GetObjectArrayElement(env, cmdArray, i);
|
|
||||||
const char * str = (*env) -> GetStringUTFChars(env, item, 0);
|
|
||||||
if(i == 0)
|
|
||||||
pCommand = strdup(str);
|
|
||||||
pParms[i] = strdup(str);
|
|
||||||
(*env) -> ReleaseStringUTFChars(env, item, str);
|
|
||||||
}
|
|
||||||
pParms[i] = NULL;
|
|
||||||
}
|
|
||||||
nEnvs = (*env) -> GetArrayLength(env, envp);
|
|
||||||
if(nEnvs > 0)
|
|
||||||
{
|
|
||||||
pEnvs = malloc(sizeof(char *) * (nEnvs + 1));
|
|
||||||
for(i = 0; i < nEnvs; ++i)
|
|
||||||
{
|
|
||||||
jobject item = (*env) -> GetObjectArrayElement(env, envp, i);
|
|
||||||
const char * str = (*env) -> GetStringUTFChars(env, item, 0);
|
|
||||||
pEnvs[i] = strdup(str);
|
|
||||||
(*env) -> ReleaseStringUTFChars(env, item, str);
|
|
||||||
}
|
|
||||||
pEnvs[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir != 0)
|
for (i = 0; i < 3; ++i) {
|
||||||
{
|
if (EOK != pipe(fd))
|
||||||
char * item;
|
ThrowByName(env, "java/io/IOException", "Cannot create pipe for spawner");
|
||||||
pwd = strdup(item = (char *)(*env) -> GetStringUTFChars(env, dir, 0));
|
if (0 == i) {
|
||||||
getcwd(cwd, sizeof(cwd));
|
fd_map[i] = fd[0];
|
||||||
chdir(pwd);
|
fd_ret[i] = fd[1];
|
||||||
(*env) -> ReleaseStringUTFChars(env, dir, item);
|
} else {
|
||||||
}
|
fd_map[i] = fd[1];
|
||||||
|
fd_ret[i] = fd[0];
|
||||||
// Nothing for now
|
}
|
||||||
memset(&inherit, 0, sizeof(inherit));
|
}
|
||||||
inherit.flags = SPAWN_SETGROUP;
|
|
||||||
inherit.pgroup = SPAWN_NEWPGROUP;
|
|
||||||
|
|
||||||
pid = spawnp(pCommand, 3, fd_map, &inherit, pParms, pEnvs);
|
|
||||||
|
|
||||||
if(dir != 0) // Restore working directory
|
if (nParms > 0) {
|
||||||
chdir(cwd);
|
pParms = malloc(sizeof(char *) * (nParms + 1));
|
||||||
|
for (i = 0; i < nParms; ++i) {
|
||||||
for(i = 0; i < 3; ++i)
|
jobject item = (*env)->GetObjectArrayElement(env, cmdArray, i);
|
||||||
{
|
const char *str = (*env)->GetStringUTFChars(env, item, 0);
|
||||||
close(fd_map[i]);
|
if (i == 0)
|
||||||
}
|
pCommand = strdup(str);
|
||||||
|
pParms[i] = strdup(str);
|
||||||
if(-1 == pid) // Failed - close pipes
|
(*env)->ReleaseStringUTFChars(env, item, str);
|
||||||
{
|
}
|
||||||
for(i = 0; i < 3; ++i)
|
pParms[i] = NULL;
|
||||||
{
|
}
|
||||||
close(fd_ret[i]);
|
|
||||||
}
|
nEnvs = (*env) -> GetArrayLength(env, envp);
|
||||||
}
|
if (nEnvs > 0) {
|
||||||
else // Success - return pipes to Java
|
pEnvs = malloc(sizeof(char *) * (nEnvs + 1));
|
||||||
{
|
for (i = 0; i < nEnvs; ++i) {
|
||||||
(*env) -> SetIntArrayRegion(env, channels, 0, 3, fd_ret);
|
jobject item = (*env)->GetObjectArrayElement(env, envp, i);
|
||||||
}
|
const char *str = (*env)->GetStringUTFChars(env, item, 0);
|
||||||
|
pEnvs[i] = strdup(str);
|
||||||
return pid;
|
(*env)->ReleaseStringUTFChars(env, item, str);
|
||||||
|
}
|
||||||
|
pEnvs[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir != 0) {
|
||||||
|
char *item = (char *)(*env)->GetStringUTFChars(env, dir, 0);
|
||||||
|
getcwd(cwd, sizeof(cwd));
|
||||||
|
chdir(item);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, dir, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing for now. */
|
||||||
|
memset(&inherit, 0, sizeof(inherit));
|
||||||
|
inherit.flags = SPAWN_SETGROUP;
|
||||||
|
inherit.pgroup = SPAWN_NEWPGROUP;
|
||||||
|
|
||||||
|
pid = spawnp(pCommand, 3, fd_map, &inherit, pParms, pEnvs);
|
||||||
|
|
||||||
|
if (dir != 0) /* Restore working directory. */
|
||||||
|
chdir(cwd);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
close(fd_map[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 == pid) { /* Failed - close pipes. */
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
close(fd_ret[i]);
|
||||||
|
}
|
||||||
|
} else { /* Success - return pipes to Java. */
|
||||||
|
(*env) -> SetIntArrayRegion(env, channels, 0, 3, fd_ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free Parameters. */
|
||||||
|
if (pParms != NULL) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; pParms[j] != NULL; j++) {
|
||||||
|
if (pParms[j] != NULL) {
|
||||||
|
free(pParms[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(pParms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free Environment variables. */
|
||||||
|
if (pEnvs != NULL) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; pEnvs[j] != NULL; j++) {
|
||||||
|
if (pEnvs[j] != NULL) {
|
||||||
|
free(pEnvs[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(pEnvs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free Command to execute. */
|
||||||
|
if (pCommand != NULL) {
|
||||||
|
free(pCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
|
@ -142,11 +149,9 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
pid_t pid; // Process ID
|
pid_t pid; // Process ID
|
||||||
struct inheritance inherit;
|
struct inheritance inherit;
|
||||||
|
|
||||||
|
|
||||||
if ((cmdArray == 0) || ((nParms = (*env) -> GetArrayLength(env, cmdArray)) == 0))
|
if ((cmdArray == 0) || ((nParms = (*env) -> GetArrayLength(env, cmdArray)) == 0))
|
||||||
ThrowByName(env, "java/lang/NullPointerException", "No command line specified");
|
ThrowByName(env, "java/lang/NullPointerException", "No command line specified");
|
||||||
|
|
||||||
|
|
||||||
if(nParms > 0)
|
if(nParms > 0)
|
||||||
{
|
{
|
||||||
pParms = malloc(sizeof(char *) * (nParms + 1));
|
pParms = malloc(sizeof(char *) * (nParms + 1));
|
||||||
|
@ -208,7 +213,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
|
||||||
(JNIEnv * env, jobject proc, jint pid, jint sig)
|
(JNIEnv * env, jobject proc, jint pid, jint sig)
|
||||||
{
|
{
|
||||||
return kill(pid, sig);
|
return kill(pid, sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -219,8 +224,8 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
|
||||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
||||||
(JNIEnv * env, jobject proc, jint pid)
|
(JNIEnv * env, jobject proc, jint pid)
|
||||||
{
|
{
|
||||||
int stat_loc;
|
int stat_loc;
|
||||||
return (waitpid(pid, &stat_loc, WEXITED));
|
return (waitpid(pid, &stat_loc, WEXITED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,13 +233,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
||||||
|
|
||||||
void ThrowByName(JNIEnv *env, const char *name, const char *msg)
|
void ThrowByName(JNIEnv *env, const char *name, const char *msg)
|
||||||
{
|
{
|
||||||
jclass cls = (*env)->FindClass(env, name);
|
jclass cls = (*env)->FindClass(env, name);
|
||||||
|
|
||||||
if (cls != 0) /* Otherwise an exception has already been thrown */
|
if (cls != 0) /* Otherwise an exception has already been thrown */
|
||||||
(*env)->ThrowNew(env, cls, msg);
|
(*env)->ThrowNew(env, cls, msg);
|
||||||
|
|
||||||
/* It's a good practice to clean up the local references. */
|
/* It's a good practice to clean up the local references. */
|
||||||
(*env)->DeleteLocalRef(env, cls);
|
(*env)->DeleteLocalRef(env, cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue