mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 14:55:41 +02:00
2004-11-16 Alain Magloire
FIX for 27663 * utils/org/eclipse/cdt/utils/pty/PTY.java * utils/org/eclipse/cdt/utils/spawner/ProcessFactory.java * utils/org/eclipse/cdt/utils/spawner/Spawner.java * utils/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java
This commit is contained in:
parent
79dfbf7c90
commit
4dec40862e
5 changed files with 141 additions and 39 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2004-11-16 Alain Magloire
|
||||||
|
FIX for 27663
|
||||||
|
* utils/org/eclipse/cdt/utils/pty/PTY.java
|
||||||
|
* utils/org/eclipse/cdt/utils/spawner/ProcessFactory.java
|
||||||
|
* utils/org/eclipse/cdt/utils/spawner/Spawner.java
|
||||||
|
* utils/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java
|
||||||
|
|
||||||
2004-11-14 Alain Magloire
|
2004-11-14 Alain Magloire
|
||||||
Fix for PR 77546.
|
Fix for PR 77546.
|
||||||
Make the error parser manager faster by
|
Make the error parser manager faster by
|
||||||
|
|
|
@ -11,24 +11,21 @@
|
||||||
package org.eclipse.cdt.utils.pty;
|
package org.eclipse.cdt.utils.pty;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author alain
|
* PTY
|
||||||
*
|
* pseudo terminal code.
|
||||||
* To change this generated comment edit the template variable "typecomment":
|
|
||||||
* Window>Preferences>Java>Templates.
|
|
||||||
* To enable and disable the creation of type comments go to
|
|
||||||
* Window>Preferences>Java>Code Generation.
|
|
||||||
*/
|
*/
|
||||||
public class PTY {
|
public class PTY {
|
||||||
|
|
||||||
String slave;
|
String slave;
|
||||||
InputStream in;
|
PTYInputStream in;
|
||||||
OutputStream out;
|
PTYOutputStream out;
|
||||||
|
/**
|
||||||
|
* NOTE: Field access by the native layer do not refactor.
|
||||||
|
*/
|
||||||
int master;
|
int master;
|
||||||
|
|
||||||
private static boolean hasPTY;
|
private static boolean hasPTY;
|
||||||
|
@ -43,14 +40,14 @@ public class PTY {
|
||||||
return master;
|
return master;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFD(int fd) {
|
void setFD(int fd) {
|
||||||
master = fd;
|
master = fd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PTY() throws IOException {
|
public PTY() throws IOException {
|
||||||
if (hasPTY) {
|
if (hasPTY) {
|
||||||
slave= forkpty();
|
slave= openMaster();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slave == null) {
|
if (slave == null) {
|
||||||
|
@ -65,22 +62,32 @@ public class PTY {
|
||||||
return slave;
|
return slave;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputStream getOutputStream() {
|
public MasterFD getMasterFD() {
|
||||||
|
return new MasterFD();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PTYOutputStream getOutputStream() {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getInputStream() {
|
public PTYInputStream getInputStream() {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
native String forkpty();
|
public static boolean isSupported() {
|
||||||
|
return hasPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
native String openMaster();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
System.loadLibrary("pty"); //$NON-NLS-1$
|
System.loadLibrary("pty"); //$NON-NLS-1$
|
||||||
hasPTY = true;
|
hasPTY = true;
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
} catch (UnsatisfiedLinkError e) {
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,9 @@ package org.eclipse.cdt.utils.spawner;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
|
|
||||||
public class ProcessFactory {
|
public class ProcessFactory {
|
||||||
|
|
||||||
static private ProcessFactory instance;
|
static private ProcessFactory instance;
|
||||||
|
@ -33,9 +36,9 @@ public class ProcessFactory {
|
||||||
hasSpawner = true;
|
hasSpawner = true;
|
||||||
}
|
}
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
//e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (UnsatisfiedLinkError e) {
|
} catch (UnsatisfiedLinkError e) {
|
||||||
//e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,4 +85,11 @@ public class ProcessFactory {
|
||||||
return new Spawner(cmdarray, envp, dir);
|
return new Spawner(cmdarray, envp, dir);
|
||||||
return runtime.exec(cmdarray, envp, dir);
|
return runtime.exec(cmdarray, envp, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Process exec(String cmdarray[], String[] envp, File dir, PTY pty)
|
||||||
|
throws IOException {
|
||||||
|
if (hasSpawner)
|
||||||
|
return new Spawner(cmdarray, envp, dir, pty);
|
||||||
|
throw new UnsupportedOperationException(CCorePlugin.getResourceString("Util.exception.cannotCreatePty")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.io.OutputStream;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
|
|
||||||
public class Spawner extends Process {
|
public class Spawner extends Process {
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ public class Spawner extends Process {
|
||||||
|
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
int status;
|
int status;
|
||||||
int[] channels = new int[3];
|
int[] fChannels = new int[3];
|
||||||
boolean isDone;
|
boolean isDone;
|
||||||
OutputStream out;
|
OutputStream out;
|
||||||
InputStream in;
|
InputStream in;
|
||||||
|
@ -56,6 +57,12 @@ public class Spawner extends Process {
|
||||||
exec(cmdarray, envp, dirpath);
|
exec(cmdarray, envp, dirpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Spawner(String[] cmdarray, String[] envp, File dir, PTY pty) throws IOException {
|
||||||
|
String dirpath = "."; //$NON-NLS-1$
|
||||||
|
if (dir != null)
|
||||||
|
dirpath = dir.getAbsolutePath();
|
||||||
|
exec_pty(cmdarray, envp, dirpath, pty);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Executes the specified string command in a separate process.
|
* Executes the specified string command in a separate process.
|
||||||
**/
|
**/
|
||||||
|
@ -222,9 +229,50 @@ public class Spawner extends Process {
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
throw new IOException("Exec error:" + reaper.getErrorMessage()); //$NON-NLS-1$
|
throw new IOException("Exec error:" + reaper.getErrorMessage()); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
in = new SpawnerInputStream(channels[1]);
|
in = new SpawnerInputStream(fChannels[1]);
|
||||||
err = new SpawnerInputStream(channels[2]);
|
err = new SpawnerInputStream(fChannels[2]);
|
||||||
out = new SpawnerOutputStream(channels[0]);
|
out = new SpawnerOutputStream(fChannels[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void exec_pty(String[] cmdarray, String[] envp, String dirpath, PTY pty) throws IOException {
|
||||||
|
String command = cmdarray[0];
|
||||||
|
SecurityManager s = System.getSecurityManager();
|
||||||
|
if (s != null)
|
||||||
|
s.checkExec(command);
|
||||||
|
if (envp == null)
|
||||||
|
envp = new String[0];
|
||||||
|
|
||||||
|
final String slaveName = pty.getSlaveName();
|
||||||
|
final int masterFD = pty.getMasterFD().getFD();
|
||||||
|
//int fdm = pty.get
|
||||||
|
Reaper reaper = new Reaper(cmdarray, envp, dirpath) {
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.utils.spawner.Spawner.Reaper#execute(java.lang.String[], java.lang.String[], java.lang.String, int[])
|
||||||
|
*/
|
||||||
|
int execute(String[] cmd, String[] env, String dir, int[] channels) throws IOException {
|
||||||
|
return exec2(cmd, env, dir, channels, slaveName, masterFD);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reaper.setDaemon(true);
|
||||||
|
reaper.start();
|
||||||
|
|
||||||
|
// Wait until the subprocess is started or error.
|
||||||
|
synchronized (this) {
|
||||||
|
while (pid == 0) {
|
||||||
|
try {
|
||||||
|
wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for errors.
|
||||||
|
if (pid == -1) {
|
||||||
|
throw new IOException("Exec_tty error:" + reaper.getErrorMessage()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
in = new SpawnerInputStream(fChannels[1]);
|
||||||
|
err = new SpawnerInputStream(fChannels[2]);
|
||||||
|
out = new SpawnerOutputStream(fChannels[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exec_detached(String[] cmdarray, String[] envp, String dirpath) throws IOException {
|
public void exec_detached(String[] cmdarray, String[] envp, String dirpath) throws IOException {
|
||||||
|
@ -241,13 +289,39 @@ public class Spawner extends Process {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native method use in normal exec() calls.
|
||||||
|
*/
|
||||||
native int exec0( String[] cmdarray, String[] envp, String dir, int[] chan) throws IOException;
|
native int exec0( String[] cmdarray, String[] envp, String dir, int[] chan) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native method use in no redirect meaning to streams will created.
|
||||||
|
*/
|
||||||
native int exec1( String[] cmdarray, String[] envp, String dir) throws IOException;
|
native int exec1( String[] cmdarray, String[] envp, String dir) throws IOException;
|
||||||
public native int raise(int pid, int sig);
|
|
||||||
native int waitFor(int pid);
|
/**
|
||||||
|
* Native method when executing with a terminal emulation.
|
||||||
|
*/
|
||||||
|
native int exec2( String[] cmdarray, String[] envp, String dir, int[] chan, String slaveName, int masterFD) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native method to drop a signal on the process with pid.
|
||||||
|
*/
|
||||||
|
public native int raise(int processID, int sig);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Native method to wait(3) for process to terminate.
|
||||||
|
*/
|
||||||
|
native int waitFor(int processID);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
try {
|
||||||
System.loadLibrary("spawner"); //$NON-NLS-1$
|
System.loadLibrary("spawner"); //$NON-NLS-1$
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spawn a thread to handle the forking and waiting
|
// Spawn a thread to handle the forking and waiting
|
||||||
|
@ -255,25 +329,29 @@ public class Spawner extends Process {
|
||||||
// send to the one thread. So do the forking and
|
// send to the one thread. So do the forking and
|
||||||
// the wait in the same thread.
|
// the wait in the same thread.
|
||||||
class Reaper extends Thread {
|
class Reaper extends Thread {
|
||||||
String[] cmdarray;
|
String[] fCmdarray;
|
||||||
String[] envp;
|
String[] fEnvp;
|
||||||
String dirpath;
|
String fDirpath;
|
||||||
String errMesg;
|
String fErrMesg;
|
||||||
|
|
||||||
public Reaper(String[] array, String[] env, String dir) {
|
public Reaper(String[] array, String[] env, String dir) {
|
||||||
super("Spawner Reaper"); //$NON-NLS-1$
|
super("Spawner Reaper"); //$NON-NLS-1$
|
||||||
cmdarray = array;
|
fCmdarray = array;
|
||||||
envp = env;
|
fEnvp = env;
|
||||||
dirpath = dir;
|
fDirpath = dir;
|
||||||
errMesg = new String(CCorePlugin.getResourceString("Util.error.cannotRun") + cmdarray[0]); //$NON-NLS-1$
|
fErrMesg = new String(CCorePlugin.getResourceString("Util.error.cannotRun") + fCmdarray[0]); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
int execute(String[] cmdarray, String[] envp, String dir, int[] channels) throws IOException {
|
||||||
|
return exec0(cmdarray, envp, dir, channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
pid = exec0(cmdarray, envp, dirpath, channels);
|
pid = execute(fCmdarray, fEnvp, fDirpath, fChannels);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
pid = -1;
|
pid = -1;
|
||||||
errMesg = e.getMessage();
|
fErrMesg = e.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell spawner that the process started.
|
// Tell spawner that the process started.
|
||||||
|
@ -292,7 +370,7 @@ public class Spawner extends Process {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getErrorMessage() {
|
public String getErrorMessage() {
|
||||||
return errMesg;
|
return fErrMesg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,8 @@ class SpawnerInputStream extends InputStream {
|
||||||
fd = -1;
|
fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native int read0(int fd, byte[] buf, int len) throws IOException;
|
private native int read0(int fileDesc, byte[] buf, int len) throws IOException;
|
||||||
private native int close0(int fd) throws IOException;
|
private native int close0(int fileDesc) throws IOException;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("spawner"); //$NON-NLS-1$
|
System.loadLibrary("spawner"); //$NON-NLS-1$
|
||||||
|
|
Loading…
Add table
Reference in a new issue