1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 15:05:36 +02:00

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>
This commit is contained in:
Martin Oberhuber 2017-09-04 00:14:04 +02:00 committed by Jonah Graham
parent 84689e06fd
commit 1019030e74
3 changed files with 97 additions and 64 deletions

View file

@ -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. */
}
}

View file

@ -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);
}

View file

@ -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;
}