< prev index next >

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

Print this page



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


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


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







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







































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


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



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


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


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


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


< prev index next >