mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
added spawner for linux
This commit is contained in:
parent
c1be110cad
commit
3da18a28f5
13 changed files with 745 additions and 0 deletions
15
core/org.eclipse.cdt.core.linux/.classpath
Normal file
15
core/org.eclipse.cdt.core.linux/.classpath
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.core.resources"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.ui"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.cdt.core"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.core.runtime"/>
|
||||||
|
<classpathentry kind="src" path="/org.apache.xerces"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.search"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.compare"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.debug.ui"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.debug.core"/>
|
||||||
|
<classpathentry kind="src" path="/org.eclipse.core.boot"/>
|
||||||
|
<classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
|
||||||
|
<classpathentry kind="output" path=""/>
|
||||||
|
</classpath>
|
38
core/org.eclipse.cdt.core.linux/.project
Normal file
38
core/org.eclipse.cdt.core.linux/.project
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>org.eclipse.cdt.core.linux</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
<project>org.apache.xerces</project>
|
||||||
|
<project>org.eclipse.cdt.core</project>
|
||||||
|
<project>org.eclipse.compare</project>
|
||||||
|
<project>org.eclipse.core.boot</project>
|
||||||
|
<project>org.eclipse.core.resources</project>
|
||||||
|
<project>org.eclipse.core.runtime</project>
|
||||||
|
<project>org.eclipse.debug.core</project>
|
||||||
|
<project>org.eclipse.debug.ui</project>
|
||||||
|
<project>org.eclipse.search</project>
|
||||||
|
<project>org.eclipse.ui</project>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
<nature>org.eclipse.pde.PluginNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
2
core/org.eclipse.cdt.core.linux/build.properties
Normal file
2
core/org.eclipse.cdt.core.linux/build.properties
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bin.includes = fragment.xml,\
|
||||||
|
os/
|
20
core/org.eclipse.cdt.core.linux/fragment.xml
Normal file
20
core/org.eclipse.cdt.core.linux/fragment.xml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<fragment
|
||||||
|
id="org.eclipse.cdt.core.linux"
|
||||||
|
name="CDT Core Linux Fragment"
|
||||||
|
version="1.0.0"
|
||||||
|
provider-name="Eclipse.org"
|
||||||
|
plugin-id="org.eclipse.cdt.core"
|
||||||
|
plugin-version="1.0.0">
|
||||||
|
|
||||||
|
<runtime>
|
||||||
|
<library name="linux.jar"/>
|
||||||
|
</runtime>
|
||||||
|
|
||||||
|
<requires>
|
||||||
|
<import plugin="org.eclipse.core.resources"/>
|
||||||
|
<import plugin="org.eclipse.ui"/>
|
||||||
|
</requires>
|
||||||
|
|
||||||
|
|
||||||
|
</fragment>
|
12
core/org.eclipse.cdt.core.linux/library/Makefile
Normal file
12
core/org.eclipse.cdt.core.linux/library/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# makefile for libspawner.so
|
||||||
|
|
||||||
|
LIB_NAME = libspawner.so
|
||||||
|
LIB_NAME_FULL = libspawner.so.1
|
||||||
|
OBJS=spawner.o io.o exec_unix.o
|
||||||
|
CCFLAGS+=-fpic -D_REENTRANT -I$(JDK_INCLUDES)
|
||||||
|
|
||||||
|
spawner : $(OBJS)
|
||||||
|
gcc -g -shared -Wl,-soname,$(LIB_NAME) -o $(LIB_NAME_FULL) $(OBJS) -lc
|
||||||
|
|
||||||
|
clean :
|
||||||
|
rm $(OBJS)
|
45
core/org.eclipse.cdt.core.linux/library/Spawner.h
Normal file
45
core/org.eclipse.cdt.core.linux/library/Spawner.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class com_qnx_tools_utils_spawner_Spawner */
|
||||||
|
|
||||||
|
#ifndef _Included_com_qnx_tools_utils_spawner_Spawner
|
||||||
|
#define _Included_com_qnx_tools_utils_spawner_Spawner
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
* Method: exec0
|
||||||
|
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
|
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
* Method: exec0
|
||||||
|
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
|
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
* Method: raise
|
||||||
|
* Signature: (II)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
|
||||||
|
(JNIEnv *, jobject, jint, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
* Method: waitFor
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
||||||
|
(JNIEnv *, jobject, jint);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
32
core/org.eclipse.cdt.core.linux/library/SpawnerInputStream.h
Normal file
32
core/org.eclipse.cdt.core.linux/library/SpawnerInputStream.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class com_qnx_tools_utils_spawner_SpawnerInputStream */
|
||||||
|
|
||||||
|
#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerInputStream
|
||||||
|
#define _Included_com_qnx_tools_utils_spawner_SpawnerInputStream
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#undef com_qnx_tools_utils_spawner_SpawnerInputStream_SKIP_BUFFER_SIZE
|
||||||
|
#define com_qnx_tools_utils_spawner_SpawnerInputStream_SKIP_BUFFER_SIZE 2048L
|
||||||
|
/* Inaccessible static: skipBuffer */
|
||||||
|
/*
|
||||||
|
* Class: org_elipse_cdt_utils_spawner_SpawnerInputStream
|
||||||
|
* Method: read0
|
||||||
|
* Signature: (I[BI)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0
|
||||||
|
(JNIEnv *, jobject, jint, jbyteArray, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||||
|
* Method: close0
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0
|
||||||
|
(JNIEnv *, jobject, jint);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class com_qnx_tools_utils_spawner_SpawnerOutputStream */
|
||||||
|
|
||||||
|
#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream
|
||||||
|
#define _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||||
|
* Method: write0
|
||||||
|
* Signature: (I[BI)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0
|
||||||
|
(JNIEnv *, jobject, jint, jbyteArray, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||||
|
* Method: close0
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0
|
||||||
|
(JNIEnv *, jobject, jint);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
11
core/org.eclipse.cdt.core.linux/library/exec0.h
Normal file
11
core/org.eclipse.cdt.core.linux/library/exec0.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
extern pid_t exec0(const char *path, char *const argv[],
|
||||||
|
char *const envp[], const char *dirpath,
|
||||||
|
int channels[3] );
|
||||||
|
|
||||||
|
extern int wait0(pid_t pid);
|
145
core/org.eclipse.cdt.core.linux/library/exec_unix.c
Normal file
145
core/org.eclipse.cdt.core.linux/library/exec_unix.c
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
#include "exec0.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* from pfind.c */
|
||||||
|
char *pfind( char *name );
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
exec0(const char *path, char *const argv[], char *const envp[],
|
||||||
|
const char *dirpath, int channels[3])
|
||||||
|
{
|
||||||
|
int pipe0[2], pipe1[2], pipe2[2];
|
||||||
|
pid_t childpid;
|
||||||
|
char *full_path;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle this error case, we need the full path for execve() below.
|
||||||
|
//
|
||||||
|
if (path[0] != '/' && path[0] != '.') {
|
||||||
|
full_path = pfind( path );
|
||||||
|
//full_path = pathfind (getenv ("PATH"), path, "rx");
|
||||||
|
if (full_path == NULL) {
|
||||||
|
fprintf( stderr, "Unable to find full path for \"%s\"\n", path );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
full_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure we can create our pipes before forking.
|
||||||
|
//
|
||||||
|
if( channels != NULL )
|
||||||
|
{
|
||||||
|
if (pipe(pipe0) < 0 || pipe(pipe1) < 0 || pipe(pipe2) < 0) {
|
||||||
|
fprintf(stderr, "%s(%d): returning due to error.\n",
|
||||||
|
__FUNCTION__, __LINE__);
|
||||||
|
free(full_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
childpid = fork();
|
||||||
|
|
||||||
|
if (childpid < 0) {
|
||||||
|
fprintf(stderr, "%s(%d): returning due to error: %s\n",
|
||||||
|
__FUNCTION__, __LINE__, strerror(errno));
|
||||||
|
free(full_path);
|
||||||
|
return -1;
|
||||||
|
} else if (childpid == 0) { /* child */
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
chdir(dirpath);
|
||||||
|
|
||||||
|
if( channels != NULL )
|
||||||
|
{
|
||||||
|
/* Close the write end of pipe0 */
|
||||||
|
if( close(pipe0[1]) == -1 )
|
||||||
|
perror( "close(pipe0[1])" );
|
||||||
|
|
||||||
|
/* Close the read end of pipe1 */
|
||||||
|
if( close(pipe1[0]) == -1 )
|
||||||
|
perror( "close(pipe1[0])" );
|
||||||
|
|
||||||
|
/* Close the read end of pipe2 */
|
||||||
|
if( close(pipe2[0]) == -1 )
|
||||||
|
perror( "close(pipe2[0]))" );
|
||||||
|
|
||||||
|
/* redirections */
|
||||||
|
dup2(pipe0[0], STDIN_FILENO); /* dup stdin */
|
||||||
|
dup2(pipe1[1], STDOUT_FILENO); /* dup stdout */
|
||||||
|
dup2(pipe2[1], STDERR_FILENO); /* dup stderr */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close all the fd's in the child */
|
||||||
|
{
|
||||||
|
int fdlimit = sysconf(_SC_OPEN_MAX);
|
||||||
|
int fd = 3;
|
||||||
|
|
||||||
|
while (fd < fdlimit)
|
||||||
|
close(fd++);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( envp[0] == NULL )
|
||||||
|
{
|
||||||
|
execv( full_path, argv );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
execve( full_path, argv, envp );
|
||||||
|
}
|
||||||
|
|
||||||
|
_exit(127);
|
||||||
|
|
||||||
|
} else if (childpid != 0) { /* parent */
|
||||||
|
|
||||||
|
char b;
|
||||||
|
|
||||||
|
if( channels != NULL )
|
||||||
|
{
|
||||||
|
/* close the read end of pipe1 */
|
||||||
|
if( close(pipe0[0]) == -1 )
|
||||||
|
perror( "close(pipe0[0])" );
|
||||||
|
|
||||||
|
/* close the write end of pipe2 */
|
||||||
|
if( close(pipe1[1]) == -1 )
|
||||||
|
perror( "close(pipe1[1])" );
|
||||||
|
|
||||||
|
/* close the write end of pipe2 */
|
||||||
|
if( close(pipe2[1]) == -1 )
|
||||||
|
perror( "close(pipe2[1])" );
|
||||||
|
|
||||||
|
channels[0] = pipe0[1]; /* Output Stream. */
|
||||||
|
channels[1] = pipe1[0]; /* Input Stream. */
|
||||||
|
channels[2] = pipe2[0]; /* Input Stream. */
|
||||||
|
}
|
||||||
|
|
||||||
|
free(full_path);
|
||||||
|
return childpid;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(full_path);
|
||||||
|
return -1; /*NOT REACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wait0(pid_t pid)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int val = -1;
|
||||||
|
|
||||||
|
if (pid < 0 || waitpid(pid, &status, 0) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
val = WEXITSTATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
103
core/org.eclipse.cdt.core.linux/library/io.c
Normal file
103
core/org.eclipse.cdt.core.linux/library/io.c
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
#include <jni.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <SpawnerInputStream.h>
|
||||||
|
#include <SpawnerOutputStream.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* Header for class _org_eclipse_cdt_utils_spawner_SpawnerInputStream */
|
||||||
|
/* Header for class _org_eclipse_cdt_utils_spawner_SpawnerOutputStream */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||||
|
* Method: read0
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0(JNIEnv * env,
|
||||||
|
jobject jobj,
|
||||||
|
jint jfd,
|
||||||
|
jbyteArray buf,
|
||||||
|
jint buf_len)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int status;
|
||||||
|
jbyte *data;
|
||||||
|
int data_len;
|
||||||
|
|
||||||
|
data = (*env)->GetByteArrayElements(env, buf, 0);
|
||||||
|
data_len = buf_len;
|
||||||
|
fd = jfd;
|
||||||
|
|
||||||
|
status = read( fd, data, data_len );
|
||||||
|
(*env)->ReleaseByteArrayElements(env, buf, data, 0);
|
||||||
|
|
||||||
|
if (status == 0) {
|
||||||
|
/* EOF. */
|
||||||
|
status = -1;
|
||||||
|
} else if (status == -1) {
|
||||||
|
/* Error, toss an exception */
|
||||||
|
jclass exception = (*env)->FindClass(env, "java/io/IOException");
|
||||||
|
if (exception == NULL) {
|
||||||
|
/* Give up. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
(*env)->ThrowNew(env, exception, "read error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||||
|
* Method: close0
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0(JNIEnv * env,
|
||||||
|
jobject jobj,
|
||||||
|
jint fd)
|
||||||
|
{
|
||||||
|
return close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||||
|
* Method: write0
|
||||||
|
* Signature: (II)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0(JNIEnv * env,
|
||||||
|
jobject jobj,
|
||||||
|
jint jfd,
|
||||||
|
jbyteArray buf,
|
||||||
|
jint buf_len)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int fd;
|
||||||
|
jbyte *data;
|
||||||
|
int data_len;
|
||||||
|
|
||||||
|
data = (*env)->GetByteArrayElements(env, buf, 0);
|
||||||
|
data_len = buf_len;
|
||||||
|
fd = jfd;
|
||||||
|
|
||||||
|
status = write(fd, data, data_len);
|
||||||
|
(*env)->ReleaseByteArrayElements(env, buf, data, 0);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||||
|
* Method: close0
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0(JNIEnv * env,
|
||||||
|
jobject jobj,
|
||||||
|
jint fd)
|
||||||
|
{
|
||||||
|
return close(fd);
|
||||||
|
}
|
74
core/org.eclipse.cdt.core.linux/library/pfind.c
Normal file
74
core/org.eclipse.cdt.core.linux/library/pfind.c
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* pfind.c - Search for a binary in $PATH.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char *pfind( const char *name )
|
||||||
|
{
|
||||||
|
char *tok;
|
||||||
|
char *sp;
|
||||||
|
char *path = getenv( "PATH" );
|
||||||
|
char FullPath[PATH_MAX+1];
|
||||||
|
|
||||||
|
if( name == NULL )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "pfind(): Null argument.\n" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( path == NULL || strlen( path ) <= 0 )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "Unable to get $PATH.\n" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The value return by getenv() is readonly */
|
||||||
|
path = strdup( path );
|
||||||
|
|
||||||
|
tok = strtok_r( path, ":", &sp );
|
||||||
|
while( tok != NULL )
|
||||||
|
{
|
||||||
|
//strcpy( FullPath, tok );
|
||||||
|
//strcat( FullPath, "/" );
|
||||||
|
//strcat( FullPath, name );
|
||||||
|
snprintf(FullPath, sizeof(FullPath) - 1, "%s/%s", tok, name);
|
||||||
|
|
||||||
|
if( access( FullPath, X_OK | R_OK ) == 0 )
|
||||||
|
{
|
||||||
|
free( path );
|
||||||
|
return strdup(FullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
tok = strtok_r( NULL, ":", &sp );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( path );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_WITH_MAIN
|
||||||
|
int main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *fullpath;
|
||||||
|
|
||||||
|
for( i=1; i<argc; i++ )
|
||||||
|
{
|
||||||
|
fullpath = pfind( argv[i] );
|
||||||
|
if( fullpath == NULL )
|
||||||
|
printf( "Unable to find %s in $PATH.\n", argv[i] );
|
||||||
|
else
|
||||||
|
printf( "Found %s @ %s.\n", argv[i], fullpath );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
219
core/org.eclipse.cdt.core.linux/library/spawner.c
Normal file
219
core/org.eclipse.cdt.core.linux/library/spawner.c
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include "exec0.h"
|
||||||
|
#include <Spawner.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define DEBUGIT 0
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header for class org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUGIT
|
||||||
|
static void print_array(char **c_array)
|
||||||
|
{
|
||||||
|
if (c_array) {
|
||||||
|
char **p = c_array;
|
||||||
|
for (; *p; p++) {
|
||||||
|
if (*p) {
|
||||||
|
fprintf(stderr, " %s", *p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "null");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static char **alloc_c_array(JNIEnv * env, jobjectArray j_array)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
jint c_array_size = (*env)->GetArrayLength(env, j_array);
|
||||||
|
char **c_array = calloc(c_array_size + 1, sizeof(*c_array));
|
||||||
|
|
||||||
|
if (c_array == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < c_array_size; i++) {
|
||||||
|
jstring j_str =
|
||||||
|
(jstring) (*env)->GetObjectArrayElement(env, j_array, i);
|
||||||
|
const char *c_str = (*env)->GetStringUTFChars(env, j_str, NULL);
|
||||||
|
c_array[i] = (char *) strdup(c_str);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, j_str, c_str);
|
||||||
|
(*env)->DeleteLocalRef(env, j_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void free_c_array(char **c_array)
|
||||||
|
{
|
||||||
|
if (c_array) {
|
||||||
|
char **p = c_array;
|
||||||
|
for (; *p; p++) {
|
||||||
|
if (*p) {
|
||||||
|
free(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(c_array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
|
||||||
|
jobjectArray jcmd,
|
||||||
|
jobjectArray jenv,
|
||||||
|
jstring jdir)
|
||||||
|
{
|
||||||
|
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
|
||||||
|
char **cmd;
|
||||||
|
char **envp;
|
||||||
|
int fd[3];
|
||||||
|
pid_t pid = -1;
|
||||||
|
|
||||||
|
cmd = alloc_c_array(env, jcmd);
|
||||||
|
if (cmd == NULL)
|
||||||
|
goto bail_out;
|
||||||
|
|
||||||
|
envp = alloc_c_array(env, jenv);
|
||||||
|
if (envp == NULL)
|
||||||
|
goto bail_out;
|
||||||
|
|
||||||
|
#if DEBUGIT
|
||||||
|
fprintf(stderr, "command:");
|
||||||
|
print_array(cmd);
|
||||||
|
fprintf(stderr, "Envp:");
|
||||||
|
print_array(envp);
|
||||||
|
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pid = exec0(cmd[0], cmd, envp, dirpath, NULL);
|
||||||
|
if (pid < 0)
|
||||||
|
goto bail_out;
|
||||||
|
|
||||||
|
bail_out:
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jdir, dirpath);
|
||||||
|
if (cmd)
|
||||||
|
free_c_array(cmd);
|
||||||
|
if (envp)
|
||||||
|
free_c_array(envp);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
* Method: exec0
|
||||||
|
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_Spawner_exec0(JNIEnv * env, jobject jobj,
|
||||||
|
jobjectArray jcmd,
|
||||||
|
jobjectArray jenv,
|
||||||
|
jstring jdir,
|
||||||
|
jintArray jchannels)
|
||||||
|
{
|
||||||
|
jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0);
|
||||||
|
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
|
||||||
|
char **cmd;
|
||||||
|
char **envp;
|
||||||
|
int fd[3];
|
||||||
|
pid_t pid = -1;
|
||||||
|
|
||||||
|
if (channels == NULL)
|
||||||
|
goto bail_out;
|
||||||
|
|
||||||
|
cmd = alloc_c_array(env, jcmd);
|
||||||
|
if (cmd == NULL)
|
||||||
|
goto bail_out;
|
||||||
|
|
||||||
|
envp = alloc_c_array(env, jenv);
|
||||||
|
if (envp == NULL)
|
||||||
|
goto bail_out;
|
||||||
|
|
||||||
|
#if DEBUGIT
|
||||||
|
fprintf(stderr, "command:");
|
||||||
|
print_array(cmd);
|
||||||
|
fprintf(stderr, "Envp:");
|
||||||
|
print_array(envp);
|
||||||
|
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pid = exec0(cmd[0], cmd, envp, dirpath, fd);
|
||||||
|
if (pid < 0)
|
||||||
|
goto bail_out;
|
||||||
|
|
||||||
|
channels[0] = fd[0];
|
||||||
|
channels[1] = fd[1];
|
||||||
|
channels[2] = fd[2];
|
||||||
|
|
||||||
|
bail_out:
|
||||||
|
(*env)->ReleaseIntArrayElements(env, jchannels, channels, 0);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jdir, dirpath);
|
||||||
|
if (cmd)
|
||||||
|
free_c_array(cmd);
|
||||||
|
if (envp)
|
||||||
|
free_c_array(envp);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
* Method: raise
|
||||||
|
* Signature: (II)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_Spawner_raise(JNIEnv * env, jobject jobj,
|
||||||
|
jint pid, jint sig)
|
||||||
|
{
|
||||||
|
int status = -1;
|
||||||
|
|
||||||
|
switch (sig) {
|
||||||
|
case 0: /* NOOP */
|
||||||
|
status = kill(pid, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* INTERRUPT */
|
||||||
|
status = kill(pid, SIGINT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9: /* KILL */
|
||||||
|
status = kill(pid, SIGKILL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 15: /* TERM */
|
||||||
|
status = kill(pid, SIGTERM);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = kill(pid, sig); /* WHAT ?? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||||
|
* Method: waitFor
|
||||||
|
* Signature: (I)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor(JNIEnv * env,
|
||||||
|
jobject jobj, jint pid)
|
||||||
|
{
|
||||||
|
return wait0(pid);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue