src/windows/native/java/lang/ProcessImpl_md.c

Print this page




 128     if (handle != INVALID_HANDLE_VALUE)
 129         CloseHandle(handle);
 130 }
 131 
 132 JNIEXPORT jlong JNICALL
 133 Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored,
 134                                   jstring cmd,
 135                                   jstring envBlock,
 136                                   jstring dir,
 137                                   jlongArray stdHandles,
 138                                   jboolean redirectErrorStream)
 139 {
 140     HANDLE inRead   = INVALID_HANDLE_VALUE;
 141     HANDLE inWrite  = INVALID_HANDLE_VALUE;
 142     HANDLE outRead  = INVALID_HANDLE_VALUE;
 143     HANDLE outWrite = INVALID_HANDLE_VALUE;
 144     HANDLE errRead  = INVALID_HANDLE_VALUE;
 145     HANDLE errWrite = INVALID_HANDLE_VALUE;
 146     SECURITY_ATTRIBUTES sa;
 147     PROCESS_INFORMATION pi;
 148     STARTUPINFO si;
 149     LPTSTR  pcmd      = NULL;
 150     LPCTSTR pdir      = NULL;
 151     LPVOID  penvBlock = NULL;
 152     jlong  *handles   = NULL;
 153     jlong ret = 0;
 154     OSVERSIONINFO ver;
 155     jboolean onNT = JNI_FALSE;
 156     DWORD processFlag;
 157 
 158     ver.dwOSVersionInfoSize = sizeof(ver);
 159     GetVersionEx(&ver);
 160     if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
 161         onNT = JNI_TRUE;
 162 
 163     assert(cmd != NULL);
 164     pcmd = (LPTSTR) JNU_GetStringPlatformChars(env, cmd, NULL);
 165     if (pcmd == NULL) goto Catch;
 166 
 167     if (dir != 0) {
 168         pdir = (LPCTSTR) JNU_GetStringPlatformChars(env, dir, NULL);
 169         if (pdir == NULL) goto Catch;
 170         pdir = (LPCTSTR) JVM_NativePath((char *)pdir);
 171     }
 172 
 173     if (envBlock != NULL) {
 174         penvBlock = onNT
 175             ? (LPVOID) ((*env)->GetStringChars(env, envBlock, NULL))
 176             : (LPVOID) JNU_GetStringPlatformChars(env, envBlock, NULL);
 177         if (penvBlock == NULL) goto Catch;
 178     }
 179 
 180     assert(stdHandles != NULL);
 181     handles = (*env)->GetLongArrayElements(env, stdHandles, NULL);
 182     if (handles == NULL) goto Catch;
 183 
 184     memset(&si, 0, sizeof(si));
 185     si.cb = sizeof(si);
 186     si.dwFlags = STARTF_USESTDHANDLES;
 187 
 188     sa.nLength = sizeof(sa);
 189     sa.lpSecurityDescriptor = 0;
 190     sa.bInheritHandle = TRUE;
 191 
 192     if (handles[0] != (jlong) -1) {
 193         si.hStdInput = (HANDLE) handles[0];
 194         handles[0] = (jlong) -1;
 195     } else {
 196         if (! CreatePipe(&inRead,  &inWrite,  &sa, PIPE_SIZE)) {
 197             win32Error(env, "CreatePipe");
 198             goto Catch;
 199         }


 222         handles[2] = (jlong) -1;
 223     } else if (handles[2] != (jlong) -1) {
 224         si.hStdError = (HANDLE) handles[2];
 225         handles[2] = (jlong) -1;
 226     } else {
 227         if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) {
 228             win32Error(env, "CreatePipe");
 229             goto Catch;
 230         }
 231         si.hStdError = errWrite;
 232         SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE);
 233         handles[2] = (jlong) errRead;
 234     }
 235     SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE);
 236 
 237     if (onNT)
 238         processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
 239     else
 240         processFlag = selectProcessFlag(env, cmd);
 241 
 242     /* Java and Windows are both pure Unicode systems at heart.
 243      * Windows has both a legacy byte-based API and a 16-bit Unicode
 244      * "W" API.  The Right Thing here is to call CreateProcessW, since
 245      * that will allow all process-related information like command
 246      * line arguments to be passed properly to the child.  We don't do
 247      * that currently, since we would first have to have "W" versions
 248      * of JVM_NativePath and perhaps other functions.  In the
 249      * meantime, we can call CreateProcess with the magic flag
 250      * CREATE_UNICODE_ENVIRONMENT, which passes only the environment
 251      * in "W" mode.  We will fix this later. */
 252 
 253     ret = CreateProcess(0,           /* executable name */
 254                         pcmd,        /* command line */
 255                         0,           /* process security attribute */
 256                         0,           /* thread security attribute */
 257                         TRUE,        /* inherits system handles */
 258                         processFlag, /* selected based on exe type */
 259                         penvBlock,   /* environment block */
 260                         pdir,        /* change to the new current directory */
 261                         &si,         /* (in)  startup information */
 262                         &pi);        /* (out) process information */
 263 
 264     if (!ret) {
 265         win32Error(env, "CreateProcess");
 266         goto Catch;
 267     }
 268 
 269     CloseHandle(pi.hThread);
 270     ret = (jlong)pi.hProcess;
 271 
 272  Finally:
 273     /* Always clean up the child's side of the pipes */
 274     closeSafely(inRead);
 275     closeSafely(outWrite);
 276     closeSafely(errWrite);
 277 
 278     if (pcmd != NULL)
 279         JNU_ReleaseStringPlatformChars(env, cmd, (char *) pcmd);
 280     if (pdir != NULL)
 281         JNU_ReleaseStringPlatformChars(env, dir, (char *) pdir);
 282     if (penvBlock != NULL) {
 283         if (onNT)
 284             (*env)->ReleaseStringChars(env, envBlock, (jchar *) penvBlock);
 285         else
 286             JNU_ReleaseStringPlatformChars(env, dir, (char *) penvBlock);
 287     }
 288     if (handles != NULL)
 289         (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);
 290 
 291     return ret;
 292 
 293  Catch:
 294     /* Clean up the parent's side of the pipes in case of failure only */
 295     closeSafely(inWrite);
 296     closeSafely(outRead);
 297     closeSafely(errRead);
 298     goto Finally;
 299 }
 300 
 301 JNIEXPORT jint JNICALL
 302 Java_java_lang_ProcessImpl_getExitCodeProcess(JNIEnv *env, jclass ignored, jlong handle)
 303 {
 304     DWORD exit_code;
 305     if (GetExitCodeProcess((HANDLE) handle, &exit_code) == 0)
 306         win32Error(env, "GetExitCodeProcess");
 307     return exit_code;
 308 }
 309 
 310 JNIEXPORT jint JNICALL




 128     if (handle != INVALID_HANDLE_VALUE)
 129         CloseHandle(handle);
 130 }
 131 
 132 JNIEXPORT jlong JNICALL
 133 Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored,
 134                                   jstring cmd,
 135                                   jstring envBlock,
 136                                   jstring dir,
 137                                   jlongArray stdHandles,
 138                                   jboolean redirectErrorStream)
 139 {
 140     HANDLE inRead   = INVALID_HANDLE_VALUE;
 141     HANDLE inWrite  = INVALID_HANDLE_VALUE;
 142     HANDLE outRead  = INVALID_HANDLE_VALUE;
 143     HANDLE outWrite = INVALID_HANDLE_VALUE;
 144     HANDLE errRead  = INVALID_HANDLE_VALUE;
 145     HANDLE errWrite = INVALID_HANDLE_VALUE;
 146     SECURITY_ATTRIBUTES sa;
 147     PROCESS_INFORMATION pi;
 148     STARTUPINFOW si;
 149     const jchar*  pcmd = NULL;
 150     const jchar*  pdir = NULL;
 151     const jchar*  penvBlock = NULL;
 152     jlong  *handles = NULL;
 153     jlong ret = 0;
 154     OSVERSIONINFO ver;
 155     jboolean onNT = JNI_FALSE;
 156     DWORD processFlag;
 157 
 158     ver.dwOSVersionInfoSize = sizeof(ver);
 159     GetVersionEx(&ver);
 160     if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
 161         onNT = JNI_TRUE;
 162 
 163     assert(cmd != NULL);
 164     pcmd = (*env)->GetStringChars(env, cmd, NULL);
 165     if (pcmd == NULL) goto Catch;
 166 
 167     if (dir != 0) {
 168         pdir = (*env)->GetStringChars(env, dir, NULL);
 169         if (pdir == NULL) goto Catch;

 170     }

 171     if (envBlock != NULL) {
 172         penvBlock = ((*env)->GetStringChars(env, envBlock, NULL));


 173         if (penvBlock == NULL) goto Catch;
 174     }

 175     assert(stdHandles != NULL);
 176     handles = (*env)->GetLongArrayElements(env, stdHandles, NULL);
 177     if (handles == NULL) goto Catch;
 178 
 179     memset(&si, 0, sizeof(si));
 180     si.cb = sizeof(si);
 181     si.dwFlags = STARTF_USESTDHANDLES;
 182 
 183     sa.nLength = sizeof(sa);
 184     sa.lpSecurityDescriptor = 0;
 185     sa.bInheritHandle = TRUE;
 186 
 187     if (handles[0] != (jlong) -1) {
 188         si.hStdInput = (HANDLE) handles[0];
 189         handles[0] = (jlong) -1;
 190     } else {
 191         if (! CreatePipe(&inRead,  &inWrite,  &sa, PIPE_SIZE)) {
 192             win32Error(env, "CreatePipe");
 193             goto Catch;
 194         }


 217         handles[2] = (jlong) -1;
 218     } else if (handles[2] != (jlong) -1) {
 219         si.hStdError = (HANDLE) handles[2];
 220         handles[2] = (jlong) -1;
 221     } else {
 222         if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) {
 223             win32Error(env, "CreatePipe");
 224             goto Catch;
 225         }
 226         si.hStdError = errWrite;
 227         SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE);
 228         handles[2] = (jlong) errRead;
 229     }
 230     SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE);
 231 
 232     if (onNT)
 233         processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
 234     else
 235         processFlag = selectProcessFlag(env, cmd);
 236 
 237     ret = CreateProcessW(0,                /* executable name */
 238                          (LPWSTR)pcmd,     /* command line */











 239                          0,                /* process security attribute */
 240                          0,                /* thread security attribute */
 241                          TRUE,             /* inherits system handles */
 242                          processFlag,      /* selected based on exe type */
 243                          (LPVOID)penvBlock,/* environment block */
 244                          (LPCWSTR)pdir,    /* change to the new current directory */
 245                          &si,              /* (in)  startup information */
 246                          &pi);             /* (out) process information */
 247 
 248     if (!ret) {
 249         win32Error(env, "CreateProcess");
 250         goto Catch;
 251     }
 252 
 253     CloseHandle(pi.hThread);
 254     ret = (jlong)pi.hProcess;
 255 
 256  Finally:
 257     /* Always clean up the child's side of the pipes */
 258     closeSafely(inRead);
 259     closeSafely(outWrite);
 260     closeSafely(errWrite);
 261 
 262     if (pcmd != NULL)
 263         (*env)->ReleaseStringChars(env, cmd, pcmd);
 264     if (pdir != NULL)
 265         (*env)->ReleaseStringChars(env, dir, pdir);
 266     if (penvBlock != NULL)
 267         (*env)->ReleaseStringChars(env, envBlock, penvBlock);




 268     if (handles != NULL)
 269         (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0);

 270     return ret;
 271 
 272  Catch:
 273     /* Clean up the parent's side of the pipes in case of failure only */
 274     closeSafely(inWrite);
 275     closeSafely(outRead);
 276     closeSafely(errRead);
 277     goto Finally;
 278 }
 279 
 280 JNIEXPORT jint JNICALL
 281 Java_java_lang_ProcessImpl_getExitCodeProcess(JNIEnv *env, jclass ignored, jlong handle)
 282 {
 283     DWORD exit_code;
 284     if (GetExitCodeProcess((HANDLE) handle, &exit_code) == 0)
 285         win32Error(env, "GetExitCodeProcess");
 286     return exit_code;
 287 }
 288 
 289 JNIEXPORT jint JNICALL