log.finer("[cgi] exec " + args[0]);
}
Runtime runtime = Runtime.getRuntime();
Process process = null;
Alarm alarm = null;
try {
File dir = new File(Vfs.lookup(realPath).getParent().getNativePath());
if (log.isLoggable(Level.FINE)) {
CharBuffer argsBuf = new CharBuffer();
argsBuf.append('[');
for (String arg : args) {
if (argsBuf.length() > 1)
argsBuf.append(", ");
argsBuf.append('"');
argsBuf.append(arg);
argsBuf.append('"');
}
argsBuf.append(']');
log.fine(L.l("exec {0} (pwd={1})", argsBuf, dir));
if (log.isLoggable(Level.FINEST)) {
for (String envElement : env)
log.finest(envElement);
}
}
process = runtime.exec(args, env, dir);
InputStream inputStream = process.getInputStream();
InputStream errorStream = process.getErrorStream();
TimeoutAlarm timeout;
timeout = new TimeoutAlarm(requestURI, process, inputStream);
alarm = new Alarm(timeout, 360 * 1000);
OutputStream outputStream = process.getOutputStream();
TempBuffer tempBuf = TempBuffer.allocate();
byte []buf = tempBuf.getBuffer();
try {
ServletInputStream sis = req.getInputStream();
int len;
while ((len = sis.read(buf, 0, buf.length)) > 0) {
outputStream.write(buf, 0, len);
}
outputStream.flush();
} catch (IOException e) {
log.log(Level.FINER, e.toString(), e);
} finally {
outputStream.close();
}
TempBuffer.free(tempBuf);
tempBuf = null;
ReadStream rs = Vfs.openRead(inputStream);
boolean hasStatus = false;
try {
hasStatus = parseHeaders(req, res, rs);
OutputStream out = res.getOutputStream();
rs.writeToStream(out);
} finally {
try {
rs.close();
} catch (Throwable e) {
log.log(Level.FINER, e.toString(), e);
}
inputStream.close();
}
StringBuilder error = new StringBuilder();
boolean hasContent = false;
int ch;
while (errorStream.available() > 0 && (ch = errorStream.read()) > 0) {
error.append((char) ch);
if (! Character.isWhitespace((char) ch))
hasContent = true;
}
errorStream.close();
if (hasContent) {
String errorString = error.toString();
log.warning(errorString);
if (! hasStatus && _stderrIsException)
throw new ServletException(errorString);
}
int exitCode = process.waitFor();
if (exitCode != 0) {
if (hasStatus) {
if (log.isLoggable(Level.FINER))
log.finer(L.l("exit code {0} (ignored, hasStatus)", exitCode));
}
else if (_ignoreExitCode) {
if (log.isLoggable(Level.FINER))
log.finer(L.l("exit code {0} (ignored)", exitCode));
}
else
throw new ServletException(L.l("CGI execution failed. Exit code {0}",
exitCode));
}
} catch (IOException e) {
throw e;
} catch (ServletException e) {
throw e;
} catch (Exception e) {
throw new ServletException(e);
} finally {
if (alarm != null)
alarm.dequeue();
try {
process.destroy();
} catch (Throwable e) {
}