diff --git a/core/org.eclipse.cdt.core.macosx/library/exec_pty.c b/core/org.eclipse.cdt.core.macosx/library/exec_pty.c index ebf4b5e8471..dd68615f0e5 100644 --- a/core/org.eclipse.cdt.core.macosx/library/exec_pty.c +++ b/core/org.eclipse.cdt.core.macosx/library/exec_pty.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002, 2011 QNX Software Systems and others. + * Copyright (c) 2004, 2010 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,7 +7,10 @@ * * Contributors: * QNX Software Systems - initial API and implementation - *******************************************************************************/ + * Wind River Systems, Inc. + * Mikhail Zabaluev (Nokia) - bug 82744 + * Mikhail Sennikovsky - bug 145737 + *******************************************************************************/ #include "exec0.h" #include "openpty.h" #include @@ -20,7 +23,7 @@ #include /* from pfind.c */ -extern char *pfind(const char *name, char *const envp[]); +extern char *pfind(const char *name, char * const envp[]); pid_t exec_pty(const char *path, char *const argv[], char *const envp[], @@ -43,7 +46,7 @@ exec_pty(const char *path, char *const argv[], char *const envp[], /* * Make sure we can create our pipes before forking. */ - if (console && channels != NULL) { + if (channels != NULL && console) { if (pipe(pipe2) < 0) { fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno)); free(full_path); @@ -90,6 +93,7 @@ exec_pty(const char *path, char *const argv[], char *const envp[], return -1; } } + /* redirections */ dup2(fds, STDIN_FILENO); /* dup stdin */ dup2(fds, STDOUT_FILENO); /* dup stdout */ @@ -119,21 +123,19 @@ exec_pty(const char *path, char *const argv[], char *const envp[], _exit(127); } else if (childpid != 0) { /* parent */ - if (console) { set_noecho(fdm); } if (channels != NULL) { - /* close the write end of pipe1 */ - if (console && close(pipe2[1]) == -1) - perror("close(pipe2[1])"); - channels[0] = fdm; /* Input Stream. */ channels[1] = fdm; /* Output Stream. */ - if (console) { /* stderr Stream. */ - channels[2] = pipe2[0]; + if (console) { + /* close the write end of pipe1 */ + if (close(pipe2[1]) == -1) + perror("close(pipe2[1])"); + channels[2] = pipe2[0]; /* stderr Stream. */ } else { - channels[2] = fdm; + channels[2] = fdm; /* Error Stream. */ } } diff --git a/core/org.eclipse.cdt.core.macosx/library/exec_unix.c b/core/org.eclipse.cdt.core.macosx/library/exec_unix.c index 4b06d7b827f..0d68dd13c0a 100644 --- a/core/org.eclipse.cdt.core.macosx/library/exec_unix.c +++ b/core/org.eclipse.cdt.core.macosx/library/exec_unix.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002 - 2011 QNX Software Systems and others. + * Copyright (c) 2002, 2010 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,8 @@ * * Contributors: * QNX Software Systems - initial API and implementation + * Wind River Systems, Inc. + * Mikhail Sennikovsky - bug 145737 *******************************************************************************/ #include "exec0.h" #include @@ -18,7 +20,7 @@ #include /* from pfind.c */ -extern char *pfind(const char *name, char *const envp[]); +extern char *pfind(const char *name, char * const envp[]); pid_t exec0(const char *path, char *const argv[], char *const envp[], @@ -90,6 +92,8 @@ exec0(const char *path, char *const argv[], char *const envp[], close(fd++); } + setpgid(getpid(), getpid()); + if (envp[0] == NULL) { execv(full_path, argv); } else { @@ -134,9 +138,18 @@ int wait0(pid_t pid) int status; int val = -1; - if (pid < 0 || waitpid(pid, &status, 0) < 0) + if (pid < 0) return -1; - + + for (;;) { + if (waitpid(pid, &status, 0) < 0) { + if (errno == EINTR) { + // interrupted system call - retry + continue; + } + } + break; + } if (WIFEXITED(status)) { val = WEXITSTATUS(status); } diff --git a/core/org.eclipse.cdt.core.macosx/library/spawner.c b/core/org.eclipse.cdt.core.macosx/library/spawner.c index 1b87e562367..217349b439d 100644 --- a/core/org.eclipse.cdt.core.macosx/library/spawner.c +++ b/core/org.eclipse.cdt.core.macosx/library/spawner.c @@ -7,6 +7,8 @@ * * Contributors: * QNX Software Systems - initial API and implementation + * Wind River Systems, Inc. + * Mikhail Zabaluev (Nokia) - bug 82744 *******************************************************************************/ #include #include @@ -90,52 +92,53 @@ 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, jboolean console) { - 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 = NULL; - char **envp = NULL; - 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; - + 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 = NULL; + char **envp = NULL; + 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); + 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, console); - 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; + + pid = exec_pty(cmd[0], cmd, envp, dirpath, fd, pts_name, masterFD, console); + 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, @@ -246,23 +249,38 @@ Java_org_eclipse_cdt_utils_spawner_Spawner_raise(JNIEnv * env, jobject jobj, switch (sig) { case 0: /* NOOP */ - status = kill(pid, 0); + status = killpg(pid, 0); + if(status == -1) { + status = kill(pid, 0); + } break; case 2: /* INTERRUPT */ - status = kill(pid, SIGINT); + status = killpg(pid, SIGINT); + if(status == -1) { + status = kill(pid, SIGINT); + } break; case 9: /* KILL */ - status = kill(pid, SIGKILL); + status = killpg(pid, SIGKILL); + if(status == -1) { + status = kill(pid, SIGKILL); + } break; case 15: /* TERM */ - status = kill(pid, SIGTERM); + status = killpg(pid, SIGTERM); + if(status == -1) { + status = kill(pid, SIGTERM); + } break; default: - status = kill(pid, sig); /* WHAT ?? */ + status = killpg(pid, sig); /* WHAT ?? */ + if(status == -1) { + status = kill(pid, sig); /* WHAT ?? */ + } break; }