⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 natwin32process.cc

📁 gcc的组建
💻 CC
字号:
// natWin32Process.cc - Native side of Win32 process code./* Copyright (C) 2003  Free Software Foundation   This file is part of libgcj.This software is copyrighted work licensed under the terms of theLibgcj License.  Please consult the file "LIBGCJ_LICENSE" fordetails.  */#include <config.h>#include <platform.h>// Conflicts with the definition in "java/lang/reflect/Modifier.h"#undef STRICT#include <java/lang/ConcreteProcess.h>#include <java/lang/IllegalThreadStateException.h>#include <java/lang/InterruptedException.h>#include <java/lang/NullPointerException.h>#include <java/lang/Thread.h>#include <java/io/File.h>#include <java/io/FileDescriptor.h>#include <java/io/FileInputStream.h>#include <java/io/FileOutputStream.h>#include <java/io/IOException.h>#include <java/lang/OutOfMemoryError.h>#include <gnu/java/nio/channels/FileChannelImpl.h>using gnu::java::nio::channels::FileChannelImpl;voidjava::lang::ConcreteProcess::cleanup (void){  // FIXME:  // We used to close the input, output and  // error streams here, but we can't do that  // because the caller also has the right  // to close these and FileInputStream and FileOutputStream  // scream if you attempt to close() them twice. Presently,  // we use _Jv_platform_close_on_exec, which is similar  // to the POSIX approach.  //  // What I wanted to do is have private nested  // classes in ConcreteProcess which extend FileInputStream  // and FileOutputStream, respectively, but override  // close() to permit multiple calls to close(). This  // led to class header and platform configury issues  // that I didn't feel like dealing with. However,  // this approach could conceivably be a good multiplatform  // one since delaying the pipe close until process  // termination could be wasteful if many child processes  // are spawned within the parent process' lifetime.  inputStream = NULL;  outputStream = NULL;  errorStream = NULL;    if (procHandle)    {      CloseHandle((HANDLE) procHandle);      procHandle = (jint) INVALID_HANDLE_VALUE;    }}voidjava::lang::ConcreteProcess::destroy (void){  if (! hasExited ())    {      // Kill it forcibly and assign an (arbitrary) exit code of 0.      TerminateProcess ((HANDLE) procHandle, 0);      exitCode = 0;      cleanup ();    }}jbooleanjava::lang::ConcreteProcess::hasExited (void){  DWORD exitStatus;  if (GetExitCodeProcess ((HANDLE) procHandle, &exitStatus) != 0)    {      // NOTE: STILL_ACTIVE is defined as "259" by Win32 - if the      // child actually exits with this return code, we have a      // problem here. See MSDN documentation on GetExitCodeProcess( ).      if (exitStatus == STILL_ACTIVE)        return false;      else        {          cleanup ();          exitCode = exitStatus;          return true;        }    }  else    return true;}jintjava::lang::ConcreteProcess::waitFor (void){  if (! hasExited ())    {      DWORD exitStatus = 0UL;      // Set up our waitable objects array      // - 0: the handle to the process we just launched      // - 1: our thread's interrupt event      HANDLE arh[2];      arh[0] = (HANDLE) procHandle;      arh[1] = _Jv_Win32GetInterruptEvent ();      DWORD rval = WaitForMultipleObjects (2, arh, 0, INFINITE);      // Use the returned value from WaitForMultipleObjects      // instead of our thread's interrupt_flag to test for      // thread interruption. See the comment for      // _Jv_Win32GetInterruptEvent().      bool bInterrupted = rval == (WAIT_OBJECT_0 + 1);            if (bInterrupted)        {          // Querying this forces a reset our thread's interrupt flag.          Thread::interrupted();                    cleanup ();          throw new InterruptedException ();        }      GetExitCodeProcess ((HANDLE) procHandle, &exitStatus);      exitCode = exitStatus;      cleanup ();    }  return exitCode;}// Helper class for creating and managing the pipes// used for I/O redirection for child processes.class ChildProcessPipe{public:  // Indicates from the child process' point of view  // whether the pipe is for reading or writing.  enum EType {INPUT, OUTPUT};  ChildProcessPipe(EType eType);  ~ChildProcessPipe();    // Returns a pipe handle suitable for use by the parent process  HANDLE getParentHandle();    // Returns a pipe handle suitable for use by the child process.  HANDLE getChildHandle();  private:  EType m_eType;  HANDLE m_hRead, m_hWrite;};ChildProcessPipe::ChildProcessPipe(EType eType):  m_eType(eType){  SECURITY_ATTRIBUTES sAttrs;  // Explicitly allow the handles to the pipes to be inherited.  sAttrs.nLength = sizeof (SECURITY_ATTRIBUTES);  sAttrs.bInheritHandle = 1;  sAttrs.lpSecurityDescriptor = NULL;  if (CreatePipe (&m_hRead, &m_hWrite, &sAttrs, 0) == 0)    {      DWORD dwErrorCode = GetLastError ();      throw new java::io::IOException (        _Jv_WinStrError (_T("Error creating pipe"), dwErrorCode));    }  // If this is the read end of the child, we need  // to make the parent write end non-inheritable. Similarly,  // if this is the write end of the child, we need to make  // the parent read end non-inheritable. If we didn't  // do this, the child would inherit these ends and we wouldn't  // be able to close them from our end. For full details,  // do a Google search on "Q190351".  HANDLE& rhStd = m_eType==INPUT ? m_hWrite : m_hRead;  _Jv_platform_close_on_exec (rhStd);}ChildProcessPipe::~ChildProcessPipe(){  // Close the parent end of the pipe. This  // destructor is called after the child process  // has been spawned.  CloseHandle(getChildHandle());}HANDLE ChildProcessPipe::getParentHandle(){  return m_eType==INPUT ? m_hWrite : m_hRead;}HANDLE ChildProcessPipe::getChildHandle(){  return m_eType==INPUT ? m_hRead : m_hWrite;}voidjava::lang::ConcreteProcess::startProcess (jstringArray progarray,                                           jstringArray envp,                                           java::io::File *dir){  using namespace java::io;  procHandle = (jint) INVALID_HANDLE_VALUE;  // Reconstruct the command line.  jstring *elts = elements (progarray);  int cmdLineLen = 0;  for (int i = 0; i < progarray->length; ++i)    cmdLineLen += (elts[i]->length() + 1);  LPTSTR cmdLine = (LPTSTR) _Jv_Malloc ((cmdLineLen + 1) * sizeof(TCHAR));  LPTSTR cmdLineCurPos = cmdLine;  for (int i = 0; i < progarray->length; ++i)    {      if (i > 0)        *cmdLineCurPos++ = _T(' ');              jint len = elts[i]->length();      JV_TEMP_STRING_WIN32(thiselt, elts[i]);      _tcscpy(cmdLineCurPos, thiselt);      cmdLineCurPos += len;    }  *cmdLineCurPos = _T('\0');  // Get the environment, if any.  LPTSTR env = NULL;  if (envp)    {      elts = elements (envp);      int envLen = 0;      for (int i = 0; i < envp->length; ++i)        envLen += (elts[i]->length() + 1);      env = (LPTSTR) _Jv_Malloc ((envLen + 1) * sizeof(TCHAR));      int j = 0;      for (int i = 0; i < envp->length; ++i)        {          jint len = elts[i]->length();                    JV_TEMP_STRING_WIN32(thiselt, elts[i]);          _tcscpy(env + j, thiselt);                    j += len;                    // Skip past the null terminator that _tcscpy just inserted.          j++;        }      *(env + j) = _T('\0');    }  // Get the working directory path, if specified.  JV_TEMP_STRING_WIN32 (wdir, dir ? dir->getPath () : 0);  errorStream = NULL;  inputStream = NULL;  outputStream = NULL;  java::lang::Throwable *exc = NULL;  try    {      // We create anonymous pipes to communicate with the child      // on each of standard streams.      ChildProcessPipe aChildStdIn(ChildProcessPipe::INPUT);      ChildProcessPipe aChildStdOut(ChildProcessPipe::OUTPUT);      ChildProcessPipe aChildStdErr(ChildProcessPipe::OUTPUT);      outputStream = new FileOutputStream (new FileChannelImpl (                           (jint) aChildStdIn.getParentHandle (),			   FileChannelImpl::WRITE));      inputStream = new FileInputStream (new FileChannelImpl (                           (jint) aChildStdOut.getParentHandle (),			   FileChannelImpl::READ));      errorStream = new FileInputStream (new FileChannelImpl (                           (jint) aChildStdErr.getParentHandle (),			   FileChannelImpl::READ));      // Now create the child process.      PROCESS_INFORMATION pi;      STARTUPINFO si;      ZeroMemory (&pi, sizeof (PROCESS_INFORMATION));      ZeroMemory (&si, sizeof (STARTUPINFO));      si.cb = sizeof (STARTUPINFO);      // Explicitly specify the handles to the standard streams.      si.dwFlags |= STARTF_USESTDHANDLES;      si.hStdInput = aChildStdIn.getChildHandle();      si.hStdOutput = aChildStdOut.getChildHandle();      si.hStdError = aChildStdErr.getChildHandle();      // Spawn the process. CREATE_NO_WINDOW only applies when      // starting a console application; it suppresses the      // creation of a console window. This flag is ignored on      // Win9X.            if (CreateProcess (NULL,                         cmdLine,                         NULL,                         NULL,                         1,                         CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,                         env,                         wdir,                         &si,                         &pi) == 0)        {          DWORD dwErrorCode = GetLastError ();          throw new IOException (            _Jv_WinStrError (_T("Error creating child process"), dwErrorCode));        }      procHandle = (jint ) pi.hProcess;      _Jv_Free (cmdLine);      if (env != NULL)        _Jv_Free (env);    }  catch (java::lang::Throwable *thrown)    {      cleanup ();      exc = thrown;    }  if (exc != NULL)    throw exc;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -