1 /*
2 * Copyright (c) 2003, 2017, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang;
27
28 import java.io.File;
29 import java.io.FileDescriptor;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.util.Arrays;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Map;
37 import sun.security.action.GetPropertyAction;
38
39 /**
40 * This class is used to create operating system processes.
41 *
42 * <p>Each {@code ProcessBuilder} instance manages a collection
43 * of process attributes. The {@link #start()} method creates a new
44 * {@link Process} instance with those attributes. The {@link
45 * #start()} method can be invoked repeatedly from the same instance
46 * to create new subprocesses with identical or related attributes.
47 * <p>
48 * The {@link #startPipeline startPipeline} method can be invoked to create
49 * a pipeline of new processes that send the output of each process
50 * directly to the next process. Each process has the attributes of
51 * its respective ProcessBuilder.
52 *
53 * <p>Each process builder manages these process attributes:
54 *
55 * <ul>
56 *
1087
1088 for (String arg : cmdarray)
1089 if (arg == null)
1090 throw new NullPointerException();
1091 // Throws IndexOutOfBoundsException if command is empty
1092 String prog = cmdarray[0];
1093
1094 SecurityManager security = System.getSecurityManager();
1095 if (security != null)
1096 security.checkExec(prog);
1097
1098 String dir = directory == null ? null : directory.toString();
1099
1100 for (int i = 1; i < cmdarray.length; i++) {
1101 if (cmdarray[i].indexOf('\u0000') >= 0) {
1102 throw new IOException("invalid null character in command");
1103 }
1104 }
1105
1106 try {
1107 return ProcessImpl.start(cmdarray,
1108 environment,
1109 dir,
1110 redirects,
1111 redirectErrorStream);
1112 } catch (IOException | IllegalArgumentException e) {
1113 String exceptionInfo = ": " + e.getMessage();
1114 Throwable cause = e;
1115 if ((e instanceof IOException) && security != null) {
1116 // Can not disclose the fail reason for read-protected files.
1117 try {
1118 security.checkRead(prog);
1119 } catch (SecurityException se) {
1120 exceptionInfo = "";
1121 cause = se;
1122 }
1123 }
1124 // It's much easier for us to create a high-quality error
1125 // message than the low-level C code which found the problem.
1126 throw new IOException(
1127 "Cannot run program \"" + prog + "\""
1128 + (dir == null ? "" : " (in directory \"" + dir + "\")")
1129 + exceptionInfo,
1130 cause);
1131 }
|
1 /*
2 * Copyright (c) 2003, 2020, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang;
27
28 import java.io.File;
29 import java.io.FileDescriptor;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.util.Arrays;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.StringJoiner;
38 import jdk.internal.event.ProcessStartEvent;
39 import sun.security.action.GetPropertyAction;
40
41 /**
42 * This class is used to create operating system processes.
43 *
44 * <p>Each {@code ProcessBuilder} instance manages a collection
45 * of process attributes. The {@link #start()} method creates a new
46 * {@link Process} instance with those attributes. The {@link
47 * #start()} method can be invoked repeatedly from the same instance
48 * to create new subprocesses with identical or related attributes.
49 * <p>
50 * The {@link #startPipeline startPipeline} method can be invoked to create
51 * a pipeline of new processes that send the output of each process
52 * directly to the next process. Each process has the attributes of
53 * its respective ProcessBuilder.
54 *
55 * <p>Each process builder manages these process attributes:
56 *
57 * <ul>
58 *
1089
1090 for (String arg : cmdarray)
1091 if (arg == null)
1092 throw new NullPointerException();
1093 // Throws IndexOutOfBoundsException if command is empty
1094 String prog = cmdarray[0];
1095
1096 SecurityManager security = System.getSecurityManager();
1097 if (security != null)
1098 security.checkExec(prog);
1099
1100 String dir = directory == null ? null : directory.toString();
1101
1102 for (int i = 1; i < cmdarray.length; i++) {
1103 if (cmdarray[i].indexOf('\u0000') >= 0) {
1104 throw new IOException("invalid null character in command");
1105 }
1106 }
1107
1108 try {
1109 Process process = ProcessImpl.start(cmdarray,
1110 environment,
1111 dir,
1112 redirects,
1113 redirectErrorStream);
1114 ProcessStartEvent event = new ProcessStartEvent();
1115 if (event.isEnabled()) {
1116 StringJoiner command = new StringJoiner(" ");
1117 for (String s: cmdarray) {
1118 command.add(s);
1119 }
1120 event.directory = dir;
1121 event.command = command.toString();
1122 event.pid = process.pid();
1123 event.commit();
1124 }
1125 return process;
1126 } catch (IOException | IllegalArgumentException e) {
1127 String exceptionInfo = ": " + e.getMessage();
1128 Throwable cause = e;
1129 if ((e instanceof IOException) && security != null) {
1130 // Can not disclose the fail reason for read-protected files.
1131 try {
1132 security.checkRead(prog);
1133 } catch (SecurityException se) {
1134 exceptionInfo = "";
1135 cause = se;
1136 }
1137 }
1138 // It's much easier for us to create a high-quality error
1139 // message than the low-level C code which found the problem.
1140 throw new IOException(
1141 "Cannot run program \"" + prog + "\""
1142 + (dir == null ? "" : " (in directory \"" + dir + "\")")
1143 + exceptionInfo,
1144 cause);
1145 }
|