1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include "process.h"
26
27 #if defined(CONFIG_POSIX)
28 # include <sys/types.h>
29 # include <unistd.h>
30 # include <signal.h>
31 # include <sys/wait.h>
32 # include <fcntl.h>
33 # include <sys/stat.h>
34 #elif defined(CONFIG_OS_WINDOWS)
35 # include <windows.h>
36 # include <process.h>
37 #endif
38
39 #include "paths.h"
40
41 typedef struct _ProcessSelf
42 {
43 mike 1.1 #if defined(CONFIG_OS_WINDOWS)
44 HANDLE handle;
45 #else
46 int pid;
47 #endif
48 }
49 ProcessSelf;
50
51 int Process_StartChild(Process* self_, const char* path, char** argv)
52 {
53 ProcessSelf* self = (ProcessSelf*)self_;
54
55 #if 0
56 {
57 char** p = argv;
58
59 while (*p)
60 printf("ARG{%s}\n", *p++);
61 }
62 #endif
63
64 mike 1.1 #if defined(CONFIG_OS_WINDOWS)
65
66 STARTUPINFO si;
67 PROCESS_INFORMATION pi;
68 BOOL b;
69 char cmd[MAX_PATH_SIZE];
70 wchar_t wcmd[MAX_PATH_SIZE];
71
72 /* Initialize process info */
73 memset(&pi, 0, sizeof(pi));
74
75 /* Initialize startup info */
76 memset(&si, 0, sizeof(si));
77 si.cb = sizeof(STARTUPINFO);
78
79 /* Build command line */
80 {
81 char** p = argv;
82 size_t n;
83
84 n = Strlcpy(cmd, path, MAX_PATH_SIZE);
85 mike 1.1 if (n >= MAX_PATH_SIZE)
86 return -1;
87
88 p++;
89
90 while (*p)
91 {
92 n = Strlcat(cmd, " ", MAX_PATH_SIZE);
93 if (n >= MAX_PATH_SIZE)
94 return -1;
95
96 n = Strlcat(cmd, *p++, MAX_PATH_SIZE);
97 if (n >= MAX_PATH_SIZE)
98 return -1;
99 }
100 }
101
102 /* Convert path to wcs */
103 {
104 size_t i;
105
106 mike 1.1 for (i = 0; i < MAX_PATH_SIZE; i++)
107 wcmd[i] = cmd[i];
108 }
109
110 /* Create the process */
111 b = CreateProcess(
112 NULL, /* applicationName */
113 wcmd, /* commandLine */
114 NULL, /* processAttributes */
115 NULL, /* threadAttributew */
116 TRUE, /* inheritHandles */
117 0, /* creationFlags */
118 NULL, /* creationFlags */
119 NULL, /* currentDirectory */
120 &si, /* startupInfo */
121 &pi); /* processInfo */
122
123 if (!b)
124 return -1;
125
126 #if 0
127 mike 1.1 CloseHandle(pi.hProcess);
128 #endif
129 CloseHandle(pi.hThread);
130
131 self->handle = pi.hProcess;
132 return 0;
133
134 #elif defined(CONFIG_POSIX)
135 int pid = fork();
136
137 if (pid == 0)
138 {
139 /* Child */
140 execv(path, argv);
141 exit(1);
142 }
143 else if (pid > 0)
144 {
145 /* Parent */
146 self->pid = pid;
147 return 0;
148 mike 1.1 }
149 else
150 {
151 /* Fork failed */
152 self->pid = -1;
153 return -1;
154 }
155 #else
156 # error "unsupported"
157 #endif
158 }
159
160 int Process_StopChild(Process* self_)
161 {
162 #if defined(CONFIG_OS_WINDOWS)
163
164 ProcessSelf* self = (ProcessSelf*)self_;
165 BOOL b;
166
167 b = TerminateProcess(self->handle, 0);
168
169 mike 1.1 if (!b)
170 return -1;
171
172 return 0;
173
174 #elif defined(CONFIG_POSIX)
175
176 ProcessSelf* self = (ProcessSelf*)self_;
177 int status;
178
179 /* Terminate the process */
180 if (kill(self->pid, SIGTERM) != 0)
181 return -1;
182
183 if (waitpid(self->pid, &status, 0) == -1)
184 return -1;
185
186 return 0;
187
188 #else
189 # error "unsupported"
190 mike 1.1 #endif
191 }
192
193 #if defined(CONFIG_POSIX)
194 int Process_Daemonize()
195 {
196 int pid;
197
198 /* Fork for the first time */
199 pid = fork();
200 if (pid == -1)
201 return -1;
202
203 /* If parent, then exit; let child live on. */
204 if (pid > 0)
205 exit(0);
206
207 /* Become the session leader (return if this fails) */
208 if (setsid() == -1)
209 return -1;
210
211 mike 1.1 /* Fork a second time */
212 pid = fork();
213 if (pid == -1)
214 return -1;
215
216 /* If parent (first child), then exit; let second child live one */
217 if (pid > 0)
218 exit(0);
219
220 /* Close all file descriptors inherited by this process */
221 #if 0
222 {
223 int i;
224 for (i = 0; i < 64 ; i++)
225 close(i);
226 }
227 #else
228 close(0);
229 close(1);
230 close(2);
231 #endif
232 mike 1.1
233 /* Tie stdin to /dev/null */
234 open("/dev/null", O_RDONLY);
235
236 /* Tie stdout to /dev/null */
237 open("/dev/null", O_RDWR);
238
239 /* Tie stderr to /dev/null */
240 open("/dev/null", O_RDWR);
241
242 /* Set root directory as current directory */
243 #if 0
244 chdir("/");
245 #endif
246
247 return 0;
248 }
249
250 int SetSignalHandler(int sig, void (*handler)(int))
251 {
252 struct sigaction sig_acts;
253 mike 1.1
254 sig_acts.sa_handler = handler;
255 sigfillset(&(sig_acts.sa_mask));
256 sig_acts.sa_flags = 0;
257
258 return sigaction(sig, &sig_acts, NULL);
259 }
260
261 #endif /* defined(CONFIG_POSIX) */
|