WITH_PLATFORM_STRING(env, pathname, path) { char canonicalPath[JVM_MAXPATHLEN]; if (canonicalize(JVM_NativePath((char *)path), canonicalPath, JVM_MAXPATHLEN) < 0) { JNU_ThrowIOExceptionWithLastError(env, "Bad pathname"); } else { rv = JNU_NewStringPlatform(env, canonicalPath); } } END_PLATFORM_STRING(env, path);
jzfile * ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified) { static char errbuf[256]; char buf[PATH_MAX]; jzfile *zip; if (InitializeZip()) { return NULL; } /* Clear zip error message */ if (pmsg != 0) { *pmsg = NULL; } if (strlen(name) >= PATH_MAX) { if (pmsg) { *pmsg = "zip file name too long"; } return NULL; } strcpy(buf, name); JVM_NativePath(buf); name = buf; MLOCK(zfiles_lock); for (zip = zfiles; zip != NULL; zip = zip->next) { if (strcmp(name, zip->name) == 0 && (zip->lastModified == lastModified || zip->lastModified == 0) && zip->refs < MAXREFS) { zip->refs++; break; } } MUNLOCK(zfiles_lock); return zip; }
JNIEXPORT jlong JNICALL Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, jstring cmd, jstring envBlock, jstring dir, jlongArray stdHandles, jboolean redirectErrorStream) { HANDLE inRead = INVALID_HANDLE_VALUE; HANDLE inWrite = INVALID_HANDLE_VALUE; HANDLE outRead = INVALID_HANDLE_VALUE; HANDLE outWrite = INVALID_HANDLE_VALUE; HANDLE errRead = INVALID_HANDLE_VALUE; HANDLE errWrite = INVALID_HANDLE_VALUE; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; LPTSTR pcmd = NULL; LPCTSTR pdir = NULL; LPVOID penvBlock = NULL; jlong *handles = NULL; jlong ret = 0; OSVERSIONINFO ver; jboolean onNT = JNI_FALSE; DWORD processFlag; ver.dwOSVersionInfoSize = sizeof(ver); GetVersionEx(&ver); if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) onNT = JNI_TRUE; assert(cmd != NULL); pcmd = (LPTSTR) JNU_GetStringPlatformChars(env, cmd, NULL); if (pcmd == NULL) goto Catch; if (dir != 0) { pdir = (LPCTSTR) JNU_GetStringPlatformChars(env, dir, NULL); if (pdir == NULL) goto Catch; pdir = (LPCTSTR) JVM_NativePath((char *)pdir); } if (envBlock != NULL) { penvBlock = onNT ? (LPVOID) ((*env)->GetStringChars(env, envBlock, NULL)) : (LPVOID) JNU_GetStringPlatformChars(env, envBlock, NULL); if (penvBlock == NULL) goto Catch; } assert(stdHandles != NULL); handles = (*env)->GetLongArrayElements(env, stdHandles, NULL); if (handles == NULL) goto Catch; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = 0; sa.bInheritHandle = TRUE; if (handles[0] != (jlong) -1) { si.hStdInput = (HANDLE) handles[0]; handles[0] = (jlong) -1; } else { if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) { win32Error(env, "CreatePipe"); goto Catch; } si.hStdInput = inRead; SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE); handles[0] = (jlong) inWrite; } SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, TRUE); if (handles[1] != (jlong) -1) { si.hStdOutput = (HANDLE) handles[1]; handles[1] = (jlong) -1; } else { if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) { win32Error(env, "CreatePipe"); goto Catch; } si.hStdOutput = outWrite; SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE); handles[1] = (jlong) outRead; } SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, TRUE); if (redirectErrorStream) { si.hStdError = si.hStdOutput; handles[2] = (jlong) -1; } else if (handles[2] != (jlong) -1) { si.hStdError = (HANDLE) handles[2]; handles[2] = (jlong) -1; } else { if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) { win32Error(env, "CreatePipe"); goto Catch; } si.hStdError = errWrite; SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE); handles[2] = (jlong) errRead; } SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE); if (onNT) processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; else processFlag = selectProcessFlag(env, cmd); /* Java and Windows are both pure Unicode systems at heart. * Windows has both a legacy byte-based API and a 16-bit Unicode * "W" API. The Right Thing here is to call CreateProcessW, since * that will allow all process-related information like command * line arguments to be passed properly to the child. We don't do * that currently, since we would first have to have "W" versions * of JVM_NativePath and perhaps other functions. In the * meantime, we can call CreateProcess with the magic flag * CREATE_UNICODE_ENVIRONMENT, which passes only the environment * in "W" mode. We will fix this later. */ ret = CreateProcess(0, /* executable name */ pcmd, /* command line */ 0, /* process security attribute */ 0, /* thread security attribute */ TRUE, /* inherits system handles */ processFlag, /* selected based on exe type */ penvBlock, /* environment block */ pdir, /* change to the new current directory */ &si, /* (in) startup information */ &pi); /* (out) process information */ if (!ret) { win32Error(env, "CreateProcess"); goto Catch; } CloseHandle(pi.hThread); ret = (jlong)pi.hProcess; Finally: /* Always clean up the child's side of the pipes */ closeSafely(inRead); closeSafely(outWrite); closeSafely(errWrite); if (pcmd != NULL) JNU_ReleaseStringPlatformChars(env, cmd, (char *) pcmd); if (pdir != NULL) JNU_ReleaseStringPlatformChars(env, dir, (char *) pdir); if (penvBlock != NULL) { if (onNT) (*env)->ReleaseStringChars(env, envBlock, (jchar *) penvBlock); else JNU_ReleaseStringPlatformChars(env, dir, (char *) penvBlock); } if (handles != NULL) (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0); return ret; Catch: /* Clean up the parent's side of the pipes in case of failure only */ closeSafely(inWrite); closeSafely(outRead); closeSafely(errRead); goto Finally; }