mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 09:46:02 +02:00
2004-11-16 Alain Magloire
Fix for 27663, allow to exec with pty emulation. * library/Makefile * library/openpty.c(set_noecho): new function * library/opentpty.h: update header. * library/pty.c: refactor forkpyt to openMaster() * library/PTY.h: regenerate * library/spawner.c: add exec2() support * library/Spawner.h: regenerate * os/linux/x86/libpty.so * os/linux/x86/libspawner.so
This commit is contained in:
parent
4dec40862e
commit
580b6dfb45
20 changed files with 611 additions and 102 deletions
|
@ -1,3 +1,17 @@
|
|||
2004-11-16 Alain Magloire
|
||||
|
||||
Fix for 27663, allow to exec with pty emulation.
|
||||
* library/Makefile
|
||||
* library/openpty.c(set_noecho): new function
|
||||
* library/opentpty.h: update header.
|
||||
* library/pty.c: refactor forkpyt to openMaster()
|
||||
* library/PTY.h: regenerate
|
||||
* library/spawner.c: add exec2() support
|
||||
* library/Spawner.h: regenerate
|
||||
|
||||
* os/linux/x86/libpty.so
|
||||
* os/linux/x86/libspawner.so
|
||||
|
||||
2004-07-12 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* library/Makefile (CFLAGS): Define _GNU_SOURCE.
|
||||
|
|
|
@ -19,7 +19,7 @@ INSTALL_DIR = ../os/$(OS)/$(ARCH)
|
|||
|
||||
LIB_NAME_SPAWNER = libspawner.so
|
||||
LIB_NAME_FULL_SPAWNER = $(INSTALL_DIR)/libspawner.so
|
||||
OBJS_SPAWNER=spawner.o io.o exec_unix.o pfind.o
|
||||
OBJS_SPAWNER=spawner.o io.o exec_unix.o exec_pty.o pfind.o openpty.o
|
||||
|
||||
LIB_NAME_PTY = libpty.so
|
||||
LIB_NAME_FULL_PTY = $(INSTALL_DIR)/libpty.so
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Inaccessible static: hasPTY */
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTY
|
||||
* Method: forkpty
|
||||
* Signature: ()I
|
||||
* Method: openMaster
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_forkpty
|
||||
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,45 +1,53 @@
|
|||
/* 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
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class org_eclipse_cdt_utils_spawner_Spawner */
|
||||
|
||||
#ifndef _Included_org_eclipse_cdt_utils_spawner_Spawner
|
||||
#define _Included_org_eclipse_cdt_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: exec1
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)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: exec2
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILjava/lang/String;I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
||||
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray, jstring, jint);
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
152
core/org.eclipse.cdt.core.linux/library/exec_pty.c
Normal file
152
core/org.eclipse.cdt.core.linux/library/exec_pty.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include "exec0.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* from pfind.c */
|
||||
extern char *pfind(const char *name);
|
||||
|
||||
pid_t
|
||||
exec_pty(const char *path, char *const argv[], char *const envp[],
|
||||
const char *dirpath, int channels[3], const char *pts_name, int fdm)
|
||||
{
|
||||
int pipe2[2];
|
||||
pid_t childpid;
|
||||
char *full_path;
|
||||
|
||||
/*
|
||||
* We use pfind() to check that the program exists and is an executable.
|
||||
* If not pass the error up. Also execve() wants a full path.
|
||||
*/
|
||||
full_path = pfind(path);
|
||||
if (full_path == NULL) {
|
||||
fprintf(stderr, "Unable to find full path for \"%s\"\n", (path) ? path : "");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we can create our pipes before forking.
|
||||
*/
|
||||
if (channels != NULL) {
|
||||
if (pipe(pipe2) < 0) {
|
||||
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
|
||||
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 */
|
||||
|
||||
chdir(dirpath);
|
||||
|
||||
if (channels != NULL) {
|
||||
int fds;
|
||||
|
||||
fds = ptys_open(fdm, pts_name);
|
||||
if (fds < 0) {
|
||||
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close the read end of pipe2 */
|
||||
if (close(pipe2[0]) == -1)
|
||||
perror("close(pipe2[0]))");
|
||||
|
||||
/* close the master, no need in the child */
|
||||
close(fdm);
|
||||
|
||||
set_noecho(fds);
|
||||
/* redirections */
|
||||
dup2(fds, STDIN_FILENO); /* dup stdin */
|
||||
dup2(fds, STDOUT_FILENO); /* dup stdout */
|
||||
dup2(pipe2[1], STDERR_FILENO); /* dup stderr */
|
||||
close(fds); /* done with fds. */
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
set_noecho(fdm);
|
||||
if (channels != NULL) {
|
||||
/* close the write end of pipe1 */
|
||||
if (close(pipe2[1]) == -1)
|
||||
perror("close(pipe2[1])");
|
||||
|
||||
channels[0] = fdm; /* Input Stream. */
|
||||
channels[1] = fdm; /* Output Stream. */
|
||||
channels[2] = pipe2[0]; /* stderr Stream. */
|
||||
//channels[2] = fdm; /* Input Stream. */
|
||||
}
|
||||
|
||||
free(full_path);
|
||||
return childpid;
|
||||
}
|
||||
|
||||
free(full_path);
|
||||
return -1; /*NOT REACHED */
|
||||
}
|
||||
#ifdef __STAND_ALONE__
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
const char *path = "./bufferring_test";
|
||||
int channels[3] = { -1, -1, -1};
|
||||
int status;
|
||||
FILE *app_stdin;
|
||||
FILE *app_stdout;
|
||||
FILE *app_stderr;
|
||||
char pts_name[32];
|
||||
int fdm;
|
||||
char buffer[32];
|
||||
|
||||
fdm = ptym_open(pts_name);
|
||||
status = exec_pty(path, argv, envp, ".", channels, pts_name, fdm);
|
||||
if (status >= 0) {
|
||||
app_stdin = fdopen(channels[0], "w");
|
||||
app_stdout = fdopen(channels[1], "r");
|
||||
app_stderr = fdopen(channels[2], "r");
|
||||
if (app_stdout == NULL || app_stderr == NULL || app_stdin == NULL) {
|
||||
fprintf(stderr, "PROBLEMS\n");
|
||||
} else {
|
||||
fputs("foo\n", app_stdin);
|
||||
fputs("bar\n", app_stdin);
|
||||
while(fgets(buffer, sizeof buffer, app_stdout) != NULL) {
|
||||
fprintf(stdout, "STDOUT: %s\n", buffer);
|
||||
}
|
||||
while(fgets(buffer, sizeof buffer, app_stderr) != NULL) {
|
||||
fprintf(stdout, "STDERR: %s\n", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
fputs("bye\n", stdout);
|
||||
close(channels[0]);
|
||||
close(channels[1]);
|
||||
close(channels[2]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
int ptym_open (char *pts_name);
|
||||
int ptys_open (int fdm, char * pts_name);
|
||||
void set_noecho(int fd);
|
||||
|
||||
int
|
||||
openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp)
|
||||
|
@ -38,6 +39,7 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct win
|
|||
close(*amaster);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (name)
|
||||
strcpy(name, line);
|
||||
#ifndef TCSAFLUSH
|
||||
|
@ -52,6 +54,24 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct win
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
set_noecho(int fd)
|
||||
{
|
||||
struct termios stermios;
|
||||
if (tcgetattr(fd, &stermios) < 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
/* turn off echo */
|
||||
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
/* Turn off the NL to CR/NL mapping ou output. */
|
||||
/*stermios.c_oflag &= ~(ONLCR);*/
|
||||
|
||||
stermios.c_iflag |= (IGNCR);
|
||||
|
||||
tcsetattr(fd, TCSANOW, &stermios);
|
||||
}
|
||||
|
||||
int
|
||||
ptym_open(char * pts_name)
|
||||
{
|
||||
|
@ -89,6 +109,7 @@ ptys_open(int fdm, char * pts_name)
|
|||
close(fdm);
|
||||
return -5;
|
||||
}
|
||||
/*
|
||||
if (ioctl(fds, I_PUSH, "ptem") < 0) {
|
||||
printf("pterm:%s\n", strerror(errno));
|
||||
close(fdm);
|
||||
|
@ -101,5 +122,6 @@ ptys_open(int fdm, char * pts_name)
|
|||
close(fds);
|
||||
return -7;
|
||||
}
|
||||
*/
|
||||
return fds;
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
#define _OPENPTY_H
|
||||
int ptym_open (char *pts_name);
|
||||
int ptys_open (int fdm, char * pts_name);
|
||||
void set_noecho(int fd);
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
|
||||
Java_org_eclipse_cdt_utils_pty_PTY_openMaster (JNIEnv *env, jobject jobj) {
|
||||
jfieldID fid; /* Store the field ID */
|
||||
jstring jstr = NULL;
|
||||
int master = -1;
|
||||
|
@ -18,6 +18,9 @@ Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
|
|||
|
||||
master = ptym_open(line);
|
||||
if (master >= 0) {
|
||||
// turn off echo
|
||||
set_noecho(master);
|
||||
|
||||
/* Get a reference to the obj's class */
|
||||
cls = (*env)->GetObjectClass(env, jobj);
|
||||
|
||||
|
|
|
@ -71,6 +71,63 @@ static void free_c_array(char **c_array)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: exec2
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILorg/eclipse/cdt/utils/pty/PTY;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
||||
(JNIEnv *env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir, jintArray jchannels,
|
||||
jstring jslaveName, jint masterFD)
|
||||
{
|
||||
jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0);
|
||||
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
|
||||
const char *pts_name = (*env)->GetStringUTFChars(env, jslaveName, 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);
|
||||
fprintf(stderr, "pts_name: %s\n", pts_name);
|
||||
#endif
|
||||
|
||||
pid = exec_pty(cmd[0], cmd, envp, dirpath, fd, pts_name, masterFD);
|
||||
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);
|
||||
(*env)->ReleaseStringUTFChars(env, jslaveName, pts_name);
|
||||
if (cmd)
|
||||
free_c_array(cmd);
|
||||
if (envp)
|
||||
free_c_array(envp);
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
|
||||
jobjectArray jcmd,
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,14 @@
|
|||
2004-11-16 Alain Magloire
|
||||
|
||||
Fix for 27663, allow to exec with pty emulation.
|
||||
* library/Makefile
|
||||
* library/openpty.c(set_noecho): new function
|
||||
* library/opentpty.h: update header.
|
||||
* library/pty.c: refactor forkpyt to openMaster()
|
||||
* library/PTY.h: regenerate
|
||||
* library/spawner.c: add exec2() support
|
||||
* library/Spawner.h: regenerate
|
||||
|
||||
2004-03-25 David Inglis
|
||||
|
||||
Added platform attribute to processlist extension
|
||||
|
|
|
@ -10,7 +10,7 @@ CFLAGS +=-fpic -D_REENTRANT
|
|||
|
||||
LIB_NAME_SPAWNER = libspawner.so
|
||||
LIB_NAME_FULL_SPAWNER = ../os/solaris/sparc/libspawner.so
|
||||
OBJS_SPAWNER=spawner.o io.o exec_unix.o pfind.o
|
||||
OBJS_SPAWNER=spawner.o io.o exec_unix.o exec_pty.o openpty.o pfind.o
|
||||
|
||||
LIB_NAME_PTY = libpty.so
|
||||
LIB_NAME_FULL_PTY = ../os/solaris/sparc/libpty.so
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Inaccessible static: hasPTY */
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_pty_PTY
|
||||
* Method: forkpty
|
||||
* Signature: ()I
|
||||
* Method: openMaster
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_forkpty
|
||||
JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,45 +1,53 @@
|
|||
/* 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
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class org_eclipse_cdt_utils_spawner_Spawner */
|
||||
|
||||
#ifndef _Included_org_eclipse_cdt_utils_spawner_Spawner
|
||||
#define _Included_org_eclipse_cdt_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: exec1
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)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: exec2
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILjava/lang/String;I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
||||
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray, jstring, jint);
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
152
core/org.eclipse.cdt.core.solaris/library/exec_pty.c
Normal file
152
core/org.eclipse.cdt.core.solaris/library/exec_pty.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include "exec0.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* from pfind.c */
|
||||
extern char *pfind(const char *name);
|
||||
|
||||
pid_t
|
||||
exec_pty(const char *path, char *const argv[], char *const envp[],
|
||||
const char *dirpath, int channels[3], const char *pts_name, int fdm)
|
||||
{
|
||||
int pipe2[2];
|
||||
pid_t childpid;
|
||||
char *full_path;
|
||||
|
||||
/*
|
||||
* We use pfind() to check that the program exists and is an executable.
|
||||
* If not pass the error up. Also execve() wants a full path.
|
||||
*/
|
||||
full_path = pfind(path);
|
||||
if (full_path == NULL) {
|
||||
fprintf(stderr, "Unable to find full path for \"%s\"\n", (path) ? path : "");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we can create our pipes before forking.
|
||||
*/
|
||||
if (channels != NULL) {
|
||||
if (pipe(pipe2) < 0) {
|
||||
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
|
||||
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 */
|
||||
|
||||
chdir(dirpath);
|
||||
|
||||
if (channels != NULL) {
|
||||
int fds;
|
||||
|
||||
fds = ptys_open(fdm, pts_name);
|
||||
if (fds < 0) {
|
||||
fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close the read end of pipe2 */
|
||||
if (close(pipe2[0]) == -1)
|
||||
perror("close(pipe2[0]))");
|
||||
|
||||
/* close the master, no need in the child */
|
||||
close(fdm);
|
||||
|
||||
set_noecho(fds);
|
||||
/* redirections */
|
||||
dup2(fds, STDIN_FILENO); /* dup stdin */
|
||||
dup2(fds, STDOUT_FILENO); /* dup stdout */
|
||||
dup2(pipe2[1], STDERR_FILENO); /* dup stderr */
|
||||
close(fds); /* done with fds. */
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
set_noecho(fdm);
|
||||
if (channels != NULL) {
|
||||
/* close the write end of pipe1 */
|
||||
if (close(pipe2[1]) == -1)
|
||||
perror("close(pipe2[1])");
|
||||
|
||||
channels[0] = fdm; /* Input Stream. */
|
||||
channels[1] = fdm; /* Output Stream. */
|
||||
channels[2] = pipe2[0]; /* stderr Stream. */
|
||||
//channels[2] = fdm; /* Input Stream. */
|
||||
}
|
||||
|
||||
free(full_path);
|
||||
return childpid;
|
||||
}
|
||||
|
||||
free(full_path);
|
||||
return -1; /*NOT REACHED */
|
||||
}
|
||||
#ifdef __STAND_ALONE__
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
const char *path = "./bufferring_test";
|
||||
int channels[3] = { -1, -1, -1};
|
||||
int status;
|
||||
FILE *app_stdin;
|
||||
FILE *app_stdout;
|
||||
FILE *app_stderr;
|
||||
char pts_name[32];
|
||||
int fdm;
|
||||
char buffer[32];
|
||||
|
||||
fdm = ptym_open(pts_name);
|
||||
status = exec_pty(path, argv, envp, ".", channels, pts_name, fdm);
|
||||
if (status >= 0) {
|
||||
app_stdin = fdopen(channels[0], "w");
|
||||
app_stdout = fdopen(channels[1], "r");
|
||||
app_stderr = fdopen(channels[2], "r");
|
||||
if (app_stdout == NULL || app_stderr == NULL || app_stdin == NULL) {
|
||||
fprintf(stderr, "PROBLEMS\n");
|
||||
} else {
|
||||
fputs("foo\n", app_stdin);
|
||||
fputs("bar\n", app_stdin);
|
||||
while(fgets(buffer, sizeof buffer, app_stdout) != NULL) {
|
||||
fprintf(stdout, "STDOUT: %s\n", buffer);
|
||||
}
|
||||
while(fgets(buffer, sizeof buffer, app_stderr) != NULL) {
|
||||
fprintf(stdout, "STDERR: %s\n", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
fputs("bye\n", stdout);
|
||||
close(channels[0]);
|
||||
close(channels[1]);
|
||||
close(channels[2]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -105,3 +105,22 @@ ptys_open(int fdm, char * pts_name)
|
|||
}
|
||||
return fds;
|
||||
}
|
||||
|
||||
void
|
||||
set_noecho(int fd)
|
||||
{
|
||||
struct termios stermios;
|
||||
if (tcgetattr(fd, &stermios) < 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
/* turn off echo */
|
||||
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
/* Turn off the NL to CR/NL mapping ou output. */
|
||||
/*stermios.c_oflag &= ~(ONLCR);*/
|
||||
|
||||
stermios.c_iflag |= (IGNCR);
|
||||
|
||||
tcsetattr(fd, TCSANOW, &stermios);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
#define _OPENPTY_H
|
||||
int ptym_open (char *pts_name);
|
||||
int ptys_open (int fdm, char * pts_name);
|
||||
void set_noecho(int fd);
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
|
||||
Java_org_eclipse_cdt_utils_pty_PTY_openMaster (JNIEnv *env, jobject jobj) {
|
||||
jfieldID fid; /* Store the field ID */
|
||||
jstring jstr = NULL;
|
||||
int master = -1;
|
||||
|
@ -18,6 +18,9 @@ Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) {
|
|||
|
||||
master = ptym_open(line);
|
||||
if (master >= 0) {
|
||||
// turn off echo
|
||||
set_noecho(master);
|
||||
|
||||
/* Get a reference to the obj's class */
|
||||
cls = (*env)->GetObjectClass(env, jobj);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
|
||||
/*
|
||||
* Header for class com_qnx_utils_spawner_Spawner
|
||||
* Header for class org_eclipse_cdt_utils_spawner_Spawner
|
||||
*/
|
||||
|
||||
|
||||
|
@ -71,6 +71,63 @@ static void free_c_array(char **c_array)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: exec2
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILorg/eclipse/cdt/utils/pty/PTY;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
||||
(JNIEnv *env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir, jintArray jchannels,
|
||||
jstring jslaveName, jint masterFD)
|
||||
{
|
||||
jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0);
|
||||
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
|
||||
const char *pts_name = (*env)->GetStringUTFChars(env, jslaveName, 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);
|
||||
fprintf(stderr, "pts_name: %s\n", pts_name);
|
||||
#endif
|
||||
|
||||
pid = exec_pty(cmd[0], cmd, envp, dirpath, fd, pts_name, masterFD);
|
||||
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);
|
||||
(*env)->ReleaseStringUTFChars(env, jslaveName, pts_name);
|
||||
if (cmd)
|
||||
free_c_array(cmd);
|
||||
if (envp)
|
||||
free_c_array(envp);
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
|
||||
jobjectArray jcmd,
|
||||
|
@ -80,7 +137,6 @@ Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
|
|||
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue