jdk/src/windows/native/java/lang/ProcessImpl_md.c
author xdono
Wed, 02 Jul 2008 12:55:45 -0700
changeset 715 f16baef3a20e
parent 48 dc5744ca15ea
child 5168 41e46b5d9b15
permissions -rw-r--r--
6719955: Update copyright year Summary: Update copyright year for files that have been modified in 2008 Reviewed-by: ohair, tbell
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 48
diff changeset
     2
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#include <assert.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#include "java_lang_ProcessImpl.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include "jni.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include "jvm.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "jni_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "io_util.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
#include <windows.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include <io.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
43
bfccfd41f0fc 6631966: (process) Raise Windows pipe buffer size an extra 24 bytes (win)
martin
parents: 2
diff changeset
    36
/* We try to make sure that we can read and write 4095 bytes (the
bfccfd41f0fc 6631966: (process) Raise Windows pipe buffer size an extra 24 bytes (win)
martin
parents: 2
diff changeset
    37
 * fixed limit on Linux) to the pipe on all operating systems without
bfccfd41f0fc 6631966: (process) Raise Windows pipe buffer size an extra 24 bytes (win)
martin
parents: 2
diff changeset
    38
 * deadlock.  Windows 2000 inexplicably appears to need an extra 24
bfccfd41f0fc 6631966: (process) Raise Windows pipe buffer size an extra 24 bytes (win)
martin
parents: 2
diff changeset
    39
 * bytes of slop to avoid deadlock.
bfccfd41f0fc 6631966: (process) Raise Windows pipe buffer size an extra 24 bytes (win)
martin
parents: 2
diff changeset
    40
 */
bfccfd41f0fc 6631966: (process) Raise Windows pipe buffer size an extra 24 bytes (win)
martin
parents: 2
diff changeset
    41
