]> source.dussan.org Git - jgit.git/commitdiff
Attempt to make git prefix detection more reliable 61/3261/4
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Mon, 2 May 2011 20:35:54 +0000 (22:35 +0200)
committerRobin Rosenberg <robin.rosenberg@dewire.com>
Mon, 2 May 2011 20:50:49 +0000 (22:50 +0200)
This fix makes sure the readPipe methods drains the stderr
pipe and close the subprocess' stdin stream before reading
the process outputs.

I never managed to repeat the reported problem myself, so this
may help in diagnosing the probelm on other peoples machines.

Bug: 337533
Change-Id: I299555f09768c34d5868327e574326946ee265e1

org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java

index d3bfd6fce57ce24cbe7ac5fedde4043a8ca82699..7440fc9d1fe625ae48b9c0281a9c3c6f4d43f0d9 100644 (file)
@@ -46,9 +46,12 @@ package org.eclipse.jgit.util;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /** Abstraction to support various file system operations not in Java. */
 public abstract class FS {
@@ -263,33 +266,82 @@ public abstract class FS {
         * @return the one-line output of the command
         */
        protected static String readPipe(File dir, String[] command, String encoding) {
+               final boolean debug = Boolean.parseBoolean(SystemReader.getInstance()
+                               .getProperty("jgit.fs.debug"));
                try {
+                       if (debug)
+                               System.err.println("readpipe " + Arrays.asList(command) + ","
+                                               + dir);
                        final Process p = Runtime.getRuntime().exec(command, null, dir);
                        final BufferedReader lineRead = new BufferedReader(
                                        new InputStreamReader(p.getInputStream(), encoding));
+                       p.getOutputStream().close();
+                       final AtomicBoolean gooblerFail = new AtomicBoolean(false);
+                       Thread gobbler = new Thread() {
+                               public void run() {
+                                       InputStream is = p.getErrorStream();
+                                       try {
+                                               int ch;
+                                               if (debug)
+                                                       while ((ch = is.read()) != -1)
+                                                               System.err.print((char) ch);
+                                               else
+                                                       while (is.read() != -1) {
+                                                               // ignore
+                                                       }
+                                       } catch (IOException e) {
+                                               // Just print on stderr for debugging
+                                               e.printStackTrace(System.err);
+                                               gooblerFail.set(true);
+                                       }
+                                       try {
+                                               is.close();
+                                       } catch (IOException e) {
+                                               // Just print on stderr for debugging
+                                               e.printStackTrace(System.err);
+                                               gooblerFail.set(true);
+                                       }
+                               }
+                       };
+                       gobbler.start();
                        String r = null;
                        try {
                                r = lineRead.readLine();
+                               if (debug) {
+                                       System.err.println("readpipe may return '" + r + "'");
+                                       System.err.println("(ignoring remaing output:");
+                               }
+                               String l;
+                               while ((l = lineRead.readLine()) != null) {
+                                       if (debug)
+                                               System.err.println(l);
+                               }
                        } finally {
-                               p.getOutputStream().close();
                                p.getErrorStream().close();
                                lineRead.close();
                        }
 
                        for (;;) {
                                try {
-                                       if (p.waitFor() == 0 && r != null && r.length() > 0)
+                                       int rc = p.waitFor();
+                                       gobbler.join();
+                                       if (rc == 0 && r != null && r.length() > 0
+                                                       && !gooblerFail.get())
                                                return r;
+                                       if (debug)
+                                               System.err.println("readpipe rc=" + rc);
                                        break;
                                } catch (InterruptedException ie) {
                                        // Stop bothering me, I have a zombie to reap.
                                }
                        }
                } catch (IOException e) {
-                       if (SystemReader.getInstance().getProperty("jgit.fs.debug") != null)
+                       if (debug)
                                System.err.println(e);
                        // Ignore error (but report)
                }
+               if (debug)
+                       System.err.println("readpipe returns null");
                return null;
        }