0N/A/*
3261N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.lang;
0N/A
0N/Aimport java.io.IOException;
25N/Aimport java.io.FileInputStream;
25N/Aimport java.io.FileOutputStream;
25N/Aimport java.lang.ProcessBuilder.Redirect;
25N/Aimport java.lang.ProcessBuilder.Redirect;
0N/A
0N/A/**
0N/A * This class is for the exclusive use of ProcessBuilder.start() to
0N/A * create new processes.
0N/A *
0N/A * @author Martin Buchholz
0N/A * @since 1.5
0N/A */
0N/Afinal class ProcessImpl {
25N/A private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
25N/A = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
25N/A
0N/A private ProcessImpl() {} // Not instantiable
0N/A
0N/A private static byte[] toCString(String s) {
0N/A if (s == null)
0N/A return null;
0N/A byte[] bytes = s.getBytes();
0N/A byte[] result = new byte[bytes.length + 1];
0N/A System.arraycopy(bytes, 0,
0N/A result, 0,
0N/A bytes.length);
0N/A result[result.length-1] = (byte)0;
0N/A return result;
0N/A }
0N/A
0N/A // Only for use by ProcessBuilder.start()
0N/A static Process start(String[] cmdarray,
0N/A java.util.Map<String,String> environment,
0N/A String dir,
25N/A ProcessBuilder.Redirect[] redirects,
0N/A boolean redirectErrorStream)
0N/A throws IOException
0N/A {
0N/A assert cmdarray != null && cmdarray.length > 0;
0N/A
0N/A // Convert arguments to a contiguous block; it's easier to do
0N/A // memory management in Java than in C.
0N/A byte[][] args = new byte[cmdarray.length-1][];
0N/A int size = args.length; // For added NUL bytes
0N/A for (int i = 0; i < args.length; i++) {
0N/A args[i] = cmdarray[i+1].getBytes();
0N/A size += args[i].length;
0N/A }
0N/A byte[] argBlock = new byte[size];
0N/A int i = 0;
0N/A for (byte[] arg : args) {
0N/A System.arraycopy(arg, 0, argBlock, i, arg.length);
0N/A i += arg.length + 1;
0N/A // No need to write NUL bytes explicitly
0N/A }
0N/A
0N/A int[] envc = new int[1];
0N/A byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc);
0N/A
25N/A int[] std_fds;
25N/A
25N/A FileInputStream f0 = null;
25N/A FileOutputStream f1 = null;
25N/A FileOutputStream f2 = null;
25N/A
25N/A try {
25N/A if (redirects == null) {
25N/A std_fds = new int[] { -1, -1, -1 };
25N/A } else {
25N/A std_fds = new int[3];
25N/A
25N/A if (redirects[0] == Redirect.PIPE)
25N/A std_fds[0] = -1;
25N/A else if (redirects[0] == Redirect.INHERIT)
25N/A std_fds[0] = 0;
25N/A else {
25N/A f0 = new FileInputStream(redirects[0].file());
25N/A std_fds[0] = fdAccess.get(f0.getFD());
25N/A }
25N/A
25N/A if (redirects[1] == Redirect.PIPE)
25N/A std_fds[1] = -1;
25N/A else if (redirects[1] == Redirect.INHERIT)
25N/A std_fds[1] = 1;
25N/A else {
3200N/A f1 = new FileOutputStream(redirects[1].file(),
3200N/A redirects[1].append());
25N/A std_fds[1] = fdAccess.get(f1.getFD());
25N/A }
25N/A
25N/A if (redirects[2] == Redirect.PIPE)
25N/A std_fds[2] = -1;
25N/A else if (redirects[2] == Redirect.INHERIT)
25N/A std_fds[2] = 2;
25N/A else {
3200N/A f2 = new FileOutputStream(redirects[2].file(),
3200N/A redirects[2].append());
25N/A std_fds[2] = fdAccess.get(f2.getFD());
25N/A }
25N/A }
25N/A
0N/A return new UNIXProcess
0N/A (toCString(cmdarray[0]),
0N/A argBlock, args.length,
0N/A envBlock, envc[0],
0N/A toCString(dir),
25N/A std_fds,
0N/A redirectErrorStream);
25N/A } finally {
25N/A // In theory, close() can throw IOException
25N/A // (although it is rather unlikely to happen here)
25N/A try { if (f0 != null) f0.close(); }
25N/A finally {
25N/A try { if (f1 != null) f1.close(); }
25N/A finally { if (f2 != null) f2.close(); }
25N/A }
25N/A }
0N/A }
0N/A}