7105640: Unix printing does not check the result of exec'd lpr/lp command
authorngmr
Fri, 23 Sep 2011 15:18:32 +0100
changeset 10865 7f8dd1713604
parent 10864 17307b96ae38
child 10866 0c897d7dde86
7105640: Unix printing does not check the result of exec'd lpr/lp command Summary: Add checking, exception for spool process failure Reviewed-by: prr, jgodinez Contributed-by: Neil Richards <neil.richards@ngmr.net>
jdk/src/share/classes/sun/print/PSPrinterJob.java
jdk/src/solaris/classes/sun/print/UnixPrintJob.java
--- a/jdk/src/share/classes/sun/print/PSPrinterJob.java	Wed Oct 26 17:59:13 2011 -0700
+++ b/jdk/src/share/classes/sun/print/PSPrinterJob.java	Fri Sep 23 15:18:32 2011 +0100
@@ -68,14 +68,18 @@
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
 import java.io.CharConversionException;
 import java.io.File;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.IOException;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 
 import java.util.ArrayList;
 import java.util.Enumeration;
@@ -673,15 +677,38 @@
     private class PrinterSpooler implements java.security.PrivilegedAction {
         PrinterException pex;
 
+        private void handleProcessFailure(final Process failedProcess,
+                final String[] execCmd, final int result) throws IOException {
+            try (StringWriter sw = new StringWriter();
+                    PrintWriter pw = new PrintWriter(sw)) {
+                pw.append("error=").append(Integer.toString(result));
+                pw.append(" running:");
+                for (String arg: execCmd) {
+                    pw.append(" '").append(arg).append("'");
+                }
+                try (InputStream is = failedProcess.getErrorStream();
+                        InputStreamReader isr = new InputStreamReader(is);
+                        BufferedReader br = new BufferedReader(isr)) {
+                    while (br.ready()) {
+                        pw.println();
+                        pw.append("\t\t").append(br.readLine());
+                    }
+                } finally {
+                    pw.flush();
+                    throw new IOException(sw.toString());
+                }
+            }
+        }
+
         public Object run() {
+            if (spoolFile == null || !spoolFile.exists()) {
+               pex = new PrinterException("No spool file");
+               return null;
+            }
             try {
                 /**
                  * Spool to the printer.
                  */
-                if (spoolFile == null || !spoolFile.exists()) {
-                   pex = new PrinterException("No spool file");
-                   return null;
-                }
                 String fileName = spoolFile.getAbsolutePath();
                 String execCmd[] = printExecCmd(mDestination, mOptions,
                                mNoJobSheet, getJobNameInt(),
@@ -689,12 +716,16 @@
 
                 Process process = Runtime.getRuntime().exec(execCmd);
                 process.waitFor();
-                spoolFile.delete();
-
+                final int result = process.exitValue();
+                if (0 != result) {
+                    handleProcessFailure(process, execCmd, result);
+                }
             } catch (IOException ex) {
                 pex = new PrinterIOException(ex);
             } catch (InterruptedException ie) {
                 pex = new PrinterException(ie.toString());
+            } finally {
+                spoolFile.delete();
             }
             return null;
         }
--- a/jdk/src/solaris/classes/sun/print/UnixPrintJob.java	Wed Oct 26 17:59:13 2011 -0700
+++ b/jdk/src/solaris/classes/sun/print/UnixPrintJob.java	Fri Sep 23 15:18:32 2011 +0100
@@ -38,7 +38,9 @@
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.Reader;
+import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.util.Vector;
 
@@ -955,23 +957,49 @@
     private class PrinterSpooler implements java.security.PrivilegedAction {
         PrintException pex;
 
+        private void handleProcessFailure(final Process failedProcess,
+                final String[] execCmd, final int result) throws IOException {
+            try (StringWriter sw = new StringWriter();
+                    PrintWriter pw = new PrintWriter(sw)) {
+                pw.append("error=").append(Integer.toString(result));
+                pw.append(" running:");
+                for (String arg: execCmd) {
+                    pw.append(" '").append(arg).append("'");
+                }
+                try (InputStream is = failedProcess.getErrorStream();
+                        InputStreamReader isr = new InputStreamReader(is);
+                        BufferedReader br = new BufferedReader(isr)) {
+                    while (br.ready()) {
+                        pw.println();
+                        pw.append("\t\t").append(br.readLine());
+                    }
+                } finally {
+                    pw.flush();
+                    throw new IOException(sw.toString());
+                }
+            }
+        }
+
         public Object run() {
+            if (spoolFile == null || !spoolFile.exists()) {
+               pex = new PrintException("No spool file");
+               notifyEvent(PrintJobEvent.JOB_FAILED);
+               return null;
+            }
             try {
                 /**
                  * Spool to the printer.
                  */
-                if (spoolFile == null || !spoolFile.exists()) {
-                   pex = new PrintException("No spool file");
-                   notifyEvent(PrintJobEvent.JOB_FAILED);
-                   return null;
-                }
                 String fileName = spoolFile.getAbsolutePath();
                 String execCmd[] = printExecCmd(mDestination, mOptions,
                                mNoJobSheet, jobName, copies, fileName);
 
                 Process process = Runtime.getRuntime().exec(execCmd);
                 process.waitFor();
-                spoolFile.delete();
+                final int result = process.exitValue();
+                if (0 != result) {
+                    handleProcessFailure(process, execCmd, result);
+                }
                 notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
             } catch (IOException ex) {
                 notifyEvent(PrintJobEvent.JOB_FAILED);
@@ -981,6 +1009,7 @@
                 notifyEvent(PrintJobEvent.JOB_FAILED);
                 pex = new PrintException(ie);
             } finally {
+                spoolFile.delete();
                 notifyEvent(PrintJobEvent.NO_MORE_EVENTS);
             }
             return null;