changeset 49263:305a5f1372f4

Fix jtreg test /java/jang/ProcessBuilder/Basic.java
author asiebenborn <axel.siebenborn@sap.com>
date Tue, 20 Mar 2018 14:37:12 +0100
parents 678bad6ee7a5
children d89c66395a1b
files src/java.base/unix/native/libjava/childproc.c test/jdk/java/lang/ProcessBuilder/Basic.java
diffstat 2 files changed, 64 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/unix/native/libjava/childproc.c	Fri Mar 16 16:11:08 2018 -0700
+++ b/src/java.base/unix/native/libjava/childproc.c	Tue Mar 20 14:37:12 2018 +0100
@@ -237,7 +237,13 @@
 {
     if (envp == NULL || (char **) envp == environ) {
         execvp(file, (char **) argv);
-        return;
+        // ENOEXEC indicates that the file header was not recognized. The musl C
+        // library does not implement the fallback to /bin/sh for that case, so fall
+        // through to the code below which implements that fallback using
+        // execve_with_shell_fallback.
+        if (errno != ENOEXEC) {
+            return;
+        }
     }
 
     if (*file == '\0') {
--- a/test/jdk/java/lang/ProcessBuilder/Basic.java	Fri Mar 16 16:11:08 2018 -0700
+++ b/test/jdk/java/lang/ProcessBuilder/Basic.java	Tue Mar 20 14:37:12 2018 +0100
@@ -389,8 +389,8 @@
                 if (failed != 0) throw new Error("null PATH");
             } else if (action.equals("PATH search algorithm")) {
                 equal(System.getenv("PATH"), "dir1:dir2:");
-                check(new File("/bin/true").exists());
-                check(new File("/bin/false").exists());
+                check(new File(TrueExe.path()).exists());
+                check(new File(FalseExe.path()).exists());
                 String[] cmd = {"prog"};
                 ProcessBuilder pb1 = new ProcessBuilder(cmd);
                 ProcessBuilder pb2 = new ProcessBuilder(cmd);
@@ -431,13 +431,13 @@
                         checkPermissionDenied(pb);
 
                         // continue searching if EACCES
-                        copy("/bin/true", "dir2/prog");
+                        copy(TrueExe.path(), "dir2/prog");
                         equal(run(pb).exitValue(), True.exitValue());
                         new File("dir1/prog").delete();
                         new File("dir2/prog").delete();
 
                         new File("dir2/prog").mkdirs();
-                        copy("/bin/true", "dir1/prog");
+                        copy(TrueExe.path(), "dir1/prog");
                         equal(run(pb).exitValue(), True.exitValue());
 
                         // Check empty PATH component means current directory.
@@ -453,10 +453,10 @@
                             pb.command(command);
                             File prog = new File("./prog");
                             // "Normal" binaries
-                            copy("/bin/true", "./prog");
+                            copy(TrueExe.path(), "./prog");
                             equal(run(pb).exitValue(),
                                   True.exitValue());
-                            copy("/bin/false", "./prog");
+                            copy(FalseExe.path(), "./prog");
                             equal(run(pb).exitValue(),
                                   False.exitValue());
                             prog.delete();
@@ -511,12 +511,12 @@
                         new File("dir2/prog").delete();
                         new File("prog").delete();
                         new File("dir3").mkdirs();
-                        copy("/bin/true", "dir1/prog");
-                        copy("/bin/false", "dir3/prog");
+                        copy(TrueExe.path(), "dir1/prog");
+                        copy(FalseExe.path(), "dir3/prog");
                         pb.environment().put("PATH","dir3");
                         equal(run(pb).exitValue(), True.exitValue());
-                        copy("/bin/true", "dir3/prog");
-                        copy("/bin/false", "dir1/prog");
+                        copy(TrueExe.path(), "dir3/prog");
+                        copy(FalseExe.path(), "dir1/prog");
                         equal(run(pb).exitValue(), False.exitValue());
 
                     } finally {
@@ -613,6 +613,13 @@
              new File("/bin/false").exists());
     }
 
+    static class BusyBox {
+        public static boolean is() { return is; }
+        private static final boolean is =
+            (! Windows.is() &&
+             new File("/bin/busybox").exists());
+    }
+
     static class UnicodeOS {
         public static boolean is() { return is; }
         private static final String osName = System.getProperty("os.name");
@@ -651,6 +658,45 @@
         }
     }
 
+    // On alpine linux, /bin/true and /bin/false are just links to /bin/busybox.
+    // Some tests copy /bin/true and /bin/false to files with a different filename.
+    // However, copying the busbox executable into a file with a different name
+    // won't result in the expected return codes. As workaround, we create
+    // executable files that can be copied and produce the exepected return
+    // values. We use this workaround, if we find the busybox executable.
+
+    private static class TrueExe {
+        public static String path() { return path; }
+        private static final String path = path0();
+        private static String path0(){
+            if (!BusyBox.is()) {
+                return "/bin/true";
+            }
+            else {
+                File trueExe = new File("true");
+                setFileContents(trueExe, "#!/bin/true\n");
+                trueExe.setExecutable(true);
+                return trueExe.getAbsolutePath();
+            }
+        }
+    }
+
+    private static class FalseExe {
+        public static String path() { return path; }
+        private static final String path = path0();
+        private static String path0(){
+            if (!BusyBox.is()) {
+                return "/bin/false";
+            }
+            else {
+                File falseExe = new File("false");
+                setFileContents(falseExe, "#!/bin/false\n");
+                falseExe.setExecutable(true);
+                return falseExe.getAbsolutePath();
+            }
+        }
+    }
+
     static class EnglishUnix {
         private static final Boolean is =
             (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL"));
@@ -1954,7 +2000,7 @@
             //----------------------------------------------------------------
             try {
                 new File("suBdiR").mkdirs();
-                copy("/bin/true", "suBdiR/unliKely");
+                copy(TrueExe.path(), "suBdiR/unliKely");
                 final ProcessBuilder pb =
                     new ProcessBuilder(new String[]{"unliKely"});
                 pb.environment().put("PATH", "suBdiR");