diff --git a/core/org.eclipse.cdt.core.linux/ChangeLog b/core/org.eclipse.cdt.core.linux/ChangeLog index f4fe5ee30be..e25cbe1f81b 100644 --- a/core/org.eclipse.cdt.core.linux/ChangeLog +++ b/core/org.eclipse.cdt.core.linux/ChangeLog @@ -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 * library/Makefile (CFLAGS): Define _GNU_SOURCE. diff --git a/core/org.eclipse.cdt.core.linux/library/Makefile b/core/org.eclipse.cdt.core.linux/library/Makefile index a27ddf67987..02d519057b3 100644 --- a/core/org.eclipse.cdt.core.linux/library/Makefile +++ b/core/org.eclipse.cdt.core.linux/library/Makefile @@ -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 diff --git a/core/org.eclipse.cdt.core.linux/library/PTY.h b/core/org.eclipse.cdt.core.linux/library/PTY.h index fabf58152d0..46a8dd9b622 100644 --- a/core/org.eclipse.cdt.core.linux/library/PTY.h +++ b/core/org.eclipse.cdt.core.linux/library/PTY.h @@ -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 diff --git a/core/org.eclipse.cdt.core.linux/library/Spawner.h b/core/org.eclipse.cdt.core.linux/library/Spawner.h index 01ffb3cc1b2..272366bad75 100644 --- a/core/org.eclipse.cdt.core.linux/library/Spawner.h +++ b/core/org.eclipse.cdt.core.linux/library/Spawner.h @@ -1,45 +1,53 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* 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 +/* 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 diff --git a/core/org.eclipse.cdt.core.linux/library/exec_pty.c b/core/org.eclipse.cdt.core.linux/library/exec_pty.c new file mode 100644 index 00000000000..d012cfb051c --- /dev/null +++ b/core/org.eclipse.cdt.core.linux/library/exec_pty.c @@ -0,0 +1,152 @@ +#include "exec0.h" +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 diff --git a/core/org.eclipse.cdt.core.linux/library/openpty.c b/core/org.eclipse.cdt.core.linux/library/openpty.c index 28f5363cf1d..21c1ccfef09 100644 --- a/core/org.eclipse.cdt.core.linux/library/openpty.c +++ b/core/org.eclipse.cdt.core.linux/library/openpty.c @@ -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; } diff --git a/core/org.eclipse.cdt.core.linux/library/openpty.h b/core/org.eclipse.cdt.core.linux/library/openpty.h index fd7b7be1b2f..36cd52fd294 100644 --- a/core/org.eclipse.cdt.core.linux/library/openpty.h +++ b/core/org.eclipse.cdt.core.linux/library/openpty.h @@ -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 diff --git a/core/org.eclipse.cdt.core.linux/library/pty.c b/core/org.eclipse.cdt.core.linux/library/pty.c index 4b9e682c3ee..245578632f3 100644 --- a/core/org.eclipse.cdt.core.linux/library/pty.c +++ b/core/org.eclipse.cdt.core.linux/library/pty.c @@ -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); diff --git a/core/org.eclipse.cdt.core.linux/library/spawner.c b/core/org.eclipse.cdt.core.linux/library/spawner.c index 58bf85a74ed..fcb111a81f0 100644 --- a/core/org.eclipse.cdt.core.linux/library/spawner.c +++ b/core/org.eclipse.cdt.core.linux/library/spawner.c @@ -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, diff --git a/core/org.eclipse.cdt.core.linux/os/linux/x86/libpty.so b/core/org.eclipse.cdt.core.linux/os/linux/x86/libpty.so index 388ec4d4769..1dd15a52e4e 100644 Binary files a/core/org.eclipse.cdt.core.linux/os/linux/x86/libpty.so and b/core/org.eclipse.cdt.core.linux/os/linux/x86/libpty.so differ diff --git a/core/org.eclipse.cdt.core.linux/os/linux/x86/libspawner.so b/core/org.eclipse.cdt.core.linux/os/linux/x86/libspawner.so index 3755c35a560..63276413797 100644 Binary files a/core/org.eclipse.cdt.core.linux/os/linux/x86/libspawner.so and b/core/org.eclipse.cdt.core.linux/os/linux/x86/libspawner.so differ diff --git a/core/org.eclipse.cdt.core.solaris/ChangeLog b/core/org.eclipse.cdt.core.solaris/ChangeLog index cd9ee7a22d4..c877818d19f 100644 --- a/core/org.eclipse.cdt.core.solaris/ChangeLog +++ b/core/org.eclipse.cdt.core.solaris/ChangeLog @@ -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 diff --git a/core/org.eclipse.cdt.core.solaris/library/Makefile b/core/org.eclipse.cdt.core.solaris/library/Makefile index 034a966cfb7..75d3a3cd5be 100644 --- a/core/org.eclipse.cdt.core.solaris/library/Makefile +++ b/core/org.eclipse.cdt.core.solaris/library/Makefile @@ -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 diff --git a/core/org.eclipse.cdt.core.solaris/library/PTY.h b/core/org.eclipse.cdt.core.solaris/library/PTY.h index fabf58152d0..46a8dd9b622 100644 --- a/core/org.eclipse.cdt.core.solaris/library/PTY.h +++ b/core/org.eclipse.cdt.core.solaris/library/PTY.h @@ -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 diff --git a/core/org.eclipse.cdt.core.solaris/library/Spawner.h b/core/org.eclipse.cdt.core.solaris/library/Spawner.h index 01ffb3cc1b2..272366bad75 100644 --- a/core/org.eclipse.cdt.core.solaris/library/Spawner.h +++ b/core/org.eclipse.cdt.core.solaris/library/Spawner.h @@ -1,45 +1,53 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* 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 +/* 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 diff --git a/core/org.eclipse.cdt.core.solaris/library/exec_pty.c b/core/org.eclipse.cdt.core.solaris/library/exec_pty.c new file mode 100644 index 00000000000..d012cfb051c --- /dev/null +++ b/core/org.eclipse.cdt.core.solaris/library/exec_pty.c @@ -0,0 +1,152 @@ +#include "exec0.h" +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 diff --git a/core/org.eclipse.cdt.core.solaris/library/openpty.c b/core/org.eclipse.cdt.core.solaris/library/openpty.c index e3908ff42d5..8fe4fe260af 100644 --- a/core/org.eclipse.cdt.core.solaris/library/openpty.c +++ b/core/org.eclipse.cdt.core.solaris/library/openpty.c @@ -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); +} + diff --git a/core/org.eclipse.cdt.core.solaris/library/openpty.h b/core/org.eclipse.cdt.core.solaris/library/openpty.h index fd7b7be1b2f..36cd52fd294 100644 --- a/core/org.eclipse.cdt.core.solaris/library/openpty.h +++ b/core/org.eclipse.cdt.core.solaris/library/openpty.h @@ -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 diff --git a/core/org.eclipse.cdt.core.solaris/library/pty.c b/core/org.eclipse.cdt.core.solaris/library/pty.c index 4b9e682c3ee..245578632f3 100644 --- a/core/org.eclipse.cdt.core.solaris/library/pty.c +++ b/core/org.eclipse.cdt.core.solaris/library/pty.c @@ -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); diff --git a/core/org.eclipse.cdt.core.solaris/library/spawner.c b/core/org.eclipse.cdt.core.solaris/library/spawner.c index 2671bcd1f0c..fcb111a81f0 100644 --- a/core/org.eclipse.cdt.core.solaris/library/spawner.c +++ b/core/org.eclipse.cdt.core.solaris/library/spawner.c @@ -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);