#define PIPE_SIZE (4096+24)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
char *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
extractExecutablePath(JNIEnv *env, char *source)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    char *p, *r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    /* If no spaces, then use entire thing */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    if ((p = strchr(source, ' ')) == NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
        return source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    /* If no quotes, or quotes after space, return up to space */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    if (((r = strchr(source, '"')) == NULL) || (r > p)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        *p = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
        return source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    /* Quotes before space, return up to space after next quotes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    p = strchr(r, '"');
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    if ((p = strchr(p, ' ')) == NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
        return source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    *p = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    return source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
DWORD
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
selectProcessFlag(JNIEnv *env, jstring cmd0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    char buf[MAX_PATH];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    DWORD newFlag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    char *exe, *p, *name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    unsigned char buffer[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    long headerLoc = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    int fd = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    exe = (char *)JNU_GetStringPlatformChars(env, cmd0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    exe = extractExecutablePath(env, exe);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    if (exe != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        if ((p = strchr(exe, '\\')) == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
            SearchPath(NULL, exe, ".exe", MAX_PATH, buf, &name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
            p = strrchr(exe, '\\');
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
            *p = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            p++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
            SearchPath(exe, p, ".exe", MAX_PATH, buf, &name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    fd = _open(buf, _O_RDONLY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    if (fd > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        _read(fd, buffer, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        if (buffer[0] == 'M' && buffer[1] == 'Z') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            _lseek(fd, 60L, SEEK_SET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            _read(fd, buffer, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            headerLoc = (long)buffer[1] << 8 | (long)buffer[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
            _lseek(fd, headerLoc, SEEK_SET);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            _read(fd, buffer, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            if (buffer[0] == 'P' && buffer[1] == 'E') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                newFlag = DETACHED_PROCESS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        _close(fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    JNU_ReleaseStringPlatformChars(env, cmd0, exe);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    return newFlag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
win32Error(JNIEnv *env, const char *functionName)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    static const char * const format = "%s error=%d, %s";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    static const char * const fallbackFormat = "%s failed, error=%d";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    char buf[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    char errmsg[sizeof(buf) + 100];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    const int errnum = GetLastError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    const int n = JVM_GetLastErrorString(buf, sizeof(buf));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    if (n > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        sprintf(errmsg, format, functionName, errnum, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        sprintf(errmsg, fallbackFormat, functionName, errnum);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    JNU_ThrowIOException(env, errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
closeSafely(HANDLE handle)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
{
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   128
    if (handle != INVALID_HANDLE_VALUE)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        CloseHandle(handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
JNIEXPORT jlong JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                                  jstring cmd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                                  jstring envBlock,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                                  jstring dir,
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   137
                                  jlongArray stdHandles,
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   138
                                  jboolean redirectErrorStream)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
{
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   140
    HANDLE inRead   = INVALID_HANDLE_VALUE;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   141
    HANDLE inWrite  = INVALID_HANDLE_VALUE;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   142
    HANDLE outRead  = INVALID_HANDLE_VALUE;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   143
    HANDLE outWrite = INVALID_HANDLE_VALUE;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   144
    HANDLE errRead  = INVALID_HANDLE_VALUE;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   145
    HANDLE errWrite = INVALID_HANDLE_VALUE;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    SECURITY_ATTRIBUTES sa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    PROCESS_INFORMATION pi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    STARTUPINFO si;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    LPTSTR  pcmd      = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    LPCTSTR pdir      = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    LPVOID  penvBlock = NULL;
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   152
    jlong  *handles   = NULL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    jlong ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    OSVERSIONINFO ver;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    jboolean onNT = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    DWORD processFlag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    ver.dwOSVersionInfoSize = sizeof(ver);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    GetVersionEx(&ver);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        onNT = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    assert(cmd != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    pcmd = (LPTSTR) JNU_GetStringPlatformChars(env, cmd, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    if (pcmd == NULL) goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    if (dir != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        pdir = (LPCTSTR) JNU_GetStringPlatformChars(env, dir, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        if (pdir == NULL) goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        pdir = (LPCTSTR) JVM_NativePath((char *)pdir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    if (envBlock != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        penvBlock = onNT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            ? (LPVOID) ((*env)->GetStringChars(env, envBlock, NULL))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            : (LPVOID) JNU_GetStringPlatformChars(env, envBlock, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        if (penvBlock == NULL) goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   180
    assert(stdHandles != NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   181
    handles = (*env)->GetLongArrayElements(env, stdHandles, NULL);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   182
    if (handles == NULL) goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   183
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    memset(&si, 0, sizeof(si));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    si.cb = sizeof(si);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    si.dwFlags = STARTF_USESTDHANDLES;
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   187
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   188
    sa.nLength = sizeof(sa);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   189
    sa.lpSecurityDescriptor = 0;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   190
    sa.bInheritHandle = TRUE;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   191
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   192
    if (handles[0] != (jlong) -1) {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   193
        si.hStdInput = (HANDLE) handles[0];
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   194
        handles[0] = (jlong) -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   195
    } else {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   196
        if (! CreatePipe(&inRead,  &inWrite,  &sa, PIPE_SIZE)) {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   197
            win32Error(env, "CreatePipe");
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   198
            goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   199
        }
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   200
        si.hStdInput = inRead;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   201
        SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   202
        handles[0] = (jlong) inWrite;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   203
    }
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   204
    SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, TRUE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   206
    if (handles[1] != (jlong) -1) {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   207
        si.hStdOutput = (HANDLE) handles[1];
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   208
        handles[1] = (jlong) -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   209
    } else {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   210
        if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   211
            win32Error(env, "CreatePipe");
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   212
            goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   213
        }
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   214
        si.hStdOutput = outWrite;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   215
        SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   216
        handles[1] = (jlong) outRead;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   217
    }
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   218
    SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, TRUE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   220
    if (redirectErrorStream) {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   221
        si.hStdError = si.hStdOutput;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   222
        handles[2] = (jlong) -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   223
    } else if (handles[2] != (jlong) -1) {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   224
        si.hStdError = (HANDLE) handles[2];
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   225
        handles[2] = (jlong) -1;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   226
    } else {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   227
        if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) {
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   228
            win32Error(env, "CreatePipe");
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   229
            goto Catch;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   230
        }
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   231
        si.hStdError = errWrite;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   232
        SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   233
        handles[2] = (jlong) errRead;
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   234
    }
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   235
    SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    if (onNT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        processFlag = selectProcessFlag(env, cmd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    /* Java and Windows are both pure Unicode systems at heart.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * Windows has both a legacy byte-based API and a 16-bit Unicode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * "W" API.  The Right Thing here is to call CreateProcessW, since
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     * that will allow all process-related information like command
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * line arguments to be passed properly to the child.  We don't do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * that currently, since we would first have to have "W" versions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * of JVM_NativePath and perhaps other functions.  In the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * meantime, we can call CreateProcess with the magic flag
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * CREATE_UNICODE_ENVIRONMENT, which passes only the environment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * in "W" mode.  We will fix this later. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    ret = CreateProcess(0,           /* executable name */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                        pcmd,        /* command line */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                        0,           /* process security attribute */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                        0,           /* thread security attribute */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                        TRUE,        /* inherits system handles */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                        processFlag, /* selected based on exe type */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                        penvBlock,   /* environment block */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                        pdir,        /* change to the new current directory */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                        &si,         /* (in)  startup information */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                        &pi);        /* (out) process information */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    if (!ret) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        win32Error(env, "CreateProcess");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        goto Catch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    CloseHandle(pi.hThread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    ret = (jlong)pi.hProcess;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
 Finally:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    /* Always clean up the child's side of the pipes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    closeSafely(inRead);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    closeSafely(outWrite);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    closeSafely(errWrite);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    if (pcmd != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        JNU_ReleaseStringPlatformChars(env, cmd, (char *) pcmd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    if (pdir != NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        JNU_ReleaseStringPlatformChars(env, dir, (char *) pdir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    if (penvBlock != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        if (onNT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            (*env)->ReleaseStringChars(env, envBlock, (jchar *) penvBlock);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            JNU_ReleaseStringPlatformChars(env, dir, (char *) penvBlock);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    }
48
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   288
    if (handles != NULL)
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   289
        (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);
dc5744ca15ea 4960438: (process) Need IO redirection API for subprocesses
martin
parents: 43
diff changeset
   290
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
 Catch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    /* Clean up the parent's side of the pipes in case of failure only */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    closeSafely(inWrite);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    closeSafely(outRead);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    closeSafely(errRead);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    goto Finally;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
JNIEXPORT jint JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
Java_java_lang_ProcessImpl_getExitCodeProcess(JNIEnv *env, jclass ignored, jlong handle)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    DWORD exit_code;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    if (GetExitCodeProcess((HANDLE) handle, &exit_code) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        win32Error(env, "GetExitCodeProcess");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    return exit_code;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
JNIEXPORT jint JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
Java_java_lang_ProcessImpl_getStillActive(JNIEnv *env, jclass ignored)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    return STILL_ACTIVE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
JNIEXPORT void JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
Java_java_lang_ProcessImpl_waitForInterruptibly(JNIEnv *env, jclass ignored, jlong handle)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    HANDLE events[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    events[0] = (HANDLE) handle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    events[1] = JVM_GetThreadInterruptEvent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    if (WaitForMultipleObjects(sizeof(events)/sizeof(events[0]), events,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                               FALSE,    /* Wait for ANY event */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                               INFINITE) /* Wait forever */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        == WAIT_FAILED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        win32Error(env, "WaitForMultipleObjects");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
JNIEXPORT void JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
Java_java_lang_ProcessImpl_terminateProcess(JNIEnv *env, jclass ignored, jlong handle)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    TerminateProcess((HANDLE) handle, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
JNIEXPORT jboolean JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
Java_java_lang_ProcessImpl_closeHandle(JNIEnv *env, jclass ignored, jlong handle)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    return CloseHandle((HANDLE) handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
}