// 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 the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#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;

void
java::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;
    }
}

void
java::lang::ConcreteProcess::destroy (void)
{
  if (! hasExited ())
    {
      // Kill it forcibly and assign an (arbitrary) exit code of 0.
      TerminateProcess ((HANDLE) procHandle, 0);
      exitCode = 0;

      cleanup ();
    }
}

jboolean
java::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;
}

jint
java::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;
}

void
java::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. Unconditionally
  // create a UNICODE environment, even on ANSI
  // builds.
  LPWSTR env = NULL;
  if (envp)
    {
      elts = elements (envp);

      int envLen = 0;
      for (int i = 0; i < envp->length; ++i)
        envLen += (elts[i]->length() + 1);

      env = (LPWSTR) _Jv_Malloc ((envLen + 1) * sizeof(WCHAR));

      int j = 0;
      for (int i = 0; i < envp->length; ++i)
        {
          jstring elt = elts[i];
          jint len = elt->length();
          
          wcsncpy(env + j, (LPCWSTR) JvGetStringChars(elt), len);
          
          j += len;
          
          // Insert the null terminator and skip past it.
          env[j++] = 0;
        }
      *(env + j) = 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;
}
