1/*
2 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/* @test
25 * @bug 5006520
26 * @summary Check many different ways to run Windows programs
27 * @author Martin Buchholz
28 * @key randomness
29 */
30
31import java.io.*;
32import java.util.*;
33import static java.lang.System.*;
34
35class StreamDrainer extends Thread {
36    private final InputStream is;
37    private final ByteArrayOutputStream os = new ByteArrayOutputStream();
38    public StreamDrainer(InputStream is) { this.is = is; }
39    public void run() {
40        try {
41            int i;
42            while ((i = is.read()) >= 0)
43                os.write(i);
44        } catch (Exception e) {}
45    }
46    public String toString() { return os.toString(); }
47}
48
49class CommandRunner {
50    private static Random generator = new Random();
51    public final int exitValue;
52    public final String out;
53    public final String err;
54    CommandRunner(String... args) throws Exception {
55        Process p = (generator.nextInt(2) == 0)
56            ? new ProcessBuilder(args).start()
57            : Runtime.getRuntime().exec(args);
58        StreamDrainer d1 = new StreamDrainer(p.getInputStream());
59        StreamDrainer d2 = new StreamDrainer(p.getErrorStream());
60        d1.start();
61        d2.start();
62        p.waitFor();
63        d1.join();
64        d2.join();
65        this.exitValue = p.exitValue();
66        this.out = d1.toString();
67        this.err = d2.toString();
68    }
69}
70
71public class WinCommand {
72    private static int failed = 0;
73
74    private static void fail(String msg) {
75        err.printf("FAIL: %s%n", msg);
76        failed++;
77    }
78
79    private static String outputOf(String... args) {
80        try {
81            CommandRunner cr = new CommandRunner(args);
82            if (cr.exitValue != 0)
83                fail("exitValue != 0");
84            if (! cr.err.equals(""))
85                fail("stderr: " + cr.err);
86            return cr.out.replaceFirst("[\r\n]+$", "");
87        } catch (Exception e) {
88            fail(e.toString());
89            return "";
90        }
91    }
92
93    private static void checkCD(String... filespecs) {
94        String firstCD = null;
95        for (String filespec : filespecs) {
96            String CD = outputOf(filespec, "/C", "CD");
97            out.printf("%s CD ==> %s%n", filespec, CD);
98            if (firstCD == null) {
99                firstCD = CD;
100                checkDir(CD);
101            }
102            if (! CD.equals(firstCD)) {
103                fail("Inconsistent result from CD subcommand");
104                checkDir(CD);
105            }
106        }
107    }
108
109    private static void checkDir(String dirname) {
110        if (! new File(dirname).isDirectory())
111            fail(String.format("Not a directory: %s%n", dirname));
112    }
113
114    private static void writeFile(String filename, String contents) {
115        try {
116            FileOutputStream fos = new FileOutputStream(filename);
117            fos.write(contents.getBytes());
118            fos.close();
119        } catch (Exception e) {
120            fail("Unexpected exception" + e.toString());
121        }
122    }
123
124    public static void main(String[] args) throws Exception {
125        File systemRoot =
126            getenv("SystemRoot") != null ? new File(getenv("SystemRoot")) :
127            getenv("WINDIR")     != null ? new File(getenv ("WINDIR")) :
128            null;
129        if (systemRoot == null || ! systemRoot.isDirectory())
130            return; // Not Windows as we know it
131
132        String systemDirW = new File(systemRoot, "System32").getPath();
133        String systemDirM = systemDirW.replace('\\', '/');
134        out.printf("systemDirW=%s%n", systemDirW);
135        out.printf("systemDirM=%s%n", systemDirM);
136
137        // Win9x systems don't have a cmd.exe
138        if (new File(systemDirW, "cmd.exe").exists()) {
139            try {
140                out.println("Running cmd.exe tests...");
141                writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n");
142                writeFile("cdbat.bat", "@echo off\r\nCD\r\n");
143                checkCD("cmd",
144                        "cmd.exe",
145                        systemDirW + "\\cmd.exe",
146                        // Only the ".exe" extension can be omitted
147                        systemDirW + "\\cmd",
148                        systemDirM + "/cmd.exe",
149                        systemDirM + "/cmd",
150                        "/" + systemDirM + "/cmd",
151                        "cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd",
152                        "cdbat.bat", "./cdbat.bat", ".\\cdbat.bat");
153            } finally {
154                new File("cdcmd.cmd").delete();
155                new File("cdbat.bat").delete();
156            }
157        }
158
159        // 16-bit apps like command.com must have a console;
160        // fix this someday...
161
162//      // Win64 systems don't have a command.com
163//      if (new File(systemDirW, "command.com").exists()
164//          // no output if running without a console;
165//          // fix this in Mustang
166//          && ! outputOf("command.com", "/C", "CD").equals("")) {
167//          out.println("Running command.com tests...");
168//          checkCD("command.com",
169//                  systemDirM + "/command.com",
170//                  systemDirW + "\\command.com");
171//      }
172
173        // Win9x systems have a %SYSTEMDRIVE%\command.com
174//      if (new File("C:\\COMMAND.COM").exists()
175//          && ! outputOf("COMMAND.COM", "/C", "CD").equals("")) {
176//          out.println("Running COMMAND.COM tests...");
177//          checkCD("C:/command.com",
178//                  "C:\\command.com");
179//      }
180
181        if (failed > 0)
182            throw new Exception(failed + " tests failed");
183    }
184}
185