Browse Source

Fix problems in Linux version of <cab>:

(1) it wouldn't use the basedir

(2) all diagnostic messages have been swallowed

Submitted by:	Ilya A. Kriveshko <ilya@kaon.com>

Note that this patch needs the magic of Execute but also access to the
processes' standard input - this has been solved by adding a new
static method launch to Execute which hands out the Process instance,
the proper fix would be to handle input for the spawned processes as
well.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271431 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 23 years ago
parent
commit
2737393e9f
3 changed files with 100 additions and 12 deletions
  1. +25
    -5
      src/main/org/apache/tools/ant/taskdefs/Execute.java
  2. +34
    -3
      src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
  3. +41
    -4
      src/main/org/apache/tools/ant/taskdefs/optional/Cab.java

+ 25
- 5
src/main/org/apache/tools/ant/taskdefs/Execute.java View File

@@ -382,6 +382,28 @@ public class Execute {
this.useVMLauncher = useVMLauncher;
}

/**
* Creates a process that runs a command.
*
* @param project the Project, only used for logging purposes, may be null.
* @param command the command to run
* @param env the environment for the command
* @param the working directory for the command
* @param useVM use the built-in exec command for JDK 1.3 if available.
*
* @since 1.35, Ant 1.5
*/
public static Process launch(Project project, String[] command,
String[] env, File dir, boolean useVM)
throws IOException {
CommandLauncher launcher = vmLauncher != null ? vmLauncher : shellLauncher;
if (!useVM) {
launcher = shellLauncher;
}

return launcher.exec(project, command, env, dir);
}

/**
* Runs a process defined by the command line and returns its exit status.
*
@@ -390,12 +412,10 @@ public class Execute {
* of the subprocess failed
*/
public int execute() throws IOException {
CommandLauncher launcher = vmLauncher != null ? vmLauncher : shellLauncher;
if (!useVMLauncher) {
launcher = shellLauncher;
}
final Process process = launch(project, getCommandline(),
getEnvironment(), workingDirectory,
useVMLauncher);

final Process process = launcher.exec(project, getCommandline(), getEnvironment(), workingDirectory);
try {
streamHandler.setProcessInputStream(process.getOutputStream());
streamHandler.setProcessOutputStream(process.getInputStream());


+ 34
- 3
src/main/org/apache/tools/ant/taskdefs/StreamPumper.java View File

@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* Copyright (c) 2000,2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -72,7 +72,7 @@ public class StreamPumper implements Runnable {
private final static int SIZE = 128;
private InputStream is;
private OutputStream os;
private boolean finished;

/**
* Create a new stream pumper.
@@ -92,6 +92,11 @@ public class StreamPumper implements Runnable {
* Terminates as soon as the input stream is closed or an error occurs.
*/
public void run() {
synchronized(this) {
// Just in case this object is reused in the future
finished = false;
}

final byte[] buf = new byte[SIZE];

int length;
@@ -102,6 +107,32 @@ public class StreamPumper implements Runnable {
Thread.sleep(SLEEP);
} catch (InterruptedException e) {}
}
} catch(IOException e) {}
} catch(IOException e) {
} finally {
synchronized(this) {
finished = true;
notify();
}
}
}

/**
* Tells whether the end of the stream has been reached.
* @return true is the stream has been exhausted.
**/
public synchronized boolean isFinished() {
return finished;
}

/**
* This method blocks until the stream pumper finishes.
* @see #isFinished()
**/
public synchronized void waitFor()
throws InterruptedException
{
while(!isFinished()) {
wait();
}
}
}

+ 41
- 4
src/main/org/apache/tools/ant/taskdefs/optional/Cab.java View File

@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -65,8 +65,11 @@ import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.ExecTask;
import org.apache.tools.ant.taskdefs.LogOutputStream;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.taskdefs.StreamPumper;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.FileSet;
@@ -175,7 +178,7 @@ public class Cab extends MatchingTask {
for (int i = 0; i < files.size() && upToDate; i++) {
String file = files.elementAt(i).toString();
if (new File(baseDir, file).lastModified() >
cabFile.lastModified()) {
cabFile.lastModified()) {
upToDate = false;
}
}
@@ -212,7 +215,7 @@ public class Cab extends MatchingTask {
* to be included in the cab, one file per line.
*/
protected File createListFile(Vector files)
throws IOException {
throws IOException {
File listFile = fileUtils.createTempFile("ant", "", null);

PrintWriter writer = new PrintWriter(new FileOutputStream(listFile));
@@ -286,11 +289,45 @@ public class Cab extends MatchingTask {
sb.append("\n").append(cabFile.getAbsolutePath()).append("\n");

try {
Process p = Runtime.getRuntime().exec("listcab");
Process p = Execute.launch(getProject(),
new String[] {"listcab"}, null,
baseDir, true);
OutputStream out = p.getOutputStream();
out.write(sb.toString().getBytes());
out.flush();
out.close();

// Create the stream pumpers to forward listcab's stdout and stderr to the log
// note: listcab is an interactive program, and issues prompts for every new line.
// Therefore, make it show only with verbose logging turned on.
LogOutputStream outLog = new LogOutputStream(this, Project.MSG_VERBOSE);
LogOutputStream errLog = new LogOutputStream(this, Project.MSG_ERR);
StreamPumper outPump = new StreamPumper(p.getInputStream(), outLog);
StreamPumper errPump = new StreamPumper(p.getErrorStream(), errLog);
// Pump streams asynchronously
(new Thread(outPump)).start();
(new Thread(errPump)).start();

int result = -99; // A wild default for when the thread is interrupted

try {
// Wait for the process to finish
result = p.waitFor();

// Wait for the end of output and error streams
outPump.waitFor();
outLog.close();
errPump.waitFor();
errLog.close();
} catch(InterruptedException ie) {
log("Thread interrupted: " + ie);
}

// Informative summary message in case of errors
if(result != 0) {
log("Error executing listcab; error code: " + result);
}
} catch (IOException ex) {
String msg = "Problem creating " + cabFile + " " + ex.getMessage();
throw new BuildException(msg);


Loading…
Cancel
Save