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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include "native_client/src/trusted/platform/nacl_process.h"
8
9 #include <fcntl.h>
10 #include <io.h>
11 #include <windows.h>
12 #include <userenv.h>
13 #include <psapi.h>
14
15 #include "native_client/src/include/portability.h"
16 #include "native_client/src/include/portability_string.h"
17
18 #include "native_client/src/shared/platform/nacl_check.h"
19 #include "native_client/src/shared/platform/nacl_log.h"
20 #include "native_client/src/shared/platform/nacl_sync.h"
21 #include "native_client/src/shared/platform/nacl_sync_checked.h"
22
23 #ifndef STATUS_SUCCESS
24 #define STATUS_SUCCESS ((NTSTATUS) 0)
25 #endif
26 #ifndef STATUS_WAIT_1
27 #define STATUS_WAIT_1 ((NTSTATUS) 0x00000001)
28 #endif
29 #ifndef STATUS_DEBUGGER_INACTIVE
30 #define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354)
31 #endif
32 #ifndef STATUS_CONTROL_C_EXIT
33 #define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013A)
34 #endif
35 #ifndef DBG_TERMINATE_PROCESS
36 #define DBG_TERMINATE_PROCESS ((NTSTATUS) 0x40010004)
37 #endif
38
39 int NaClProcessLaunch(struct NaClProcess *npp,
40 char *cmd,
41 char *env,
42 int flags) {
43 STARTUPINFO startup_info;
44 PROCESS_INFORMATION process_info;
45 DWORD creation_flags = CREATE_UNICODE_ENVIRONMENT;
46 BOOL inherit;
47
48 NaClLog(2,
49 ("NaClProcessLaunch(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR
50 ", 0x%08"NACL_PRIxPTR", 0x%x)\n"),
51 (uintptr_t) npp, (uintptr_t) cmd, (uintptr_t) env, flags);
52
53 CHECK(npp != NULL);
54
55 ZeroMemory(&startup_info, sizeof startup_info);
56 startup_info.cb = sizeof startup_info;
57 startup_info.dwFlags = STARTF_USESTDHANDLES;
58
59 if ((flags & NACL_PROCESS_LAUNCH_CLOSE_FDS) != 0) {
60 inherit = FALSE;
61 } else {
62 inherit = TRUE;
63 }
64
65 if (0 != (flags & NACL_PROCESS_LAUNCH_NEW_GROUP)) {
66 creation_flags |= CREATE_NEW_PROCESS_GROUP;
67 }
68
69 if (!CreateProcess(/* lpApplicationName= */ NULL,
70 cmd,
71 /* lpProcessAttributes= */ NULL,
72 /* lpThreadAttributes= */ NULL,
73 inherit,
74 creation_flags,
75 env,
76 /* lpCurrentDirectory= */NULL,
77 &startup_info,
78 &process_info)) {
79 NaClLog(LOG_ERROR,
80 "NaClProcessSpawn: CreateProcess failed, error %d\n",
81 GetLastError());
82 return 0;
83 }
84
85 /* TODO(phosek): might we ever need this handle? */
86 DCHECK(CloseHandle(process_info.hThread));
87
88 if (npp != NULL) {
89 npp->handle = process_info.hProcess;
90 }
91
92 return 1;
93 }
94
95 int NaClProcessKill(struct NaClProcess *npp, int exit_code, int wait) {
96 BOOL retval;
97
98 NaClLog(2,
99 "NaClProcessKill(0x%08"NACL_PRIxPTR", %d, %d)\n",
100 (uintptr_t) npp, exit_code, wait);
101
102 CHECK(npp != NULL);
103
104 retval = TerminateProcess(npp->handle, exit_code);
105 if (FALSE == retval) {
106 NaClLog(LOG_ERROR,
107 "NaClProcessKill: unable to terminate process, error %d\n",
108 GetLastError());
109 goto done;
110 }
111
112 if (wait != 0) {
113 /* The process may not end immediately due to pending I/O */
114 if (WAIT_OBJECT_0 != WaitForSingleObject(npp->handle, 60 * 1000)) {
115 NaClLog(LOG_ERROR,
116 "NaClProcessKill: waiting for process failed, error %d\n",
117 GetLastError());
118 }
119 }
120
121 done:
122 return retval != FALSE;
123 }
124
125 int NaClProcessGetStatus(
126 struct NaClProcess *npp,
127 int *status) {
128 DWORD exit_code = 0;
129
130 NaClLog(2,
131 ("NaClProcessGetStatus(0x%08"NACL_PRIxPTR
132 ", 0x%08"NACL_PRIxPTR")\n"),
133 (uintptr_t) npp, (uintptr_t) status);
134
135 CHECK(npp != NULL);
136
137 NaClLog(4,
138 "NaClProcessGetStatus: checking status of process %d\n",
139 (int) npp->handle);
140
141 if (!GetExitCodeProcess(npp->handle, &exit_code)) {
142 NaClLog(LOG_ERROR,
143 ("NaClProcessGetStatus: GetExitCodeProcess"
144 "returned error %d\n"),
145 GetLastError());
146 return 0;
147 }
148
149 if (STILL_ACTIVE == exit_code) {
150 DWORD wait_result = WaitForSingleObject(npp->handle, 0);
151 if (WAIT_TIMEOUT == wait_result) {
152 *status = NACL_PROCESS_STATUS_STILL_RUNNING;
153 return 1;
154 }
155
156 CHECK(WAIT_OBJECT_0 == wait_result);
157 /* The process used 0x103 (STILL_ACTIVE) as exit code. */
158 *status = NACL_PROCESS_STATUS_ABNORMAL_EXIT;
159 return 1;
160 }
161
162 switch (exit_code) {
163 case STATUS_SUCCESS: /* Normal termination */
164 *status = NACL_PROCESS_STATUS_NORMAL_EXIT;
165 break;
166 case STATUS_DEBUGGER_INACTIVE: /* Debugger inactive */
167 case STATUS_CONTROL_C_EXIT: /* Keyboard interrupt */
168 case DBG_TERMINATE_PROCESS: /* Debugger terminated */
169 case STATUS_WAIT_1: /* Task manager killed */
170 *status = NACL_PROCESS_STATUS_KILLED;
171 break;
172 default:
173 /* All other exit codes indicate crashes */
174 *status = NACL_PROCESS_STATUS_CRASHED;
175 break;
176 }
177
178 return 1;
179 }
180
181 int NaClProcessWaitForExitCode(struct NaClProcess *npp,
182 int *exit_code) {
183 DWORD tmp_exit_code;
184
185 NaClLog(2,
186 ("NaClProcessWaitForExitCode(0x%08"NACL_PRIxPTR
187 ", 0x%08"NACL_PRIxPTR")\n"),
188 (uintptr_t) npp, (uintptr_t) exit_code);
189
190 CHECK(npp != NULL);
191
192 if (WAIT_OBJECT_0 != WaitForSingleObject(npp->handle, INFINITE)) {
193 return 0;
194 }
195
196 if (!GetExitCodeProcess(npp->handle, &tmp_exit_code)) {
197 return 0;
198 }
199
200 *exit_code = tmp_exit_code;
201 return 1;
202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698