1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "osProcess.h"
17 #include <windows.h>
18 #include <string>
19 #include <stdlib.h>
20 #include <psapi.h>
21
22 namespace osUtils {
23
24 childProcess *
create(const char * p_cmdLine,const char * p_startdir)25 childProcess::create(const char *p_cmdLine, const char *p_startdir)
26 {
27 childProcess *child = new childProcess();
28 if (!child) {
29 return NULL;
30 }
31
32 STARTUPINFOA si;
33 ZeroMemory(&si, sizeof(si));
34
35 ZeroMemory(&child->m_proc, sizeof(child->m_proc));
36 BOOL ret = CreateProcessA(
37 NULL ,
38 (LPSTR)p_cmdLine,
39 NULL,
40 NULL,
41 FALSE,
42 CREATE_DEFAULT_ERROR_MODE,
43 NULL,
44 (p_startdir != NULL ? p_startdir : ".\\"),
45 &si,
46 &child->m_proc);
47 if (ret == 0) {
48 delete child;
49 return NULL;
50 }
51
52 // close the thread handle we do not need it,
53 // keep the process handle for wait/trywait operations, will
54 // be closed on destruction
55 CloseHandle(child->m_proc.hThread);
56
57 return child;
58 }
59
~childProcess()60 childProcess::~childProcess()
61 {
62 if (m_proc.hProcess) {
63 CloseHandle(m_proc.hProcess);
64 }
65 }
66
67 bool
wait(int * exitStatus)68 childProcess::wait(int *exitStatus)
69 {
70 DWORD _exitStatus;
71
72 if (WaitForSingleObject(m_proc.hProcess, INFINITE) == WAIT_FAILED) {
73 return false;
74 }
75
76 if (!GetExitCodeProcess(m_proc.hProcess, &_exitStatus))
77 {
78 return false;
79 }
80
81 if (exitStatus) {
82 *exitStatus = _exitStatus;
83 }
84
85 return true;
86 }
87
88 int
tryWait(bool & isAlive)89 childProcess::tryWait(bool& isAlive)
90 {
91 DWORD status = WaitForSingleObject(m_proc.hProcess, 0);
92
93 if(status == WAIT_OBJECT_0)
94 {
95 // process has exited
96 isAlive = false;
97 GetExitCodeProcess(m_proc.hProcess, &status);
98 }
99 else if (status == WAIT_TIMEOUT)
100 {
101 isAlive = true;
102 status = 0;
103 }
104
105 return status;
106
107 }
108
ProcessGetPID()109 int ProcessGetPID()
110 {
111 return GetCurrentProcessId();
112 }
113
ProcessGetTID()114 int ProcessGetTID()
115 {
116 return GetCurrentThreadId();
117 }
118
ProcessGetName(char * p_outName,int p_outNameLen)119 bool ProcessGetName(char *p_outName, int p_outNameLen)
120 {
121 return 0 != GetModuleFileNameEx( GetCurrentProcess(), NULL, p_outName, p_outNameLen);
122 }
123
KillProcess(int pid,bool wait)124 int KillProcess(int pid, bool wait)
125 {
126 DWORD exitStatus = 1;
127 HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
128
129 if (NULL == hProc) {
130 return 0;
131 }
132
133 //
134 // Terminate the process
135 //
136 TerminateProcess(hProc, 0x55);
137
138 if (wait) {
139 //
140 // Wait for it to be terminated
141 //
142 if(WaitForSingleObject(hProc, INFINITE) == WAIT_FAILED) {
143 CloseHandle(hProc);
144 return 0;
145 }
146
147 if (!GetExitCodeProcess(hProc, &exitStatus)) {
148 CloseHandle(hProc);
149 return 0;
150 }
151 }
152
153 CloseHandle(hProc);
154
155 return exitStatus;
156 }
157
isProcessRunning(int pid)158 bool isProcessRunning(int pid)
159 {
160 bool isRunning = false;
161
162 HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
163 if (NULL != process) {
164 DWORD ret = WaitForSingleObject(process, 0);
165 CloseHandle(process);
166 isRunning = (ret == WAIT_TIMEOUT);
167 }
168 return isRunning;
169 }
170
171 } // of namespace osUtils
172