Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Oberhuber2017-09-03 22:14:04 +0000
committerJonah Graham2017-09-04 10:35:15 +0000
commit1019030e744284cc6d6d31d148eb828a025755be (patch)
treefdbbf413234823aea9db9231c413409b8ac25e14
parent84689e06fdcf685e104cbe915a7cf2b26c5bb986 (diff)
downloadorg.eclipse.cdt-1019030e744284cc6d6d31d148eb828a025755be.tar.gz
org.eclipse.cdt-1019030e744284cc6d6d31d148eb828a025755be.tar.xz
org.eclipse.cdt-1019030e744284cc6d6d31d148eb828a025755be.zip
Bug 521788 - spawner doesnt kill child process on MacOS X
Fixed by copying code from org.eclipse.cdt.core.linux that contains the fix from bug 119387 : set the process group by calling setpgid() when forking a process, and use killpg() for killing the entire process group on termination. This also aligns MacOS code fully with Linux code. Tested on MacOSX 10.8 and 10.13 beta. Binaries will be submitted with the related fix for bug 519886. Change-Id: I87df87caa88cff60b4d9eee2252252234d1a4f84 Signed-off-by: Martin Oberhuber <mober.at+eclipse@gmail.com>
-rw-r--r--core/org.eclipse.cdt.core.macosx/library/exec_pty.c26
-rw-r--r--core/org.eclipse.cdt.core.macosx/library/exec_unix.c21
-rw-r--r--core/org.eclipse.cdt.core.macosx/library/spawner.c114
3 files changed, 97 insertions, 64 deletions
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 <unistd.h>
@@ -20,7 +23,7 @@
#include <termios.h>
/* 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 <unistd.h>
@@ -18,7 +20,7 @@
#include <stdlib.h>
/* 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 <unistd.h>
#include <stdlib.h>
@@ -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;
}

Back to the top