Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: src/trusted/platform/win/nacl_process.c

Issue 10832400: Process abstraction layer for NaCl Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/platform/win/nacl_process.c
diff --git a/src/trusted/platform/win/nacl_process.c b/src/trusted/platform/win/nacl_process.c
new file mode 100644
index 0000000000000000000000000000000000000000..11893570be282a1fcd0c55e5744eec584025ec0f
--- /dev/null
+++ b/src/trusted/platform/win/nacl_process.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2012 The Native Client Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "native_client/src/trusted/platform/nacl_process.h"
+
+#include <fcntl.h>
+#include <io.h>
+#include <windows.h>
+#include <userenv.h>
+#include <psapi.h>
+
+#include "native_client/src/include/portability.h"
+#include "native_client/src/include/portability_string.h"
+
+#include "native_client/src/shared/platform/nacl_check.h"
+#include "native_client/src/shared/platform/nacl_log.h"
+#include "native_client/src/shared/platform/nacl_sync.h"
+#include "native_client/src/shared/platform/nacl_sync_checked.h"
+
+#ifndef STATUS_SUCCESS
+#define STATUS_SUCCESS ((NTSTATUS) 0)
+#endif
+#ifndef STATUS_WAIT_1
+#define STATUS_WAIT_1 ((NTSTATUS) 0x00000001)
+#endif
+#ifndef STATUS_DEBUGGER_INACTIVE
+#define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354)
+#endif
+#ifndef STATUS_CONTROL_C_EXIT
+#define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013A)
+#endif
+#ifndef DBG_TERMINATE_PROCESS
+#define DBG_TERMINATE_PROCESS ((NTSTATUS) 0x40010004)
+#endif
+
+int NaClProcessLaunch(struct NaClProcess *npp,
+ char *cmd,
+ char *env,
+ int flags) {
+ STARTUPINFO startup_info;
+ PROCESS_INFORMATION process_info;
+ DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT;
+ BOOL inherit;
+
+ NaClLog(2,
+ ("NaClProcessLaunch(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR
+ ", 0x%08"NACL_PRIxPTR", 0x%x)\n"),
+ (uintptr_t) npp, (uintptr_t) cmd, (uintptr_t) env, flags);
+
+ CHECK(npp != NULL);
+
+ ZeroMemory(&startup_info, sizeof startup_info);
+ startup_info.cb = sizeof startup_info;
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+
+ if ((flags & NACL_PROCESS_LAUNCH_CLOSE_FDS) != 0) {
+ inherit = FALSE;
+ } else {
+ inherit = TRUE;
+ }
+
+ if (0 != (flags & NACL_PROCESS_LAUNCH_NEW_GROUP)) {
+ creation_flags |= CREATE_NEW_PROCESS_GROUP;
+ }
+
+ if (!CreateProcess(/* lpApplicationName= */ NULL,
+ cmd,
+ /* lpProcessAttributes= */ NULL,
+ /* lpThreadAttributes= */ NULL,
+ inherit,
+ creation_flags,
+ env,
+ /* lpCurrentDirectory= */NULL,
+ &startup_info,
+ &process_info)) {
+ NaClLog(LOG_ERROR,
+ "NaClProcessSpawn: CreateProcess failed, error %d\n",
+ GetLastError());
+ return 0;
+ }
+
+ /* TODO(phosek): might we ever need this handle? */
+ DCHECK(CloseHandle(process_info.hThread));
+
+ if (npp != NULL) {
+ npp->handle = process_info.hProcess;
+ }
+
+ return 1;
+}
+
+int NaClProcessKill(struct NaClProcess *npp, int exit_code, int wait) {
+ BOOL retval;
+
+ NaClLog(2,
+ "NaClProcessKill(0x%08"NACL_PRIxPTR", %d, %d)\n",
+ (uintptr_t) npp, exit_code, wait);
+
+ CHECK(npp != NULL);
+
+ retval = TerminateProcess(npp->handle, exit_code);
+ if (FALSE == retval) {
+ NaClLog(LOG_ERROR,
+ "NaClProcessKill: unable to terminate process, error %d\n",
+ GetLastError());
+ goto done;
+ }
+
+ if (wait != 0) {
+ /* The process may not end immediately due to pending I/O */
+ if (WAIT_OBJECT_0 != WaitForSingleObject(npp->handle, 60 * 1000)) {
+ NaClLog(LOG_ERROR,
+ "NaClProcessKill: waiting for process failed, error %d\n",
+ GetLastError());
+ }
+ }
+
+ done:
+ return retval != FALSE;
+}
+
+int NaClProcessGetStatus(
+ struct NaClProcess *npp,
+ int *status) {
+ DWORD exit_code = 0;
+
+ NaClLog(2,
+ ("NaClProcessGetStatus(0x%08"NACL_PRIxPTR
+ ", 0x%08"NACL_PRIxPTR")\n"),
+ (uintptr_t) npp, (uintptr_t) status);
+
+ CHECK(npp != NULL);
+
+ NaClLog(4,
+ "NaClProcessGetStatus: checking status of process %d\n",
+ (int) npp->handle);
+
+ if (!GetExitCodeProcess(npp->handle, &exit_code)) {
+ NaClLog(LOG_ERROR,
+ ("NaClProcessGetStatus: GetExitCodeProcess"
+ "returned error %d\n"),
+ GetLastError());
+ return 0;
+ }
+
+ if (STILL_ACTIVE == exit_code) {
+ DWORD wait_result = WaitForSingleObject(npp->handle, 0);
+ if (WAIT_TIMEOUT == wait_result) {
+ *status = NACL_PROCESS_STATUS_STILL_RUNNING;
+ return 1;
+ }
+
+ CHECK(WAIT_OBJECT_0 == wait_result);
+ /* The process used 0x103 (STILL_ACTIVE) as exit code. */
+ *status = NACL_PROCESS_STATUS_ABNORMAL_EXIT;
+ return 1;
+ }
+
+ switch (exit_code) {
+ case STATUS_SUCCESS: /* Normal termination */
+ *status = NACL_PROCESS_STATUS_NORMAL_EXIT;
+ break;
+ case STATUS_DEBUGGER_INACTIVE: /* Debugger inactive */
+ case STATUS_CONTROL_C_EXIT: /* Keyboard interrupt */
+ case DBG_TERMINATE_PROCESS: /* Debugger terminated */
+ case STATUS_WAIT_1: /* Task manager killed */
+ *status = NACL_PROCESS_STATUS_KILLED;
+ break;
+ default:
+ /* All other exit codes indicate crashes */
+ *status = NACL_PROCESS_STATUS_CRASHED;
+ break;
+ }
+
+ return 1;
+}
+
+int NaClProcessWaitForExitCode(struct NaClProcess *npp,
+ int *exit_code) {
+ DWORD tmp_exit_code;
+
+ NaClLog(2,
+ ("NaClProcessWaitForExitCode(0x%08"NACL_PRIxPTR
+ ", 0x%08"NACL_PRIxPTR")\n"),
+ (uintptr_t) npp, (uintptr_t) exit_code);
+
+ CHECK(npp != NULL);
+
+ if (WAIT_OBJECT_0 != WaitForSingleObject(npp->handle, INFINITE)) {
+ return 0;
+ }
+
+ if (!GetExitCodeProcess(npp->handle, &tmp_exit_code)) {
+ return 0;
+ }
+
+ *exit_code = tmp_exit_code;
+ return 1;
+}

Powered by Google App Engine
This is Rietveld 408576698