All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sun.tools.attach.WindowsVirtualMachine Maven / Gradle / Ivy

There is a newer version: 0.999.4
Show newest version
/*
 * 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 java.io.*;
import java.util.*;

import com.sun.tools.attach.*;
import com.sun.tools.attach.spi.*;

public final class WindowsVirtualMachine extends HotSpotVirtualMachine
{
   // The enqueue code stub (copied into each target VM).
   private static final byte[] stub;

   private volatile long hProcess;     // handle to the process

   public WindowsVirtualMachine(AttachProvider provider, String id) throws IOException
   {
      super(provider, id);
      int pid = Integer.parseInt(id);
      hProcess = openProcess(pid);
   }

   @Override
   public void detach() throws IOException
   {
      synchronized (this) {
         if (hProcess != -1) {
            closeProcess(hProcess);
            hProcess = -1;
         }
      }
   }

   @Override
   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 ("load".equals(cmd)) {
               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 final class PipedInputStream extends InputStream
   {
      private long hPipe;

      PipedInputStream(long hPipe)
      {
         this.hPipe = hPipe;
      }

      @Override
      public synchronized int read() throws IOException
      {
         byte[] b = new byte[1];
         int n = read(b, 0, 1);

         if (n == 1) {
            return b[0] & 0xff;
         }
         else {
            return -1;
         }
      }

      @Override
      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 readPipe(hPipe, bs, off, len);
      }

      @Override
      public void close() throws IOException
      {
         if (hPipe != -1) {
            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
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy