--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/tools/attach/WindowsVirtualMachine.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package sun.tools.attach;
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.AgentLoadException;
+import com.sun.tools.attach.AttachNotSupportedException;
+import com.sun.tools.attach.spi.AttachProvider;
+import sun.tools.attach.HotSpotVirtualMachine;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.Random;
+
+public class WindowsVirtualMachine extends HotSpotVirtualMachine {
+
+ // the enqueue code stub (copied into each target VM)
+ private static byte[] stub;
+
+ private volatile long hProcess; // handle to the process
+
+ WindowsVirtualMachine(AttachProvider provider, String id)
+ throws AttachNotSupportedException, IOException
+ {
+ super(provider, id);
+
+ int pid;
+ try {
+ pid = Integer.parseInt(id);
+ } catch (NumberFormatException x) {
+ throw new AttachNotSupportedException("Invalid process identifier");
+ }
+ hProcess = openProcess(pid);
+
+ // The target VM might be a pre-6.0 VM so we enqueue a "null" command
+ // which minimally tests that the enqueue function exists in the target
+ // VM.
+ try {
+ enqueue(hProcess, stub, null, null);
+ } catch (IOException x) {
+ throw new AttachNotSupportedException(x.getMessage());
+ }
+ }
+
+ public void detach() throws IOException {
+ synchronized (this) {
+ if (hProcess != -1) {
+ closeProcess(hProcess);
+ hProcess = -1;
+ }
+ }
+ }
+
+ InputStream execute(String cmd, Object ... args)
+ throws AgentLoadException, IOException
+ {
+ assert args.length <= 3; // includes null
+
+ // create a pipe using a random name
+ int r = (new Random()).nextInt();
+ String pipename = "\\\\.\\pipe\\javatool" + r;
+ long hPipe = createPipe(pipename);
+
+ // check if we are detached - in theory it's possible that detach is invoked
+ // after this check but before we enqueue the command.
+ if (hProcess == -1) {
+ closePipe(hPipe);
+ throw new IOException("Detached from target VM");
+ }
+
+ try {
+ // enqueue the command to the process
+ enqueue(hProcess, stub, cmd, pipename, args);
+
+ // wait for command to complete - process will connect with the
+ // completion status
+ connectPipe(hPipe);
+
+ // create an input stream for the pipe
+ PipedInputStream is = new PipedInputStream(hPipe);
+
+ // read completion status
+ int status = readInt(is);
+ if (status != 0) {
+ // special case the load command so that the right exception is thrown
+ if (cmd.equals("load")) {
+ throw new AgentLoadException("Failed to load agent library");
+ } else {
+ throw new IOException("Command failed in target VM");
+ }
+ }
+
+ // return the input stream
+ return is;
+
+ } catch (IOException ioe) {
+ closePipe(hPipe);
+ throw ioe;
+ }
+ }
+
+ // An InputStream based on a pipe to the target VM
+ private class PipedInputStream extends InputStream {
+
+ private long hPipe;
+
+ public PipedInputStream(long hPipe) {
+ this.hPipe = hPipe;
+ }
+
+ public synchronized int read() throws IOException {
+ byte b[] = new byte[1];
+ int n = this.read(b, 0, 1);
+ if (n == 1) {
+ return b[0] & 0xff;
+ } else {
+ return -1;
+ }
+ }
+
+ public synchronized int read(byte[] bs, int off, int len) throws IOException {
+ if ((off < 0) || (off > bs.length) || (len < 0) ||
+ ((off + len) > bs.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0)
+ return 0;
+
+ return WindowsVirtualMachine.readPipe(hPipe, bs, off, len);
+ }
+
+ public void close() throws IOException {
+ if (hPipe != -1) {
+ WindowsVirtualMachine.closePipe(hPipe);
+ hPipe = -1;
+ }
+ }
+ }
+
+
+ //-- native methods
+
+ static native void init();
+
+ static native byte[] generateStub();
+
+ static native long openProcess(int pid) throws IOException;
+
+ static native void closeProcess(long hProcess) throws IOException;
+
+ static native long createPipe(String name) throws IOException;
+
+ static native void closePipe(long hPipe) throws IOException;
+
+ static native void connectPipe(long hPipe) throws IOException;
+
+ static native int readPipe(long hPipe, byte buf[], int off, int buflen) throws IOException;
+
+ static native void enqueue(long hProcess, byte[] stub,
+ String cmd, String pipename, Object ... args) throws IOException;
+
+ static {
+ System.loadLibrary("attach");
+ init(); // native initialization
+ stub = generateStub(); // generate stub to copy into target process
+ }
+}