< prev index next >

test/jdk/java/lang/ProcessBuilder/Basic.java

Print this page




 379                 equal(System.getenv("PATH"), null);
 380                 check(new File("/bin/true").exists());
 381                 check(new File("/bin/false").exists());
 382                 ProcessBuilder pb1 = new ProcessBuilder();
 383                 ProcessBuilder pb2 = new ProcessBuilder();
 384                 pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
 385                 ProcessResults r;
 386 
 387                 for (final ProcessBuilder pb :
 388                          new ProcessBuilder[] {pb1, pb2}) {
 389                     pb.command("true");
 390                     equal(run(pb).exitValue(), True.exitValue());
 391 
 392                     pb.command("false");
 393                     equal(run(pb).exitValue(), False.exitValue());
 394                 }
 395 
 396                 if (failed != 0) throw new Error("null PATH");
 397             } else if (action.equals("PATH search algorithm")) {
 398                 equal(System.getenv("PATH"), "dir1:dir2:");
 399                 check(new File("/bin/true").exists());
 400                 check(new File("/bin/false").exists());
 401                 String[] cmd = {"prog"};
 402                 ProcessBuilder pb1 = new ProcessBuilder(cmd);
 403                 ProcessBuilder pb2 = new ProcessBuilder(cmd);
 404                 ProcessBuilder pb3 = new ProcessBuilder(cmd);
 405                 pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
 406                 pb3.environment().remove("PATH");
 407 
 408                 for (final ProcessBuilder pb :
 409                          new ProcessBuilder[] {pb1, pb2, pb3}) {
 410                     try {
 411                         // Not on PATH at all; directories don't exist
 412                         try {
 413                             pb.start();
 414                             fail("Expected IOException not thrown");
 415                         } catch (IOException e) {
 416                             String m = e.getMessage();
 417                             if (EnglishUnix.is() &&
 418                                 ! matches(m, "No such file"))
 419                                 unexpected(e);
 420                         } catch (Throwable t) { unexpected(t); }
 421 
 422                         // Not on PATH at all; directories exist
 423                         new File("dir1").mkdirs();
 424                         new File("dir2").mkdirs();
 425                         try {
 426                             pb.start();
 427                             fail("Expected IOException not thrown");
 428                         } catch (IOException e) {
 429                             String m = e.getMessage();
 430                             if (EnglishUnix.is() &&
 431                                 ! matches(m, "No such file"))
 432                                 unexpected(e);
 433                         } catch (Throwable t) { unexpected(t); }
 434 
 435                         // Can't execute a directory -- permission denied
 436                         // Report EACCES errno
 437                         new File("dir1/prog").mkdirs();
 438                         checkPermissionDenied(pb);
 439 
 440                         // continue searching if EACCES
 441                         copy("/bin/true", "dir2/prog");
 442                         equal(run(pb).exitValue(), True.exitValue());
 443                         new File("dir1/prog").delete();
 444                         new File("dir2/prog").delete();
 445 
 446                         new File("dir2/prog").mkdirs();
 447                         copy("/bin/true", "dir1/prog");
 448                         equal(run(pb).exitValue(), True.exitValue());
 449 
 450                         // Check empty PATH component means current directory.
 451                         //
 452                         // While we're here, let's test different kinds of
 453                         // Unix executables, and PATH vs explicit searching.
 454                         new File("dir1/prog").delete();
 455                         new File("dir2/prog").delete();
 456                         for (String[] command :
 457                                  new String[][] {
 458                                      new String[] {"./prog"},
 459                                      cmd}) {
 460                             pb.command(command);
 461                             File prog = new File("./prog");
 462                             // "Normal" binaries
 463                             copy("/bin/true", "./prog");
 464                             equal(run(pb).exitValue(),
 465                                   True.exitValue());
 466                             copy("/bin/false", "./prog");
 467                             equal(run(pb).exitValue(),
 468                                   False.exitValue());
 469                             prog.delete();
 470                             // Interpreter scripts with #!
 471                             setFileContents(prog, "#!/bin/true\n");
 472                             prog.setExecutable(true);
 473                             equal(run(pb).exitValue(),
 474                                   True.exitValue());
 475                             prog.delete();
 476                             setFileContents(prog, "#!/bin/false\n");
 477                             prog.setExecutable(true);
 478                             equal(run(pb).exitValue(),
 479                                   False.exitValue());
 480                             // Traditional shell scripts without #!
 481                             setFileContents(prog, "exec /bin/true\n");
 482                             prog.setExecutable(true);
 483                             equal(run(pb).exitValue(),
 484                                   True.exitValue());
 485                             prog.delete();
 486                             setFileContents(prog, "exec /bin/false\n");


 501                         equal(run(pb).exitValue(), True.exitValue());
 502                         dir1Prog.delete();
 503                         pb.command(cmd);
 504 
 505                         // Test traditional shell scripts without #!
 506                         setFileContents(dir1Prog, "/bin/echo \"$@\"\n");
 507                         pb.command(new String[] {"prog", "hello", "world"});
 508                         checkPermissionDenied(pb);
 509                         dir1Prog.setExecutable(true);
 510                         equal(run(pb).out(), "hello world\n");
 511                         equal(run(pb).exitValue(), True.exitValue());
 512                         dir1Prog.delete();
 513                         pb.command(cmd);
 514 
 515                         // If prog found on both parent and child's PATH,
 516                         // parent's is used.
 517                         new File("dir1/prog").delete();
 518                         new File("dir2/prog").delete();
 519                         new File("prog").delete();
 520                         new File("dir3").mkdirs();
 521                         copy("/bin/true", "dir1/prog");
 522                         copy("/bin/false", "dir3/prog");
 523                         pb.environment().put("PATH","dir3");
 524                         equal(run(pb).exitValue(), True.exitValue());
 525                         copy("/bin/true", "dir3/prog");
 526                         copy("/bin/false", "dir1/prog");
 527                         equal(run(pb).exitValue(), False.exitValue());
 528 
 529                     } finally {
 530                         // cleanup
 531                         new File("dir1/prog").delete();
 532                         new File("dir2/prog").delete();
 533                         new File("dir3/prog").delete();
 534                         new File("dir1").delete();
 535                         new File("dir2").delete();
 536                         new File("dir3").delete();
 537                         new File("prog").delete();
 538                     }
 539                 }
 540 
 541                 if (failed != 0) throw new Error("PATH search algorithm");
 542             }
 543             else throw new Error("JavaChild invocation error");
 544         }
 545     }
 546 


 603         public static boolean is() { return is; }
 604         private static final boolean is =
 605             System.getProperty("os.name").startsWith("Windows");
 606     }
 607 
 608     static class AIX {
 609         public static boolean is() { return is; }
 610         private static final boolean is =
 611             System.getProperty("os.name").equals("AIX");
 612     }
 613 
 614     static class Unix {
 615         public static boolean is() { return is; }
 616         private static final boolean is =
 617             (! Windows.is() &&
 618              new File("/bin/sh").exists() &&
 619              new File("/bin/true").exists() &&
 620              new File("/bin/false").exists());
 621     }
 622 







 623     static class UnicodeOS {
 624         public static boolean is() { return is; }
 625         private static final String osName = System.getProperty("os.name");
 626         private static final boolean is =
 627             // MacOS X would probably also qualify
 628             osName.startsWith("Windows")   &&
 629             ! osName.startsWith("Windows 9") &&
 630             ! osName.equals("Windows Me");
 631     }
 632 
 633     static class MacOSX {
 634         public static boolean is() { return is; }
 635         private static final String osName = System.getProperty("os.name");
 636         private static final boolean is = osName.contains("OS X");
 637     }
 638 
 639     static class True {
 640         public static int exitValue() { return 0; }
 641     }
 642 
 643     private static class False {
 644         public static int exitValue() { return exitValue; }
 645         private static final int exitValue = exitValue0();
 646         private static int exitValue0() {
 647             // /bin/false returns an *unspecified* non-zero number.
 648             try {
 649                 if (! Unix.is())
 650                     return -1;
 651                 else {
 652                     int rc = new ProcessBuilder("/bin/false")
 653                         .start().waitFor();
 654                     check(rc != 0);
 655                     return rc;
 656                 }
 657             } catch (Throwable t) { unexpected(t); return -1; }
 658         }
 659     }
 660 







































 661     static class EnglishUnix {
 662         private static final Boolean is =
 663             (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL"));
 664 
 665         private static boolean isEnglish(String envvar) {
 666             String val = getenv(envvar);
 667             return (val == null) || val.matches("en.*") || val.matches("C");
 668         }
 669 
 670         /** Returns true if we can expect English OS error strings */
 671         static boolean is() { return is; }
 672     }
 673 
 674     static class DelegatingProcess extends Process {
 675         final Process p;
 676 
 677         DelegatingProcess(Process p) {
 678             this.p = p;
 679         }
 680 


1944 
1945             //----------------------------------------------------------------
1946             // PATH search algorithm on Unix
1947             //----------------------------------------------------------------
1948             try {
1949                 List<String> childArgs = new ArrayList<String>(javaChildArgs);
1950                 childArgs.add("PATH search algorithm");
1951                 ProcessBuilder pb = new ProcessBuilder(childArgs);
1952                 pb.environment().put("PATH", "dir1:dir2:");
1953                 ProcessResults r = run(pb);
1954                 equal(r.out(), "");
1955                 equal(r.err(), "");
1956                 equal(r.exitValue(), True.exitValue());
1957             } catch (Throwable t) { unexpected(t); }
1958 
1959             //----------------------------------------------------------------
1960             // Parent's, not child's PATH is used
1961             //----------------------------------------------------------------
1962             try {
1963                 new File("suBdiR").mkdirs();
1964                 copy("/bin/true", "suBdiR/unliKely");
1965                 final ProcessBuilder pb =
1966                     new ProcessBuilder(new String[]{"unliKely"});
1967                 pb.environment().put("PATH", "suBdiR");
1968                 THROWS(IOException.class, () -> pb.start());
1969             } catch (Throwable t) { unexpected(t);
1970             } finally {
1971                 new File("suBdiR/unliKely").delete();
1972                 new File("suBdiR").delete();
1973             }
1974         }
1975 
1976         //----------------------------------------------------------------
1977         // Attempt to start bogus program ""
1978         //----------------------------------------------------------------
1979         try {
1980             new ProcessBuilder("").start();
1981             fail("Expected IOException not thrown");
1982         } catch (IOException e) {
1983             String m = e.getMessage();
1984             if (EnglishUnix.is() &&




 379                 equal(System.getenv("PATH"), null);
 380                 check(new File("/bin/true").exists());
 381                 check(new File("/bin/false").exists());
 382                 ProcessBuilder pb1 = new ProcessBuilder();
 383                 ProcessBuilder pb2 = new ProcessBuilder();
 384                 pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
 385                 ProcessResults r;
 386 
 387                 for (final ProcessBuilder pb :
 388                          new ProcessBuilder[] {pb1, pb2}) {
 389                     pb.command("true");
 390                     equal(run(pb).exitValue(), True.exitValue());
 391 
 392                     pb.command("false");
 393                     equal(run(pb).exitValue(), False.exitValue());
 394                 }
 395 
 396                 if (failed != 0) throw new Error("null PATH");
 397             } else if (action.equals("PATH search algorithm")) {
 398                 equal(System.getenv("PATH"), "dir1:dir2:");
 399                 check(new File(TrueExe.path()).exists());
 400                 check(new File(FalseExe.path()).exists());
 401                 String[] cmd = {"prog"};
 402                 ProcessBuilder pb1 = new ProcessBuilder(cmd);
 403                 ProcessBuilder pb2 = new ProcessBuilder(cmd);
 404                 ProcessBuilder pb3 = new ProcessBuilder(cmd);
 405                 pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
 406                 pb3.environment().remove("PATH");
 407 
 408                 for (final ProcessBuilder pb :
 409                          new ProcessBuilder[] {pb1, pb2, pb3}) {
 410                     try {
 411                         // Not on PATH at all; directories don't exist
 412                         try {
 413                             pb.start();
 414                             fail("Expected IOException not thrown");
 415                         } catch (IOException e) {
 416                             String m = e.getMessage();
 417                             if (EnglishUnix.is() &&
 418                                 ! matches(m, "No such file"))
 419                                 unexpected(e);
 420                         } catch (Throwable t) { unexpected(t); }
 421 
 422                         // Not on PATH at all; directories exist
 423                         new File("dir1").mkdirs();
 424                         new File("dir2").mkdirs();
 425                         try {
 426                             pb.start();
 427                             fail("Expected IOException not thrown");
 428                         } catch (IOException e) {
 429                             String m = e.getMessage();
 430                             if (EnglishUnix.is() &&
 431                                 ! matches(m, "No such file"))
 432                                 unexpected(e);
 433                         } catch (Throwable t) { unexpected(t); }
 434 
 435                         // Can't execute a directory -- permission denied
 436                         // Report EACCES errno
 437                         new File("dir1/prog").mkdirs();
 438                         checkPermissionDenied(pb);
 439 
 440                         // continue searching if EACCES
 441                         copy(TrueExe.path(), "dir2/prog");
 442                         equal(run(pb).exitValue(), True.exitValue());
 443                         new File("dir1/prog").delete();
 444                         new File("dir2/prog").delete();
 445 
 446                         new File("dir2/prog").mkdirs();
 447                         copy(TrueExe.path(), "dir1/prog");
 448                         equal(run(pb).exitValue(), True.exitValue());
 449 
 450                         // Check empty PATH component means current directory.
 451                         //
 452                         // While we're here, let's test different kinds of
 453                         // Unix executables, and PATH vs explicit searching.
 454                         new File("dir1/prog").delete();
 455                         new File("dir2/prog").delete();
 456                         for (String[] command :
 457                                  new String[][] {
 458                                      new String[] {"./prog"},
 459                                      cmd}) {
 460                             pb.command(command);
 461                             File prog = new File("./prog");
 462                             // "Normal" binaries
 463                             copy(TrueExe.path(), "./prog");
 464                             equal(run(pb).exitValue(),
 465                                   True.exitValue());
 466                             copy(FalseExe.path(), "./prog");
 467                             equal(run(pb).exitValue(),
 468                                   False.exitValue());
 469                             prog.delete();
 470                             // Interpreter scripts with #!
 471                             setFileContents(prog, "#!/bin/true\n");
 472                             prog.setExecutable(true);
 473                             equal(run(pb).exitValue(),
 474                                   True.exitValue());
 475                             prog.delete();
 476                             setFileContents(prog, "#!/bin/false\n");
 477                             prog.setExecutable(true);
 478                             equal(run(pb).exitValue(),
 479                                   False.exitValue());
 480                             // Traditional shell scripts without #!
 481                             setFileContents(prog, "exec /bin/true\n");
 482                             prog.setExecutable(true);
 483                             equal(run(pb).exitValue(),
 484                                   True.exitValue());
 485                             prog.delete();
 486                             setFileContents(prog, "exec /bin/false\n");


 501                         equal(run(pb).exitValue(), True.exitValue());
 502                         dir1Prog.delete();
 503                         pb.command(cmd);
 504 
 505                         // Test traditional shell scripts without #!
 506                         setFileContents(dir1Prog, "/bin/echo \"$@\"\n");
 507                         pb.command(new String[] {"prog", "hello", "world"});
 508                         checkPermissionDenied(pb);
 509                         dir1Prog.setExecutable(true);
 510                         equal(run(pb).out(), "hello world\n");
 511                         equal(run(pb).exitValue(), True.exitValue());
 512                         dir1Prog.delete();
 513                         pb.command(cmd);
 514 
 515                         // If prog found on both parent and child's PATH,
 516                         // parent's is used.
 517                         new File("dir1/prog").delete();
 518                         new File("dir2/prog").delete();
 519                         new File("prog").delete();
 520                         new File("dir3").mkdirs();
 521                         copy(TrueExe.path(), "dir1/prog");
 522                         copy(FalseExe.path(), "dir3/prog");
 523                         pb.environment().put("PATH","dir3");
 524                         equal(run(pb).exitValue(), True.exitValue());
 525                         copy(TrueExe.path(), "dir3/prog");
 526                         copy(FalseExe.path(), "dir1/prog");
 527                         equal(run(pb).exitValue(), False.exitValue());
 528 
 529                     } finally {
 530                         // cleanup
 531                         new File("dir1/prog").delete();
 532                         new File("dir2/prog").delete();
 533                         new File("dir3/prog").delete();
 534                         new File("dir1").delete();
 535                         new File("dir2").delete();
 536                         new File("dir3").delete();
 537                         new File("prog").delete();
 538                     }
 539                 }
 540 
 541                 if (failed != 0) throw new Error("PATH search algorithm");
 542             }
 543             else throw new Error("JavaChild invocation error");
 544         }
 545     }
 546 


 603         public static boolean is() { return is; }
 604         private static final boolean is =
 605             System.getProperty("os.name").startsWith("Windows");
 606     }
 607 
 608     static class AIX {
 609         public static boolean is() { return is; }
 610         private static final boolean is =
 611             System.getProperty("os.name").equals("AIX");
 612     }
 613 
 614     static class Unix {
 615         public static boolean is() { return is; }
 616         private static final boolean is =
 617             (! Windows.is() &&
 618              new File("/bin/sh").exists() &&
 619              new File("/bin/true").exists() &&
 620              new File("/bin/false").exists());
 621     }
 622 
 623     static class BusyBox {
 624         public static boolean is() { return is; }
 625         private static final boolean is =
 626             (! Windows.is() &&
 627              new File("/bin/busybox").exists());
 628     }
 629 
 630     static class UnicodeOS {
 631         public static boolean is() { return is; }
 632         private static final String osName = System.getProperty("os.name");
 633         private static final boolean is =
 634             // MacOS X would probably also qualify
 635             osName.startsWith("Windows")   &&
 636             ! osName.startsWith("Windows 9") &&
 637             ! osName.equals("Windows Me");
 638     }
 639 
 640     static class MacOSX {
 641         public static boolean is() { return is; }
 642         private static final String osName = System.getProperty("os.name");
 643         private static final boolean is = osName.contains("OS X");
 644     }
 645 
 646     static class True {
 647         public static int exitValue() { return 0; }
 648     }
 649 
 650     private static class False {
 651         public static int exitValue() { return exitValue; }
 652         private static final int exitValue = exitValue0();
 653         private static int exitValue0() {
 654             // /bin/false returns an *unspecified* non-zero number.
 655             try {
 656                 if (! Unix.is())
 657                     return -1;
 658                 else {
 659                     int rc = new ProcessBuilder("/bin/false")
 660                         .start().waitFor();
 661                     check(rc != 0);
 662                     return rc;
 663                 }
 664             } catch (Throwable t) { unexpected(t); return -1; }
 665         }
 666     }
 667 
 668     // On alpine linux, /bin/true and /bin/false are just links to /bin/busybox.
 669     // Some tests copy /bin/true and /bin/false to files with a different filename.
 670     // However, copying the busbox executable into a file with a different name
 671     // won't result in the expected return codes. As workaround, we create
 672     // executable files that can be copied and produce the exepected return
 673     // values. We use this workaround, if we find the busybox executable.
 674 
 675     private static class TrueExe {
 676         public static String path() { return path; }
 677         private static final String path = path0();
 678         private static String path0(){
 679             if (!BusyBox.is()) {
 680                 return "/bin/true";
 681             }
 682             else {
 683                 File trueExe = new File("true");
 684                 setFileContents(trueExe, "#!/bin/true\n");
 685                 trueExe.setExecutable(true);
 686                 return trueExe.getAbsolutePath();
 687             }
 688         }
 689     }
 690 
 691     private static class FalseExe {
 692         public static String path() { return path; }
 693         private static final String path = path0();
 694         private static String path0(){
 695             if (!BusyBox.is()) {
 696                 return "/bin/false";
 697             }
 698             else {
 699                 File falseExe = new File("false");
 700                 setFileContents(falseExe, "#!/bin/false\n");
 701                 falseExe.setExecutable(true);
 702                 return falseExe.getAbsolutePath();
 703             }
 704         }
 705     }
 706 
 707     static class EnglishUnix {
 708         private static final Boolean is =
 709             (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL"));
 710 
 711         private static boolean isEnglish(String envvar) {
 712             String val = getenv(envvar);
 713             return (val == null) || val.matches("en.*") || val.matches("C");
 714         }
 715 
 716         /** Returns true if we can expect English OS error strings */
 717         static boolean is() { return is; }
 718     }
 719 
 720     static class DelegatingProcess extends Process {
 721         final Process p;
 722 
 723         DelegatingProcess(Process p) {
 724             this.p = p;
 725         }
 726 


1990 
1991             //----------------------------------------------------------------
1992             // PATH search algorithm on Unix
1993             //----------------------------------------------------------------
1994             try {
1995                 List<String> childArgs = new ArrayList<String>(javaChildArgs);
1996                 childArgs.add("PATH search algorithm");
1997                 ProcessBuilder pb = new ProcessBuilder(childArgs);
1998                 pb.environment().put("PATH", "dir1:dir2:");
1999                 ProcessResults r = run(pb);
2000                 equal(r.out(), "");
2001                 equal(r.err(), "");
2002                 equal(r.exitValue(), True.exitValue());
2003             } catch (Throwable t) { unexpected(t); }
2004 
2005             //----------------------------------------------------------------
2006             // Parent's, not child's PATH is used
2007             //----------------------------------------------------------------
2008             try {
2009                 new File("suBdiR").mkdirs();
2010                 copy(TrueExe.path(), "suBdiR/unliKely");
2011                 final ProcessBuilder pb =
2012                     new ProcessBuilder(new String[]{"unliKely"});
2013                 pb.environment().put("PATH", "suBdiR");
2014                 THROWS(IOException.class, () -> pb.start());
2015             } catch (Throwable t) { unexpected(t);
2016             } finally {
2017                 new File("suBdiR/unliKely").delete();
2018                 new File("suBdiR").delete();
2019             }
2020         }
2021 
2022         //----------------------------------------------------------------
2023         // Attempt to start bogus program ""
2024         //----------------------------------------------------------------
2025         try {
2026             new ProcessBuilder("").start();
2027             fail("Expected IOException not thrown");
2028         } catch (IOException e) {
2029             String m = e.getMessage();
2030             if (EnglishUnix.is() &&


< prev index next >