diff options
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r-- | src/util/os_priority.c | 2218 |
1 files changed, 1109 insertions, 1109 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index 17baa0df8..e4f2371e7 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -11,12 +11,12 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file util/os_priority.c | 22 | * @file util/os_priority.c |
@@ -29,19 +29,18 @@ | |||
29 | #include "disk.h" | 29 | #include "disk.h" |
30 | #include <unistr.h> | 30 | #include <unistr.h> |
31 | 31 | ||
32 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__) | 32 | #define LOG(kind, ...) GNUNET_log_from(kind, "util-os-priority", __VA_ARGS__) |
33 | 33 | ||
34 | #define LOG_STRERROR(kind, syscall) \ | 34 | #define LOG_STRERROR(kind, syscall) \ |
35 | GNUNET_log_from_strerror (kind, "util-os-priority", syscall) | 35 | GNUNET_log_from_strerror(kind, "util-os-priority", syscall) |
36 | 36 | ||
37 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ | 37 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ |
38 | GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename) | 38 | GNUNET_log_from_strerror_file(kind, "util-os-priority", syscall, filename) |
39 | 39 | ||
40 | #define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE" | 40 | #define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE" |
41 | 41 | ||
42 | 42 | ||
43 | struct GNUNET_OS_Process | 43 | struct GNUNET_OS_Process { |
44 | { | ||
45 | /** | 44 | /** |
46 | * PID of the process. | 45 | * PID of the process. |
47 | */ | 46 | */ |
@@ -84,13 +83,13 @@ static struct GNUNET_SCHEDULER_Task *spch; | |||
84 | * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe | 83 | * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe |
85 | */ | 84 | */ |
86 | static void | 85 | static void |
87 | shutdown_pch (void *cls) | 86 | shutdown_pch(void *cls) |
88 | { | 87 | { |
89 | struct GNUNET_DISK_FileHandle *control_pipe = cls; | 88 | struct GNUNET_DISK_FileHandle *control_pipe = cls; |
90 | 89 | ||
91 | GNUNET_SCHEDULER_cancel (pch); | 90 | GNUNET_SCHEDULER_cancel(pch); |
92 | pch = NULL; | 91 | pch = NULL; |
93 | GNUNET_DISK_file_close (control_pipe); | 92 | GNUNET_DISK_file_close(control_pipe); |
94 | control_pipe = NULL; | 93 | control_pipe = NULL; |
95 | } | 94 | } |
96 | 95 | ||
@@ -101,7 +100,7 @@ shutdown_pch (void *cls) | |||
101 | * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe | 100 | * @param cls the `struct GNUNET_DISK_FileHandle` of the control pipe |
102 | */ | 101 | */ |
103 | static void | 102 | static void |
104 | parent_control_handler (void *cls) | 103 | parent_control_handler(void *cls) |
105 | { | 104 | { |
106 | struct GNUNET_DISK_FileHandle *control_pipe = cls; | 105 | struct GNUNET_DISK_FileHandle *control_pipe = cls; |
107 | char sig; | 106 | char sig; |
@@ -109,29 +108,29 @@ parent_control_handler (void *cls) | |||
109 | ssize_t ret; | 108 | ssize_t ret; |
110 | 109 | ||
111 | pch = NULL; | 110 | pch = NULL; |
112 | ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig)); | 111 | ret = GNUNET_DISK_file_read(control_pipe, &sig, sizeof(sig)); |
113 | if (sizeof (sig) != ret) | 112 | if (sizeof(sig) != ret) |
114 | { | 113 | { |
115 | if (-1 == ret) | 114 | if (-1 == ret) |
116 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read"); | 115 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read"); |
117 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n"); | 116 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n"); |
118 | GNUNET_DISK_file_close (control_pipe); | 117 | GNUNET_DISK_file_close(control_pipe); |
119 | control_pipe = NULL; | 118 | control_pipe = NULL; |
120 | GNUNET_SCHEDULER_cancel (spch); | 119 | GNUNET_SCHEDULER_cancel(spch); |
121 | spch = NULL; | 120 | spch = NULL; |
122 | return; | 121 | return; |
123 | } | 122 | } |
124 | pipe_fd = getenv (GNUNET_OS_CONTROL_PIPE); | 123 | pipe_fd = getenv(GNUNET_OS_CONTROL_PIPE); |
125 | GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0)); | 124 | GNUNET_assert((NULL == pipe_fd) || (strlen(pipe_fd) <= 0)); |
126 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 125 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
127 | "Got control code %d from parent via pipe %s\n", | 126 | "Got control code %d from parent via pipe %s\n", |
128 | sig, | 127 | sig, |
129 | pipe_fd); | 128 | pipe_fd); |
130 | pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 129 | pch = GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, |
131 | control_pipe, | 130 | control_pipe, |
132 | &parent_control_handler, | 131 | &parent_control_handler, |
133 | control_pipe); | 132 | control_pipe); |
134 | GNUNET_SIGNAL_raise ((int) sig); | 133 | GNUNET_SIGNAL_raise((int)sig); |
135 | } | 134 | } |
136 | 135 | ||
137 | 136 | ||
@@ -144,71 +143,71 @@ parent_control_handler (void *cls) | |||
144 | * @param cls closure (unused) | 143 | * @param cls closure (unused) |
145 | */ | 144 | */ |
146 | void | 145 | void |
147 | GNUNET_OS_install_parent_control_handler (void *cls) | 146 | GNUNET_OS_install_parent_control_handler(void *cls) |
148 | { | 147 | { |
149 | const char *env_buf; | 148 | const char *env_buf; |
150 | char *env_buf_end; | 149 | char *env_buf_end; |
151 | struct GNUNET_DISK_FileHandle *control_pipe; | 150 | struct GNUNET_DISK_FileHandle *control_pipe; |
152 | uint64_t pipe_fd; | 151 | uint64_t pipe_fd; |
153 | 152 | ||
154 | (void) cls; | 153 | (void)cls; |
155 | if (NULL != pch) | 154 | if (NULL != pch) |
156 | { | 155 | { |
157 | /* already done, we've been called twice... */ | 156 | /* already done, we've been called twice... */ |
158 | GNUNET_break (0); | 157 | GNUNET_break(0); |
159 | return; | 158 | return; |
160 | } | 159 | } |
161 | env_buf = getenv (GNUNET_OS_CONTROL_PIPE); | 160 | env_buf = getenv(GNUNET_OS_CONTROL_PIPE); |
162 | if ((NULL == env_buf) || (strlen (env_buf) <= 0)) | 161 | if ((NULL == env_buf) || (strlen(env_buf) <= 0)) |
163 | { | 162 | { |
164 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 163 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
165 | "Not installing a handler because $%s is empty\n", | 164 | "Not installing a handler because $%s is empty\n", |
166 | GNUNET_OS_CONTROL_PIPE); | 165 | GNUNET_OS_CONTROL_PIPE); |
167 | putenv (GNUNET_OS_CONTROL_PIPE "="); | 166 | putenv(GNUNET_OS_CONTROL_PIPE "="); |
168 | return; | 167 | return; |
169 | } | 168 | } |
170 | errno = 0; | 169 | errno = 0; |
171 | pipe_fd = strtoull (env_buf, &env_buf_end, 16); | 170 | pipe_fd = strtoull(env_buf, &env_buf_end, 16); |
172 | if ((0 != errno) || (env_buf == env_buf_end)) | 171 | if ((0 != errno) || (env_buf == env_buf_end)) |
173 | { | 172 | { |
174 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf); | 173 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf); |
175 | putenv (GNUNET_OS_CONTROL_PIPE "="); | 174 | putenv(GNUNET_OS_CONTROL_PIPE "="); |
176 | return; | 175 | return; |
177 | } | 176 | } |
178 | #if ! defined(WINDOWS) | 177 | #if !defined(WINDOWS) |
179 | if (pipe_fd >= FD_SETSIZE) | 178 | if (pipe_fd >= FD_SETSIZE) |
180 | #else | 179 | #else |
181 | if ((FILE_TYPE_UNKNOWN == GetFileType ((HANDLE) (uintptr_t) pipe_fd)) && | 180 | if ((FILE_TYPE_UNKNOWN == GetFileType((HANDLE)(uintptr_t)pipe_fd)) && |
182 | (0 != GetLastError ())) | 181 | (0 != GetLastError())) |
183 | #endif | 182 | #endif |
184 | { | 183 | { |
185 | LOG (GNUNET_ERROR_TYPE_ERROR, | 184 | LOG(GNUNET_ERROR_TYPE_ERROR, |
186 | "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n", | 185 | "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n", |
187 | env_buf); | 186 | env_buf); |
188 | putenv (GNUNET_OS_CONTROL_PIPE "="); | 187 | putenv(GNUNET_OS_CONTROL_PIPE "="); |
189 | return; | 188 | return; |
190 | } | 189 | } |
191 | #if WINDOWS | 190 | #if WINDOWS |
192 | control_pipe = | 191 | control_pipe = |
193 | GNUNET_DISK_get_handle_from_w32_handle ((HANDLE) (uintptr_t) pipe_fd); | 192 | GNUNET_DISK_get_handle_from_w32_handle((HANDLE)(uintptr_t)pipe_fd); |
194 | #else | 193 | #else |
195 | control_pipe = GNUNET_DISK_get_handle_from_int_fd ((int) pipe_fd); | 194 | control_pipe = GNUNET_DISK_get_handle_from_int_fd((int)pipe_fd); |
196 | #endif | 195 | #endif |
197 | if (NULL == control_pipe) | 196 | if (NULL == control_pipe) |
198 | { | 197 | { |
199 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", env_buf); | 198 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "open", env_buf); |
200 | putenv (GNUNET_OS_CONTROL_PIPE "="); | 199 | putenv(GNUNET_OS_CONTROL_PIPE "="); |
201 | return; | 200 | return; |
202 | } | 201 | } |
203 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 202 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
204 | "Adding parent control handler pipe `%s' to the scheduler\n", | 203 | "Adding parent control handler pipe `%s' to the scheduler\n", |
205 | env_buf); | 204 | env_buf); |
206 | pch = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 205 | pch = GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, |
207 | control_pipe, | 206 | control_pipe, |
208 | &parent_control_handler, | 207 | &parent_control_handler, |
209 | control_pipe); | 208 | control_pipe); |
210 | spch = GNUNET_SCHEDULER_add_shutdown (&shutdown_pch, control_pipe); | 209 | spch = GNUNET_SCHEDULER_add_shutdown(&shutdown_pch, control_pipe); |
211 | putenv (GNUNET_OS_CONTROL_PIPE "="); | 210 | putenv(GNUNET_OS_CONTROL_PIPE "="); |
212 | } | 211 | } |
213 | 212 | ||
214 | 213 | ||
@@ -221,11 +220,11 @@ GNUNET_OS_install_parent_control_handler (void *cls) | |||
221 | * @return pointer to the process sturcutre for this process | 220 | * @return pointer to the process sturcutre for this process |
222 | */ | 221 | */ |
223 | struct GNUNET_OS_Process * | 222 | struct GNUNET_OS_Process * |
224 | GNUNET_OS_process_current () | 223 | GNUNET_OS_process_current() |
225 | { | 224 | { |
226 | #if WINDOWS | 225 | #if WINDOWS |
227 | current_process.pid = GetCurrentProcessId (); | 226 | current_process.pid = GetCurrentProcessId(); |
228 | current_process.handle = GetCurrentProcess (); | 227 | current_process.handle = GetCurrentProcess(); |
229 | #else | 228 | #else |
230 | current_process.pid = 0; | 229 | current_process.pid = 0; |
231 | #endif | 230 | #endif |
@@ -241,92 +240,92 @@ GNUNET_OS_process_current () | |||
241 | * @return 0 on success, -1 on error | 240 | * @return 0 on success, -1 on error |
242 | */ | 241 | */ |
243 | int | 242 | int |
244 | GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig) | 243 | GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig) |
245 | { | 244 | { |
246 | int ret; | 245 | int ret; |
247 | char csig; | 246 | char csig; |
248 | 247 | ||
249 | csig = (char) sig; | 248 | csig = (char)sig; |
250 | if (NULL != proc->control_pipe) | 249 | if (NULL != proc->control_pipe) |
251 | { | 250 | { |
252 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 251 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
253 | "Sending signal %d to pid: %u via pipe\n", | 252 | "Sending signal %d to pid: %u via pipe\n", |
254 | sig, | 253 | sig, |
255 | proc->pid); | 254 | proc->pid); |
256 | ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof (csig)); | 255 | ret = GNUNET_DISK_file_write(proc->control_pipe, &csig, sizeof(csig)); |
257 | if (sizeof (csig) == ret) | 256 | if (sizeof(csig) == ret) |
258 | return 0; | 257 | return 0; |
259 | } | 258 | } |
260 | /* pipe failed or non-existent, try other methods */ | 259 | /* pipe failed or non-existent, try other methods */ |
261 | switch (sig) | 260 | switch (sig) |
262 | { | 261 | { |
263 | #if ! defined(WINDOWS) | 262 | #if !defined(WINDOWS) |
264 | case SIGHUP: | 263 | case SIGHUP: |
265 | #endif | 264 | #endif |
266 | case SIGINT: | 265 | case SIGINT: |
267 | case SIGKILL: | 266 | case SIGKILL: |
268 | case SIGTERM: | 267 | case SIGTERM: |
269 | #if (SIGTERM != GNUNET_TERM_SIG) | 268 | #if (SIGTERM != GNUNET_TERM_SIG) |
270 | case GNUNET_TERM_SIG: | 269 | case GNUNET_TERM_SIG: |
271 | #endif | 270 | #endif |
272 | #if defined(WINDOWS) && ! defined(__CYGWIN__) | 271 | #if defined(WINDOWS) && !defined(__CYGWIN__) |
273 | { | ||
274 | DWORD exitcode; | ||
275 | int must_kill = GNUNET_YES; | ||
276 | if (0 != GetExitCodeProcess (proc->handle, &exitcode)) | ||
277 | must_kill = (exitcode == STILL_ACTIVE) ? GNUNET_YES : GNUNET_NO; | ||
278 | if (GNUNET_YES == must_kill) | ||
279 | { | ||
280 | if (0 == SafeTerminateProcess (proc->handle, 0, 0)) | ||
281 | { | 272 | { |
282 | DWORD error_code = GetLastError (); | 273 | DWORD exitcode; |
283 | if ((error_code != WAIT_TIMEOUT) && | 274 | int must_kill = GNUNET_YES; |
284 | (error_code != ERROR_PROCESS_ABORTED)) | 275 | if (0 != GetExitCodeProcess(proc->handle, &exitcode)) |
285 | { | 276 | must_kill = (exitcode == STILL_ACTIVE) ? GNUNET_YES : GNUNET_NO; |
286 | LOG ((error_code == ERROR_ACCESS_DENIED) ? GNUNET_ERROR_TYPE_INFO | 277 | if (GNUNET_YES == must_kill) |
287 | : GNUNET_ERROR_TYPE_WARNING, | ||
288 | "SafeTermiateProcess failed with code %lu\n", | ||
289 | error_code); | ||
290 | /* The problem here is that a process that is already dying | ||
291 | * might cause SafeTerminateProcess to fail with | ||
292 | * ERROR_ACCESS_DENIED, but the process WILL die eventually. | ||
293 | * If we really had a permissions problem, hanging up (which | ||
294 | * is what will happen in process_wait() in that case) is | ||
295 | * a valid option. | ||
296 | */ | ||
297 | if (ERROR_ACCESS_DENIED == error_code) | ||
298 | { | ||
299 | errno = 0; | ||
300 | } | ||
301 | else | ||
302 | { | 278 | { |
303 | SetErrnoFromWinError (error_code); | 279 | if (0 == SafeTerminateProcess(proc->handle, 0, 0)) |
304 | return -1; | 280 | { |
281 | DWORD error_code = GetLastError(); | ||
282 | if ((error_code != WAIT_TIMEOUT) && | ||
283 | (error_code != ERROR_PROCESS_ABORTED)) | ||
284 | { | ||
285 | LOG((error_code == ERROR_ACCESS_DENIED) ? GNUNET_ERROR_TYPE_INFO | ||
286 | : GNUNET_ERROR_TYPE_WARNING, | ||
287 | "SafeTermiateProcess failed with code %lu\n", | ||
288 | error_code); | ||
289 | /* The problem here is that a process that is already dying | ||
290 | * might cause SafeTerminateProcess to fail with | ||
291 | * ERROR_ACCESS_DENIED, but the process WILL die eventually. | ||
292 | * If we really had a permissions problem, hanging up (which | ||
293 | * is what will happen in process_wait() in that case) is | ||
294 | * a valid option. | ||
295 | */ | ||
296 | if (ERROR_ACCESS_DENIED == error_code) | ||
297 | { | ||
298 | errno = 0; | ||
299 | } | ||
300 | else | ||
301 | { | ||
302 | SetErrnoFromWinError(error_code); | ||
303 | return -1; | ||
304 | } | ||
305 | } | ||
306 | } | ||
305 | } | 307 | } |
306 | } | ||
307 | } | 308 | } |
308 | } | 309 | return 0; |
309 | } | ||
310 | return 0; | ||
311 | #else | 310 | #else |
312 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 311 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
313 | "Sending signal %d to pid: %u via system call\n", | 312 | "Sending signal %d to pid: %u via system call\n", |
314 | sig, | 313 | sig, |
315 | proc->pid); | 314 | proc->pid); |
316 | return kill (proc->pid, sig); | 315 | return kill(proc->pid, sig); |
317 | #endif | 316 | #endif |
318 | default: | 317 | default: |
319 | #if defined(WINDOWS) | 318 | #if defined(WINDOWS) |
320 | errno = EINVAL; | 319 | errno = EINVAL; |
321 | return -1; | 320 | return -1; |
322 | #else | 321 | #else |
323 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 322 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
324 | "Sending signal %d to pid: %u via system call\n", | 323 | "Sending signal %d to pid: %u via system call\n", |
325 | sig, | 324 | sig, |
326 | proc->pid); | 325 | proc->pid); |
327 | return kill (proc->pid, sig); | 326 | return kill(proc->pid, sig); |
328 | #endif | 327 | #endif |
329 | } | 328 | } |
330 | } | 329 | } |
331 | 330 | ||
332 | 331 | ||
@@ -338,7 +337,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig) | |||
338 | * @return the current process id | 337 | * @return the current process id |
339 | */ | 338 | */ |
340 | pid_t | 339 | pid_t |
341 | GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc) | 340 | GNUNET_OS_process_get_pid(struct GNUNET_OS_Process *proc) |
342 | { | 341 | { |
343 | return proc->pid; | 342 | return proc->pid; |
344 | } | 343 | } |
@@ -351,15 +350,15 @@ GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc) | |||
351 | * @param proc pointer to process structure | 350 | * @param proc pointer to process structure |
352 | */ | 351 | */ |
353 | void | 352 | void |
354 | GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc) | 353 | GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc) |
355 | { | 354 | { |
356 | if (NULL != proc->control_pipe) | 355 | if (NULL != proc->control_pipe) |
357 | GNUNET_DISK_file_close (proc->control_pipe); | 356 | GNUNET_DISK_file_close(proc->control_pipe); |
358 | #if defined(WINDOWS) | 357 | #if defined(WINDOWS) |
359 | if (NULL != proc->handle) | 358 | if (NULL != proc->handle) |
360 | CloseHandle (proc->handle); | 359 | CloseHandle(proc->handle); |
361 | #endif | 360 | #endif |
362 | GNUNET_free (proc); | 361 | GNUNET_free(proc); |
363 | } | 362 | } |
364 | 363 | ||
365 | 364 | ||
@@ -379,14 +378,14 @@ extern GNUNET_SIGNAL_Handler w32_sigchld_handler; | |||
379 | * @param proc pointer to process structure | 378 | * @param proc pointer to process structure |
380 | */ | 379 | */ |
381 | static DWORD_WINAPI | 380 | static DWORD_WINAPI |
382 | child_wait_thread (void *arg) | 381 | child_wait_thread(void *arg) |
383 | { | 382 | { |
384 | struct GNUNET_OS_Process *proc = (struct GNUNET_OS_Process *) arg; | 383 | struct GNUNET_OS_Process *proc = (struct GNUNET_OS_Process *)arg; |
385 | 384 | ||
386 | WaitForSingleObject (proc->handle, INFINITE); | 385 | WaitForSingleObject(proc->handle, INFINITE); |
387 | 386 | ||
388 | if (w32_sigchld_handler) | 387 | if (w32_sigchld_handler) |
389 | w32_sigchld_handler (); | 388 | w32_sigchld_handler(); |
390 | 389 | ||
391 | return 0; | 390 | return 0; |
392 | } | 391 | } |
@@ -395,7 +394,7 @@ child_wait_thread (void *arg) | |||
395 | 394 | ||
396 | #if MINGW | 395 | #if MINGW |
397 | static char * | 396 | static char * |
398 | CreateCustomEnvTable (char **vars) | 397 | CreateCustomEnvTable(char **vars) |
399 | { | 398 | { |
400 | char *win32_env_table; | 399 | char *win32_env_table; |
401 | char *ptr; | 400 | char *ptr; |
@@ -412,90 +411,90 @@ CreateCustomEnvTable (char **vars) | |||
412 | char *var; | 411 | char *var; |
413 | char *val; | 412 | char *val; |
414 | 413 | ||
415 | win32_env_table = GetEnvironmentStringsA (); | 414 | win32_env_table = GetEnvironmentStringsA(); |
416 | if (NULL == win32_env_table) | 415 | if (NULL == win32_env_table) |
417 | return NULL; | 416 | return NULL; |
418 | for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++) | 417 | for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++) |
419 | ; | 418 | ; |
420 | n_var = c; | 419 | n_var = c; |
421 | index = GNUNET_malloc (sizeof (char *) * n_var); | 420 | index = GNUNET_malloc(sizeof(char *) * n_var); |
422 | for (c = 0; c < n_var; c++) | 421 | for (c = 0; c < n_var; c++) |
423 | index[c] = 0; | 422 | index[c] = 0; |
424 | for (items_count = 0, ptr = win32_env_table; ptr[0] != 0; items_count++) | 423 | for (items_count = 0, ptr = win32_env_table; ptr[0] != 0; items_count++) |
425 | { | ||
426 | size_t len = strlen (ptr); | ||
427 | int found = 0; | ||
428 | |||
429 | for (var_ptr = vars; *var_ptr; var_ptr++) | ||
430 | { | 424 | { |
431 | var = *var_ptr++; | 425 | size_t len = strlen(ptr); |
432 | val = *var_ptr; | 426 | int found = 0; |
433 | var_len = strlen (var); | 427 | |
434 | if (strncmp (var, ptr, var_len) == 0) | 428 | for (var_ptr = vars; *var_ptr; var_ptr++) |
435 | { | 429 | { |
436 | found = 1; | 430 | var = *var_ptr++; |
437 | index[c] = 1; | 431 | val = *var_ptr; |
438 | tablesize += var_len + strlen (val) + 1; | 432 | var_len = strlen(var); |
439 | break; | 433 | if (strncmp(var, ptr, var_len) == 0) |
440 | } | 434 | { |
435 | found = 1; | ||
436 | index[c] = 1; | ||
437 | tablesize += var_len + strlen(val) + 1; | ||
438 | break; | ||
439 | } | ||
440 | } | ||
441 | if (!found) | ||
442 | tablesize += len + 1; | ||
443 | ptr += len + 1; | ||
441 | } | 444 | } |
442 | if (! found) | ||
443 | tablesize += len + 1; | ||
444 | ptr += len + 1; | ||
445 | } | ||
446 | for (n_found = 0, c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) | 445 | for (n_found = 0, c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) |
447 | { | ||
448 | var = *var_ptr++; | ||
449 | val = *var_ptr; | ||
450 | if (index[c] != 1) | ||
451 | n_found += strlen (var) + strlen (val) + 1; | ||
452 | } | ||
453 | result = GNUNET_malloc (tablesize + n_found + 1); | ||
454 | for (result_ptr = result, ptr = win32_env_table; ptr[0] != 0;) | ||
455 | { | ||
456 | size_t len = strlen (ptr); | ||
457 | int found = 0; | ||
458 | |||
459 | for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) | ||
460 | { | 446 | { |
461 | var = *var_ptr++; | 447 | var = *var_ptr++; |
462 | val = *var_ptr; | 448 | val = *var_ptr; |
463 | var_len = strlen (var); | 449 | if (index[c] != 1) |
464 | if (strncmp (var, ptr, var_len) == 0) | 450 | n_found += strlen(var) + strlen(val) + 1; |
465 | { | ||
466 | found = 1; | ||
467 | break; | ||
468 | } | ||
469 | } | ||
470 | if (! found) | ||
471 | { | ||
472 | strcpy (result_ptr, ptr); | ||
473 | result_ptr += len + 1; | ||
474 | } | 451 | } |
475 | else | 452 | result = GNUNET_malloc(tablesize + n_found + 1); |
453 | for (result_ptr = result, ptr = win32_env_table; ptr[0] != 0;) | ||
476 | { | 454 | { |
477 | strcpy (result_ptr, var); | 455 | size_t len = strlen(ptr); |
478 | result_ptr += var_len; | 456 | int found = 0; |
479 | strcpy (result_ptr, val); | 457 | |
480 | result_ptr += strlen (val) + 1; | 458 | for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) |
459 | { | ||
460 | var = *var_ptr++; | ||
461 | val = *var_ptr; | ||
462 | var_len = strlen(var); | ||
463 | if (strncmp(var, ptr, var_len) == 0) | ||
464 | { | ||
465 | found = 1; | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | if (!found) | ||
470 | { | ||
471 | strcpy(result_ptr, ptr); | ||
472 | result_ptr += len + 1; | ||
473 | } | ||
474 | else | ||
475 | { | ||
476 | strcpy(result_ptr, var); | ||
477 | result_ptr += var_len; | ||
478 | strcpy(result_ptr, val); | ||
479 | result_ptr += strlen(val) + 1; | ||
480 | } | ||
481 | ptr += len + 1; | ||
481 | } | 482 | } |
482 | ptr += len + 1; | ||
483 | } | ||
484 | for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) | 483 | for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) |
485 | { | ||
486 | var = *var_ptr++; | ||
487 | val = *var_ptr; | ||
488 | var_len = strlen (var); | ||
489 | if (index[c] != 1) | ||
490 | { | 484 | { |
491 | strcpy (result_ptr, var); | 485 | var = *var_ptr++; |
492 | result_ptr += var_len; | 486 | val = *var_ptr; |
493 | strcpy (result_ptr, val); | 487 | var_len = strlen(var); |
494 | result_ptr += strlen (val) + 1; | 488 | if (index[c] != 1) |
489 | { | ||
490 | strcpy(result_ptr, var); | ||
491 | result_ptr += var_len; | ||
492 | strcpy(result_ptr, val); | ||
493 | result_ptr += strlen(val) + 1; | ||
494 | } | ||
495 | } | 495 | } |
496 | } | 496 | FreeEnvironmentStrings(win32_env_table); |
497 | FreeEnvironmentStrings (win32_env_table); | 497 | GNUNET_free(index); |
498 | GNUNET_free (index); | ||
499 | *result_ptr = 0; | 498 | *result_ptr = 0; |
500 | return result; | 499 | return result; |
501 | } | 500 | } |
@@ -510,25 +509,25 @@ CreateCustomEnvTable (char **vars) | |||
510 | * @param flags open flags (O_RDONLY, O_WRONLY) | 509 | * @param flags open flags (O_RDONLY, O_WRONLY) |
511 | */ | 510 | */ |
512 | static void | 511 | static void |
513 | open_dev_null (int target_fd, int flags) | 512 | open_dev_null(int target_fd, int flags) |
514 | { | 513 | { |
515 | int fd; | 514 | int fd; |
516 | 515 | ||
517 | fd = open ("/dev/null", flags); | 516 | fd = open("/dev/null", flags); |
518 | if (-1 == fd) | 517 | if (-1 == fd) |
519 | { | 518 | { |
520 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", "/dev/null"); | 519 | GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "open", "/dev/null"); |
521 | return; | 520 | return; |
522 | } | 521 | } |
523 | if (fd == target_fd) | 522 | if (fd == target_fd) |
524 | return; | 523 | return; |
525 | if (-1 == dup2 (fd, target_fd)) | 524 | if (-1 == dup2(fd, target_fd)) |
526 | { | 525 | { |
527 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "dup2"); | 526 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "dup2"); |
528 | (void) close (fd); | 527 | (void)close(fd); |
529 | return; | 528 | return; |
530 | } | 529 | } |
531 | GNUNET_break (0 == close (fd)); | 530 | GNUNET_break(0 == close(fd)); |
532 | } | 531 | } |
533 | #endif | 532 | #endif |
534 | 533 | ||
@@ -551,14 +550,14 @@ open_dev_null (int target_fd, int flags) | |||
551 | * @return process ID of the new process, -1 on error | 550 | * @return process ID of the new process, -1 on error |
552 | */ | 551 | */ |
553 | static struct GNUNET_OS_Process * | 552 | static struct GNUNET_OS_Process * |
554 | start_process (int pipe_control, | 553 | start_process(int pipe_control, |
555 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | 554 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
556 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 555 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
557 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 556 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
558 | struct GNUNET_DISK_PipeHandle *pipe_stderr, | 557 | struct GNUNET_DISK_PipeHandle *pipe_stderr, |
559 | const SOCKTYPE *lsocks, | 558 | const SOCKTYPE *lsocks, |
560 | const char *filename, | 559 | const char *filename, |
561 | char *const argv[]) | 560 | char *const argv[]) |
562 | { | 561 | { |
563 | #ifndef MINGW | 562 | #ifndef MINGW |
564 | pid_t ret; | 563 | pid_t ret; |
@@ -582,223 +581,223 @@ start_process (int pipe_control, | |||
582 | int fd_stdin_write; | 581 | int fd_stdin_write; |
583 | 582 | ||
584 | if (GNUNET_SYSERR == | 583 | if (GNUNET_SYSERR == |
585 | GNUNET_OS_check_helper_binary (filename, GNUNET_NO, NULL)) | 584 | GNUNET_OS_check_helper_binary(filename, GNUNET_NO, NULL)) |
586 | return NULL; /* not executable */ | 585 | return NULL; /* not executable */ |
587 | if (GNUNET_YES == pipe_control) | 586 | if (GNUNET_YES == pipe_control) |
588 | { | 587 | { |
589 | struct GNUNET_DISK_PipeHandle *childpipe; | 588 | struct GNUNET_DISK_PipeHandle *childpipe; |
590 | int dup_childpipe_read_fd = -1; | 589 | int dup_childpipe_read_fd = -1; |
591 | 590 | ||
592 | childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); | 591 | childpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); |
593 | if (NULL == childpipe) | 592 | if (NULL == childpipe) |
594 | return NULL; | 593 | return NULL; |
595 | childpipe_read = | 594 | childpipe_read = |
596 | GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_READ); | 595 | GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_READ); |
597 | childpipe_write = | 596 | childpipe_write = |
598 | GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_WRITE); | 597 | GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_WRITE); |
599 | GNUNET_DISK_pipe_close (childpipe); | 598 | GNUNET_DISK_pipe_close(childpipe); |
600 | if ((NULL == childpipe_read) || (NULL == childpipe_write) || | 599 | if ((NULL == childpipe_read) || (NULL == childpipe_write) || |
601 | (GNUNET_OK != GNUNET_DISK_internal_file_handle_ (childpipe_read, | 600 | (GNUNET_OK != GNUNET_DISK_internal_file_handle_(childpipe_read, |
602 | &childpipe_read_fd, | 601 | &childpipe_read_fd, |
603 | sizeof (int))) || | 602 | sizeof(int))) || |
604 | (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd)))) | 603 | (-1 == (dup_childpipe_read_fd = dup(childpipe_read_fd)))) |
605 | { | 604 | { |
606 | if (NULL != childpipe_read) | 605 | if (NULL != childpipe_read) |
607 | GNUNET_DISK_file_close (childpipe_read); | 606 | GNUNET_DISK_file_close(childpipe_read); |
608 | if (NULL != childpipe_write) | 607 | if (NULL != childpipe_write) |
609 | GNUNET_DISK_file_close (childpipe_write); | 608 | GNUNET_DISK_file_close(childpipe_write); |
610 | if (0 <= dup_childpipe_read_fd) | 609 | if (0 <= dup_childpipe_read_fd) |
611 | close (dup_childpipe_read_fd); | 610 | close(dup_childpipe_read_fd); |
612 | return NULL; | 611 | return NULL; |
612 | } | ||
613 | childpipe_read_fd = dup_childpipe_read_fd; | ||
614 | GNUNET_DISK_file_close(childpipe_read); | ||
613 | } | 615 | } |
614 | childpipe_read_fd = dup_childpipe_read_fd; | ||
615 | GNUNET_DISK_file_close (childpipe_read); | ||
616 | } | ||
617 | else | 616 | else |
618 | { | 617 | { |
619 | childpipe_write = NULL; | 618 | childpipe_write = NULL; |
620 | childpipe_read_fd = -1; | 619 | childpipe_read_fd = -1; |
621 | } | 620 | } |
622 | if (NULL != pipe_stdin) | 621 | if (NULL != pipe_stdin) |
623 | { | 622 | { |
624 | GNUNET_assert ( | 623 | GNUNET_assert( |
625 | GNUNET_OK == | 624 | GNUNET_OK == |
626 | GNUNET_DISK_internal_file_handle_ ( | 625 | GNUNET_DISK_internal_file_handle_( |
627 | GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_READ), | 626 | GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_READ), |
628 | &fd_stdin_read, | 627 | &fd_stdin_read, |
629 | sizeof (int))); | 628 | sizeof(int))); |
630 | GNUNET_assert ( | 629 | GNUNET_assert( |
631 | GNUNET_OK == | 630 | GNUNET_OK == |
632 | GNUNET_DISK_internal_file_handle_ ( | 631 | GNUNET_DISK_internal_file_handle_( |
633 | GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE), | 632 | GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_WRITE), |
634 | &fd_stdin_write, | 633 | &fd_stdin_write, |
635 | sizeof (int))); | 634 | sizeof(int))); |
636 | } | 635 | } |
637 | if (NULL != pipe_stdout) | 636 | if (NULL != pipe_stdout) |
638 | { | 637 | { |
639 | GNUNET_assert ( | 638 | GNUNET_assert( |
640 | GNUNET_OK == | 639 | GNUNET_OK == |
641 | GNUNET_DISK_internal_file_handle_ ( | 640 | GNUNET_DISK_internal_file_handle_( |
642 | GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), | 641 | GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), |
643 | &fd_stdout_write, | 642 | &fd_stdout_write, |
644 | sizeof (int))); | 643 | sizeof(int))); |
645 | GNUNET_assert ( | 644 | GNUNET_assert( |
646 | GNUNET_OK == | 645 | GNUNET_OK == |
647 | GNUNET_DISK_internal_file_handle_ ( | 646 | GNUNET_DISK_internal_file_handle_( |
648 | GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_READ), | 647 | GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_READ), |
649 | &fd_stdout_read, | 648 | &fd_stdout_read, |
650 | sizeof (int))); | 649 | sizeof(int))); |
651 | } | 650 | } |
652 | if (NULL != pipe_stderr) | 651 | if (NULL != pipe_stderr) |
653 | { | 652 | { |
654 | GNUNET_assert ( | 653 | GNUNET_assert( |
655 | GNUNET_OK == | 654 | GNUNET_OK == |
656 | GNUNET_DISK_internal_file_handle_ ( | 655 | GNUNET_DISK_internal_file_handle_( |
657 | GNUNET_DISK_pipe_handle (pipe_stderr, GNUNET_DISK_PIPE_END_READ), | 656 | GNUNET_DISK_pipe_handle(pipe_stderr, GNUNET_DISK_PIPE_END_READ), |
658 | &fd_stderr_read, | 657 | &fd_stderr_read, |
659 | sizeof (int))); | 658 | sizeof(int))); |
660 | GNUNET_assert ( | 659 | GNUNET_assert( |
661 | GNUNET_OK == | 660 | GNUNET_OK == |
662 | GNUNET_DISK_internal_file_handle_ ( | 661 | GNUNET_DISK_internal_file_handle_( |
663 | GNUNET_DISK_pipe_handle (pipe_stderr, GNUNET_DISK_PIPE_END_WRITE), | 662 | GNUNET_DISK_pipe_handle(pipe_stderr, GNUNET_DISK_PIPE_END_WRITE), |
664 | &fd_stderr_write, | 663 | &fd_stderr_write, |
665 | sizeof (int))); | 664 | sizeof(int))); |
666 | } | 665 | } |
667 | lscp = NULL; | 666 | lscp = NULL; |
668 | ls = 0; | 667 | ls = 0; |
669 | if (NULL != lsocks) | 668 | if (NULL != lsocks) |
670 | { | 669 | { |
671 | i = 0; | 670 | i = 0; |
672 | while (-1 != (k = lsocks[i++])) | 671 | while (-1 != (k = lsocks[i++])) |
673 | GNUNET_array_append (lscp, ls, k); | 672 | GNUNET_array_append(lscp, ls, k); |
674 | GNUNET_array_append (lscp, ls, -1); | 673 | GNUNET_array_append(lscp, ls, -1); |
675 | } | 674 | } |
676 | #if DARWIN | 675 | #if DARWIN |
677 | /* see https://gnunet.org/vfork */ | 676 | /* see https://gnunet.org/vfork */ |
678 | ret = vfork (); | 677 | ret = vfork(); |
679 | #else | 678 | #else |
680 | ret = fork (); | 679 | ret = fork(); |
681 | #endif | 680 | #endif |
682 | if (-1 == ret) | 681 | if (-1 == ret) |
683 | { | 682 | { |
684 | int eno = errno; | 683 | int eno = errno; |
685 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); | 684 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork"); |
686 | GNUNET_array_grow (lscp, ls, 0); | 685 | GNUNET_array_grow(lscp, ls, 0); |
687 | if (NULL != childpipe_write) | 686 | if (NULL != childpipe_write) |
688 | GNUNET_DISK_file_close (childpipe_write); | 687 | GNUNET_DISK_file_close(childpipe_write); |
689 | if (0 <= childpipe_read_fd) | 688 | if (0 <= childpipe_read_fd) |
690 | close (childpipe_read_fd); | 689 | close(childpipe_read_fd); |
691 | errno = eno; | 690 | errno = eno; |
692 | return NULL; | 691 | return NULL; |
693 | } | 692 | } |
694 | if (0 != ret) | 693 | if (0 != ret) |
695 | { | ||
696 | unsetenv (GNUNET_OS_CONTROL_PIPE); | ||
697 | gnunet_proc = GNUNET_new (struct GNUNET_OS_Process); | ||
698 | gnunet_proc->pid = ret; | ||
699 | gnunet_proc->control_pipe = childpipe_write; | ||
700 | if (GNUNET_YES == pipe_control) | ||
701 | { | 694 | { |
702 | close (childpipe_read_fd); | 695 | unsetenv(GNUNET_OS_CONTROL_PIPE); |
696 | gnunet_proc = GNUNET_new(struct GNUNET_OS_Process); | ||
697 | gnunet_proc->pid = ret; | ||
698 | gnunet_proc->control_pipe = childpipe_write; | ||
699 | if (GNUNET_YES == pipe_control) | ||
700 | { | ||
701 | close(childpipe_read_fd); | ||
702 | } | ||
703 | GNUNET_array_grow(lscp, ls, 0); | ||
704 | return gnunet_proc; | ||
703 | } | 705 | } |
704 | GNUNET_array_grow (lscp, ls, 0); | ||
705 | return gnunet_proc; | ||
706 | } | ||
707 | if (0 <= childpipe_read_fd) | 706 | if (0 <= childpipe_read_fd) |
708 | { | 707 | { |
709 | char fdbuf[100]; | 708 | char fdbuf[100]; |
710 | #ifndef DARWIN | 709 | #ifndef DARWIN |
711 | /* due to vfork, we must NOT free memory on DARWIN! */ | 710 | /* due to vfork, we must NOT free memory on DARWIN! */ |
712 | GNUNET_DISK_file_close (childpipe_write); | 711 | GNUNET_DISK_file_close(childpipe_write); |
713 | #endif | 712 | #endif |
714 | snprintf (fdbuf, 100, "%x", childpipe_read_fd); | 713 | snprintf(fdbuf, 100, "%x", childpipe_read_fd); |
715 | setenv (GNUNET_OS_CONTROL_PIPE, fdbuf, 1); | 714 | setenv(GNUNET_OS_CONTROL_PIPE, fdbuf, 1); |
716 | } | 715 | } |
717 | else | 716 | else |
718 | unsetenv (GNUNET_OS_CONTROL_PIPE); | 717 | unsetenv(GNUNET_OS_CONTROL_PIPE); |
719 | if (NULL != pipe_stdin) | 718 | if (NULL != pipe_stdin) |
720 | { | 719 | { |
721 | GNUNET_break (0 == close (fd_stdin_write)); | 720 | GNUNET_break(0 == close(fd_stdin_write)); |
722 | if (-1 == dup2 (fd_stdin_read, 0)) | 721 | if (-1 == dup2(fd_stdin_read, 0)) |
723 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); | 722 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); |
724 | GNUNET_break (0 == close (fd_stdin_read)); | 723 | GNUNET_break(0 == close(fd_stdin_read)); |
725 | } | 724 | } |
726 | else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_IN)) | 725 | else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_IN)) |
727 | { | 726 | { |
728 | GNUNET_break (0 == close (0)); | 727 | GNUNET_break(0 == close(0)); |
729 | open_dev_null (0, O_RDONLY); | 728 | open_dev_null(0, O_RDONLY); |
730 | } | 729 | } |
731 | if (NULL != pipe_stdout) | 730 | if (NULL != pipe_stdout) |
732 | { | 731 | { |
733 | GNUNET_break (0 == close (fd_stdout_read)); | 732 | GNUNET_break(0 == close(fd_stdout_read)); |
734 | if (-1 == dup2 (fd_stdout_write, 1)) | 733 | if (-1 == dup2(fd_stdout_write, 1)) |
735 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); | 734 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); |
736 | GNUNET_break (0 == close (fd_stdout_write)); | 735 | GNUNET_break(0 == close(fd_stdout_write)); |
737 | } | 736 | } |
738 | else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_OUT)) | 737 | else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_OUT)) |
739 | { | 738 | { |
740 | GNUNET_break (0 == close (1)); | 739 | GNUNET_break(0 == close(1)); |
741 | open_dev_null (1, O_WRONLY); | 740 | open_dev_null(1, O_WRONLY); |
742 | } | 741 | } |
743 | if (NULL != pipe_stderr) | 742 | if (NULL != pipe_stderr) |
744 | { | 743 | { |
745 | GNUNET_break (0 == close (fd_stderr_read)); | 744 | GNUNET_break(0 == close(fd_stderr_read)); |
746 | if (-1 == dup2 (fd_stderr_write, 2)) | 745 | if (-1 == dup2(fd_stderr_write, 2)) |
747 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); | 746 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); |
748 | GNUNET_break (0 == close (fd_stderr_write)); | 747 | GNUNET_break(0 == close(fd_stderr_write)); |
749 | } | 748 | } |
750 | else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_ERR)) | 749 | else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_ERR)) |
751 | { | 750 | { |
752 | GNUNET_break (0 == close (2)); | 751 | GNUNET_break(0 == close(2)); |
753 | open_dev_null (2, O_WRONLY); | 752 | open_dev_null(2, O_WRONLY); |
754 | } | 753 | } |
755 | if (NULL != lscp) | 754 | if (NULL != lscp) |
756 | { | ||
757 | /* read systemd documentation... */ | ||
758 | i = 0; | ||
759 | tgt = 3; | ||
760 | while (-1 != lscp[i]) | ||
761 | { | 755 | { |
762 | j = i + 1; | 756 | /* read systemd documentation... */ |
763 | while (-1 != lscp[j]) | 757 | i = 0; |
764 | { | 758 | tgt = 3; |
765 | if (lscp[j] == tgt) | 759 | while (-1 != lscp[i]) |
766 | { | 760 | { |
767 | /* dup away */ | 761 | j = i + 1; |
768 | k = dup (lscp[j]); | 762 | while (-1 != lscp[j]) |
769 | GNUNET_assert (-1 != k); | 763 | { |
770 | GNUNET_assert (0 == close (lscp[j])); | 764 | if (lscp[j] == tgt) |
771 | lscp[j] = k; | 765 | { |
772 | break; | 766 | /* dup away */ |
767 | k = dup(lscp[j]); | ||
768 | GNUNET_assert(-1 != k); | ||
769 | GNUNET_assert(0 == close(lscp[j])); | ||
770 | lscp[j] = k; | ||
771 | break; | ||
772 | } | ||
773 | j++; | ||
774 | } | ||
775 | if (lscp[i] != tgt) | ||
776 | { | ||
777 | /* Bury any existing FD, no matter what; they should all be closed | ||
778 | * on exec anyway and the important onces have been dup'ed away */ | ||
779 | (void)close(tgt); | ||
780 | GNUNET_assert(-1 != dup2(lscp[i], tgt)); | ||
781 | } | ||
782 | /* unset close-on-exec flag */ | ||
783 | flags = fcntl(tgt, F_GETFD); | ||
784 | GNUNET_assert(flags >= 0); | ||
785 | flags &= ~FD_CLOEXEC; | ||
786 | fflush(stderr); | ||
787 | (void)fcntl(tgt, F_SETFD, flags); | ||
788 | tgt++; | ||
789 | i++; | ||
773 | } | 790 | } |
774 | j++; | 791 | GNUNET_snprintf(fds, sizeof(fds), "%u", i); |
775 | } | 792 | setenv("LISTEN_FDS", fds, 1); |
776 | if (lscp[i] != tgt) | 793 | } |
777 | { | ||
778 | /* Bury any existing FD, no matter what; they should all be closed | ||
779 | * on exec anyway and the important onces have been dup'ed away */ | ||
780 | (void) close (tgt); | ||
781 | GNUNET_assert (-1 != dup2 (lscp[i], tgt)); | ||
782 | } | ||
783 | /* unset close-on-exec flag */ | ||
784 | flags = fcntl (tgt, F_GETFD); | ||
785 | GNUNET_assert (flags >= 0); | ||
786 | flags &= ~FD_CLOEXEC; | ||
787 | fflush (stderr); | ||
788 | (void) fcntl (tgt, F_SETFD, flags); | ||
789 | tgt++; | ||
790 | i++; | ||
791 | } | ||
792 | GNUNET_snprintf (fds, sizeof (fds), "%u", i); | ||
793 | setenv ("LISTEN_FDS", fds, 1); | ||
794 | } | ||
795 | #ifndef DARWIN | 794 | #ifndef DARWIN |
796 | /* due to vfork, we must NOT free memory on DARWIN! */ | 795 | /* due to vfork, we must NOT free memory on DARWIN! */ |
797 | GNUNET_array_grow (lscp, ls, 0); | 796 | GNUNET_array_grow(lscp, ls, 0); |
798 | #endif | 797 | #endif |
799 | execvp (filename, argv); | 798 | execvp(filename, argv); |
800 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "execvp", filename); | 799 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, "execvp", filename); |
801 | _exit (1); | 800 | _exit(1); |
802 | #else | 801 | #else |
803 | struct GNUNET_DISK_FileHandle *childpipe_read; | 802 | struct GNUNET_DISK_FileHandle *childpipe_read; |
804 | struct GNUNET_DISK_FileHandle *childpipe_write; | 803 | struct GNUNET_DISK_FileHandle *childpipe_write; |
@@ -813,7 +812,7 @@ start_process (int pipe_control, | |||
813 | int argcount = 0; | 812 | int argcount = 0; |
814 | struct GNUNET_OS_Process *gnunet_proc; | 813 | struct GNUNET_OS_Process *gnunet_proc; |
815 | char path[MAX_PATH + 1]; | 814 | char path[MAX_PATH + 1]; |
816 | char *our_env[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; | 815 | char *our_env[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
817 | char *env_block = NULL; | 816 | char *env_block = NULL; |
818 | char *pathbuf; | 817 | char *pathbuf; |
819 | DWORD pathbuf_len; | 818 | DWORD pathbuf_len; |
@@ -844,499 +843,500 @@ start_process (int pipe_control, | |||
844 | DWORD create_no_window; | 843 | DWORD create_no_window; |
845 | 844 | ||
846 | if (GNUNET_SYSERR == | 845 | if (GNUNET_SYSERR == |
847 | GNUNET_OS_check_helper_binary (filename, GNUNET_NO, NULL)) | 846 | GNUNET_OS_check_helper_binary(filename, GNUNET_NO, NULL)) |
848 | return NULL; /* not executable */ | 847 | return NULL; /* not executable */ |
849 | 848 | ||
850 | /* Search in prefix dir (hopefully - the directory from which | 849 | /* Search in prefix dir (hopefully - the directory from which |
851 | * the current module was loaded), bindir and libdir, then in PATH | 850 | * the current module was loaded), bindir and libdir, then in PATH |
852 | */ | 851 | */ |
853 | self_prefix = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_SELF_PREFIX); | 852 | self_prefix = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_SELF_PREFIX); |
854 | bindir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_BINDIR); | 853 | bindir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_BINDIR); |
855 | libdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); | 854 | libdir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LIBDIR); |
856 | 855 | ||
857 | pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); | 856 | pathbuf_len = GetEnvironmentVariableA("PATH", (char *)&pathbuf, 0); |
858 | 857 | ||
859 | alloc_len = pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + | 858 | alloc_len = pathbuf_len + 1 + strlen(self_prefix) + 1 + strlen(bindir) + 1 + |
860 | strlen (libdir); | 859 | strlen(libdir); |
861 | 860 | ||
862 | pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); | 861 | pathbuf = GNUNET_malloc(alloc_len * sizeof(char)); |
863 | 862 | ||
864 | ptr = pathbuf; | 863 | ptr = pathbuf; |
865 | ptr += sprintf (pathbuf, "%s;%s;%s;", self_prefix, bindir, libdir); | 864 | ptr += sprintf(pathbuf, "%s;%s;%s;", self_prefix, bindir, libdir); |
866 | GNUNET_free (self_prefix); | 865 | GNUNET_free(self_prefix); |
867 | GNUNET_free (bindir); | 866 | GNUNET_free(bindir); |
868 | GNUNET_free (libdir); | 867 | GNUNET_free(libdir); |
869 | 868 | ||
870 | alloc_len = GetEnvironmentVariableA ("PATH", ptr, pathbuf_len); | 869 | alloc_len = GetEnvironmentVariableA("PATH", ptr, pathbuf_len); |
871 | if (alloc_len != pathbuf_len - 1) | 870 | if (alloc_len != pathbuf_len - 1) |
872 | { | 871 | { |
873 | GNUNET_free (pathbuf); | 872 | GNUNET_free(pathbuf); |
874 | errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ | 873 | errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ |
875 | return NULL; | 874 | return NULL; |
876 | } | 875 | } |
877 | 876 | ||
878 | cmdlen = strlen (filename); | 877 | cmdlen = strlen(filename); |
879 | if ((cmdlen < 5) || (0 != strcmp (&filename[cmdlen - 4], ".exe"))) | 878 | if ((cmdlen < 5) || (0 != strcmp(&filename[cmdlen - 4], ".exe"))) |
880 | GNUNET_asprintf (&non_const_filename, "%s.exe", filename); | 879 | GNUNET_asprintf(&non_const_filename, "%s.exe", filename); |
881 | else | 880 | else |
882 | GNUNET_asprintf (&non_const_filename, "%s", filename); | 881 | GNUNET_asprintf(&non_const_filename, "%s", filename); |
883 | 882 | ||
884 | /* It could be in POSIX form, convert it to a DOS path early on */ | 883 | /* It could be in POSIX form, convert it to a DOS path early on */ |
885 | if (ERROR_SUCCESS != | 884 | if (ERROR_SUCCESS != |
886 | (lRet = plibc_conv_to_win_path (non_const_filename, win_path))) | 885 | (lRet = plibc_conv_to_win_path(non_const_filename, win_path))) |
887 | { | 886 | { |
888 | SetErrnoFromWinError (lRet); | 887 | SetErrnoFromWinError(lRet); |
889 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, | 888 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, |
890 | "plibc_conv_to_win_path", | 889 | "plibc_conv_to_win_path", |
891 | non_const_filename); | 890 | non_const_filename); |
892 | GNUNET_free (non_const_filename); | 891 | GNUNET_free(non_const_filename); |
893 | GNUNET_free (pathbuf); | 892 | GNUNET_free(pathbuf); |
894 | return NULL; | 893 | return NULL; |
895 | } | 894 | } |
896 | GNUNET_free (non_const_filename); | 895 | GNUNET_free(non_const_filename); |
897 | non_const_filename = GNUNET_strdup (win_path); | 896 | non_const_filename = GNUNET_strdup(win_path); |
898 | /* Check that this is the full path. If it isn't, search. */ | 897 | /* Check that this is the full path. If it isn't, search. */ |
899 | /* FIXME: convert it to wchar_t and use SearchPathW? | 898 | /* FIXME: convert it to wchar_t and use SearchPathW? |
900 | * Remember: arguments to _start_process() are technically in UTF-8... | 899 | * Remember: arguments to _start_process() are technically in UTF-8... |
901 | */ | 900 | */ |
902 | if (non_const_filename[1] == ':') | 901 | if (non_const_filename[1] == ':') |
903 | { | 902 | { |
904 | snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); | 903 | snprintf(path, sizeof(path) / sizeof(char), "%s", non_const_filename); |
905 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 904 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
906 | "Using path `%s' as-is. PATH is %s\n", | 905 | "Using path `%s' as-is. PATH is %s\n", |
907 | path, | 906 | path, |
908 | ptr); | 907 | ptr); |
909 | } | 908 | } |
910 | else if (! SearchPathA (pathbuf, | 909 | else if (!SearchPathA(pathbuf, |
911 | non_const_filename, | 910 | non_const_filename, |
912 | NULL, | 911 | NULL, |
913 | sizeof (path) / sizeof (char), | 912 | sizeof(path) / sizeof(char), |
914 | path, | 913 | path, |
915 | NULL)) | 914 | NULL)) |
916 | { | 915 | { |
917 | SetErrnoFromWinError (GetLastError ()); | 916 | SetErrnoFromWinError(GetLastError()); |
918 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, | 917 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_ERROR, |
919 | "SearchPath", | 918 | "SearchPath", |
920 | non_const_filename); | 919 | non_const_filename); |
921 | GNUNET_free (non_const_filename); | 920 | GNUNET_free(non_const_filename); |
922 | GNUNET_free (pathbuf); | 921 | GNUNET_free(pathbuf); |
923 | return NULL; | 922 | return NULL; |
924 | } | 923 | } |
925 | else | 924 | else |
926 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' in PATH `%s'\n", path, pathbuf); | 925 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Found `%s' in PATH `%s'\n", path, pathbuf); |
927 | GNUNET_free (pathbuf); | 926 | GNUNET_free(pathbuf); |
928 | GNUNET_free (non_const_filename); | 927 | GNUNET_free(non_const_filename); |
929 | 928 | ||
930 | /* Count the number of arguments */ | 929 | /* Count the number of arguments */ |
931 | arg = (char **) argv; | 930 | arg = (char **)argv; |
932 | while (*arg) | 931 | while (*arg) |
933 | { | 932 | { |
934 | arg++; | 933 | arg++; |
935 | argcount++; | 934 | argcount++; |
936 | } | 935 | } |
937 | 936 | ||
938 | /* Allocate a copy argv */ | 937 | /* Allocate a copy argv */ |
939 | non_const_argv = GNUNET_malloc (sizeof (char *) * (argcount + 1)); | 938 | non_const_argv = GNUNET_malloc(sizeof(char *) * (argcount + 1)); |
940 | 939 | ||
941 | /* Copy all argv strings */ | 940 | /* Copy all argv strings */ |
942 | argcount = 0; | 941 | argcount = 0; |
943 | arg = (char **) argv; | 942 | arg = (char **)argv; |
944 | while (*arg) | 943 | while (*arg) |
945 | { | 944 | { |
946 | if (arg == argv) | 945 | if (arg == argv) |
947 | non_const_argv[argcount] = GNUNET_strdup (path); | 946 | non_const_argv[argcount] = GNUNET_strdup(path); |
948 | else | 947 | else |
949 | non_const_argv[argcount] = GNUNET_strdup (*arg); | 948 | non_const_argv[argcount] = GNUNET_strdup(*arg); |
950 | arg++; | 949 | arg++; |
951 | argcount++; | 950 | argcount++; |
952 | } | 951 | } |
953 | non_const_argv[argcount] = NULL; | 952 | non_const_argv[argcount] = NULL; |
954 | 953 | ||
955 | /* Count cmd len */ | 954 | /* Count cmd len */ |
956 | cmdlen = 1; | 955 | cmdlen = 1; |
957 | arg = non_const_argv; | 956 | arg = non_const_argv; |
958 | while (*arg) | 957 | while (*arg) |
959 | { | 958 | { |
960 | cmdlen = cmdlen + strlen (*arg) + 4; | 959 | cmdlen = cmdlen + strlen(*arg) + 4; |
961 | arg++; | 960 | arg++; |
962 | } | 961 | } |
963 | 962 | ||
964 | /* Allocate and create cmd */ | 963 | /* Allocate and create cmd */ |
965 | cmd = idx = GNUNET_malloc (sizeof (char) * cmdlen); | 964 | cmd = idx = GNUNET_malloc(sizeof(char) * cmdlen); |
966 | arg = non_const_argv; | 965 | arg = non_const_argv; |
967 | while (*arg) | 966 | while (*arg) |
968 | { | 967 | { |
969 | char arg_last_char = (*arg)[strlen (*arg) - 1]; | 968 | char arg_last_char = (*arg)[strlen(*arg) - 1]; |
970 | idx += sprintf (idx, | 969 | idx += sprintf(idx, |
971 | "\"%s%s\"%s", | 970 | "\"%s%s\"%s", |
972 | *arg, | 971 | *arg, |
973 | arg_last_char == '\\' ? "\\" : "", | 972 | arg_last_char == '\\' ? "\\" : "", |
974 | *(arg + 1) ? " " : ""); | 973 | *(arg + 1) ? " " : ""); |
975 | arg++; | 974 | arg++; |
976 | } | 975 | } |
977 | 976 | ||
978 | while (argcount > 0) | 977 | while (argcount > 0) |
979 | GNUNET_free (non_const_argv[--argcount]); | 978 | GNUNET_free(non_const_argv[--argcount]); |
980 | GNUNET_free (non_const_argv); | 979 | GNUNET_free(non_const_argv); |
981 | 980 | ||
982 | memset (&start, 0, sizeof (start)); | 981 | memset(&start, 0, sizeof(start)); |
983 | start.cb = sizeof (start); | 982 | start.cb = sizeof(start); |
984 | if ((pipe_stdin != NULL) || (pipe_stdout != NULL) || (std_inheritance != 0)) | 983 | if ((pipe_stdin != NULL) || (pipe_stdout != NULL) || (std_inheritance != 0)) |
985 | start.dwFlags |= STARTF_USESTDHANDLES; | 984 | start.dwFlags |= STARTF_USESTDHANDLES; |
986 | 985 | ||
987 | stdih = GetStdHandle (STD_INPUT_HANDLE); | 986 | stdih = GetStdHandle(STD_INPUT_HANDLE); |
988 | GetHandleInformation (stdih, &stdif); | 987 | GetHandleInformation(stdih, &stdif); |
989 | if (pipe_stdin != NULL) | 988 | if (pipe_stdin != NULL) |
990 | { | 989 | { |
991 | GNUNET_DISK_internal_file_handle_ ( | 990 | GNUNET_DISK_internal_file_handle_( |
992 | GNUNET_DISK_pipe_handle (pipe_stdin, GNUNET_DISK_PIPE_END_READ), | 991 | GNUNET_DISK_pipe_handle(pipe_stdin, GNUNET_DISK_PIPE_END_READ), |
993 | &stdin_handle, | 992 | &stdin_handle, |
994 | sizeof (HANDLE)); | 993 | sizeof(HANDLE)); |
995 | start.hStdInput = stdin_handle; | 994 | start.hStdInput = stdin_handle; |
996 | } | 995 | } |
997 | else if (stdih) | 996 | else if (stdih) |
998 | { | ||
999 | if (std_inheritance & GNUNET_OS_INHERIT_STD_IN) | ||
1000 | { | 997 | { |
1001 | SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, 1); | 998 | if (std_inheritance & GNUNET_OS_INHERIT_STD_IN) |
1002 | if (pipe_stdin == NULL) | 999 | { |
1003 | start.hStdInput = stdih; | 1000 | SetHandleInformation(stdih, HANDLE_FLAG_INHERIT, 1); |
1001 | if (pipe_stdin == NULL) | ||
1002 | start.hStdInput = stdih; | ||
1003 | } | ||
1004 | else | ||
1005 | SetHandleInformation(stdih, HANDLE_FLAG_INHERIT, 0); | ||
1004 | } | 1006 | } |
1005 | else | ||
1006 | SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, 0); | ||
1007 | } | ||
1008 | 1007 | ||
1009 | 1008 | ||
1010 | stdoh = GetStdHandle (STD_OUTPUT_HANDLE); | 1009 | stdoh = GetStdHandle(STD_OUTPUT_HANDLE); |
1011 | GetHandleInformation (stdoh, &stdof); | 1010 | GetHandleInformation(stdoh, &stdof); |
1012 | if (NULL != pipe_stdout) | 1011 | if (NULL != pipe_stdout) |
1013 | { | 1012 | { |
1014 | GNUNET_DISK_internal_file_handle_ ( | 1013 | GNUNET_DISK_internal_file_handle_( |
1015 | GNUNET_DISK_pipe_handle (pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), | 1014 | GNUNET_DISK_pipe_handle(pipe_stdout, GNUNET_DISK_PIPE_END_WRITE), |
1016 | &stdout_handle, | 1015 | &stdout_handle, |
1017 | sizeof (HANDLE)); | 1016 | sizeof(HANDLE)); |
1018 | start.hStdOutput = stdout_handle; | 1017 | start.hStdOutput = stdout_handle; |
1019 | } | 1018 | } |
1020 | else if (stdoh) | 1019 | else if (stdoh) |
1021 | { | ||
1022 | if (std_inheritance & GNUNET_OS_INHERIT_STD_OUT) | ||
1023 | { | 1020 | { |
1024 | SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, 1); | 1021 | if (std_inheritance & GNUNET_OS_INHERIT_STD_OUT) |
1025 | if (pipe_stdout == NULL) | 1022 | { |
1026 | start.hStdOutput = stdoh; | 1023 | SetHandleInformation(stdoh, HANDLE_FLAG_INHERIT, 1); |
1024 | if (pipe_stdout == NULL) | ||
1025 | start.hStdOutput = stdoh; | ||
1026 | } | ||
1027 | else | ||
1028 | SetHandleInformation(stdoh, HANDLE_FLAG_INHERIT, 0); | ||
1027 | } | 1029 | } |
1028 | else | ||
1029 | SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, 0); | ||
1030 | } | ||
1031 | 1030 | ||
1032 | stdeh = GetStdHandle (STD_ERROR_HANDLE); | 1031 | stdeh = GetStdHandle(STD_ERROR_HANDLE); |
1033 | GetHandleInformation (stdeh, &stdef); | 1032 | GetHandleInformation(stdeh, &stdef); |
1034 | if (stdeh) | 1033 | if (stdeh) |
1035 | { | ||
1036 | if (std_inheritance & GNUNET_OS_INHERIT_STD_ERR) | ||
1037 | { | 1034 | { |
1038 | SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, 1); | 1035 | if (std_inheritance & GNUNET_OS_INHERIT_STD_ERR) |
1039 | start.hStdError = stdeh; | 1036 | { |
1037 | SetHandleInformation(stdeh, HANDLE_FLAG_INHERIT, 1); | ||
1038 | start.hStdError = stdeh; | ||
1039 | } | ||
1040 | else | ||
1041 | SetHandleInformation(stdeh, HANDLE_FLAG_INHERIT, 0); | ||
1040 | } | 1042 | } |
1041 | else | ||
1042 | SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, 0); | ||
1043 | } | ||
1044 | 1043 | ||
1045 | if (GNUNET_YES == pipe_control) | 1044 | if (GNUNET_YES == pipe_control) |
1046 | { | 1045 | { |
1047 | struct GNUNET_DISK_PipeHandle *childpipe; | 1046 | struct GNUNET_DISK_PipeHandle *childpipe; |
1048 | childpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); | 1047 | childpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); |
1049 | if (NULL == childpipe) | 1048 | if (NULL == childpipe) |
1050 | return NULL; | 1049 | return NULL; |
1051 | childpipe_read = | 1050 | childpipe_read = |
1052 | GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_READ); | 1051 | GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_READ); |
1053 | childpipe_write = | 1052 | childpipe_write = |
1054 | GNUNET_DISK_pipe_detach_end (childpipe, GNUNET_DISK_PIPE_END_WRITE); | 1053 | GNUNET_DISK_pipe_detach_end(childpipe, GNUNET_DISK_PIPE_END_WRITE); |
1055 | GNUNET_DISK_pipe_close (childpipe); | 1054 | GNUNET_DISK_pipe_close(childpipe); |
1056 | if ((NULL == childpipe_read) || (NULL == childpipe_write) || | 1055 | if ((NULL == childpipe_read) || (NULL == childpipe_write) || |
1057 | (GNUNET_OK != GNUNET_DISK_internal_file_handle_ (childpipe_read, | 1056 | (GNUNET_OK != GNUNET_DISK_internal_file_handle_(childpipe_read, |
1058 | &childpipe_read_handle, | 1057 | &childpipe_read_handle, |
1059 | sizeof (HANDLE)))) | 1058 | sizeof(HANDLE)))) |
1060 | { | 1059 | { |
1061 | if (childpipe_read) | 1060 | if (childpipe_read) |
1062 | GNUNET_DISK_file_close (childpipe_read); | 1061 | GNUNET_DISK_file_close(childpipe_read); |
1063 | if (childpipe_write) | 1062 | if (childpipe_write) |
1064 | GNUNET_DISK_file_close (childpipe_write); | 1063 | GNUNET_DISK_file_close(childpipe_write); |
1065 | GNUNET_free (cmd); | 1064 | GNUNET_free(cmd); |
1066 | return NULL; | 1065 | return NULL; |
1066 | } | ||
1067 | /* Unlike *nix variant, we don't dup the handle, so can't close | ||
1068 | * filehandle right now. | ||
1069 | */ | ||
1070 | SetHandleInformation(childpipe_read_handle, HANDLE_FLAG_INHERIT, 1); | ||
1067 | } | 1071 | } |
1068 | /* Unlike *nix variant, we don't dup the handle, so can't close | ||
1069 | * filehandle right now. | ||
1070 | */ | ||
1071 | SetHandleInformation (childpipe_read_handle, HANDLE_FLAG_INHERIT, 1); | ||
1072 | } | ||
1073 | else | 1072 | else |
1074 | { | 1073 | { |
1075 | childpipe_read = NULL; | 1074 | childpipe_read = NULL; |
1076 | childpipe_write = NULL; | 1075 | childpipe_write = NULL; |
1077 | } | 1076 | } |
1078 | 1077 | ||
1079 | if (lsocks != NULL && lsocks[0] != INVALID_SOCKET) | 1078 | if (lsocks != NULL && lsocks[0] != INVALID_SOCKET) |
1080 | { | ||
1081 | lsocks_pipe = | ||
1082 | GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); | ||
1083 | |||
1084 | if (lsocks_pipe == NULL) | ||
1085 | { | 1079 | { |
1086 | GNUNET_free (cmd); | 1080 | lsocks_pipe = |
1087 | GNUNET_DISK_pipe_close (lsocks_pipe); | 1081 | GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); |
1088 | if (GNUNET_YES == pipe_control) | 1082 | |
1089 | { | 1083 | if (lsocks_pipe == NULL) |
1090 | GNUNET_DISK_file_close (childpipe_write); | 1084 | { |
1091 | GNUNET_DISK_file_close (childpipe_read); | 1085 | GNUNET_free(cmd); |
1092 | } | 1086 | GNUNET_DISK_pipe_close(lsocks_pipe); |
1093 | return NULL; | 1087 | if (GNUNET_YES == pipe_control) |
1088 | { | ||
1089 | GNUNET_DISK_file_close(childpipe_write); | ||
1090 | GNUNET_DISK_file_close(childpipe_read); | ||
1091 | } | ||
1092 | return NULL; | ||
1093 | } | ||
1094 | lsocks_write_fd = | ||
1095 | GNUNET_DISK_pipe_handle(lsocks_pipe, GNUNET_DISK_PIPE_END_WRITE); | ||
1096 | GNUNET_DISK_internal_file_handle_(lsocks_write_fd, | ||
1097 | &lsocks_write, | ||
1098 | sizeof(HANDLE)); | ||
1099 | GNUNET_DISK_internal_file_handle_( | ||
1100 | GNUNET_DISK_pipe_handle(lsocks_pipe, GNUNET_DISK_PIPE_END_READ), | ||
1101 | &lsocks_read, | ||
1102 | sizeof(HANDLE)); | ||
1094 | } | 1103 | } |
1095 | lsocks_write_fd = | ||
1096 | GNUNET_DISK_pipe_handle (lsocks_pipe, GNUNET_DISK_PIPE_END_WRITE); | ||
1097 | GNUNET_DISK_internal_file_handle_ (lsocks_write_fd, | ||
1098 | &lsocks_write, | ||
1099 | sizeof (HANDLE)); | ||
1100 | GNUNET_DISK_internal_file_handle_ ( | ||
1101 | GNUNET_DISK_pipe_handle (lsocks_pipe, GNUNET_DISK_PIPE_END_READ), | ||
1102 | &lsocks_read, | ||
1103 | sizeof (HANDLE)); | ||
1104 | } | ||
1105 | else | 1104 | else |
1106 | { | 1105 | { |
1107 | lsocks_pipe = NULL; | 1106 | lsocks_pipe = NULL; |
1108 | lsocks_write_fd = NULL; | 1107 | lsocks_write_fd = NULL; |
1109 | } | 1108 | } |
1110 | 1109 | ||
1111 | env_off = 0; | 1110 | env_off = 0; |
1112 | if (GNUNET_YES == pipe_control) | 1111 | if (GNUNET_YES == pipe_control) |
1113 | { | 1112 | { |
1114 | GNUNET_asprintf (&our_env[env_off++], "%s=", GNUNET_OS_CONTROL_PIPE); | 1113 | GNUNET_asprintf(&our_env[env_off++], "%s=", GNUNET_OS_CONTROL_PIPE); |
1115 | GNUNET_asprintf (&our_env[env_off++], "%p", childpipe_read_handle); | 1114 | GNUNET_asprintf(&our_env[env_off++], "%p", childpipe_read_handle); |
1116 | } | 1115 | } |
1117 | if ((lsocks != NULL) && (lsocks[0] != INVALID_SOCKET)) | 1116 | if ((lsocks != NULL) && (lsocks[0] != INVALID_SOCKET)) |
1118 | { | 1117 | { |
1119 | /*This will tell the child that we're going to send lsocks over the pipe*/ | 1118 | /*This will tell the child that we're going to send lsocks over the pipe*/ |
1120 | GNUNET_asprintf (&our_env[env_off++], "%s=", "GNUNET_OS_READ_LSOCKS"); | 1119 | GNUNET_asprintf(&our_env[env_off++], "%s=", "GNUNET_OS_READ_LSOCKS"); |
1121 | GNUNET_asprintf (&our_env[env_off++], "%lu", lsocks_read); | 1120 | GNUNET_asprintf(&our_env[env_off++], "%lu", lsocks_read); |
1122 | } | 1121 | } |
1123 | our_env[env_off++] = NULL; | 1122 | our_env[env_off++] = NULL; |
1124 | env_block = CreateCustomEnvTable (our_env); | 1123 | env_block = CreateCustomEnvTable(our_env); |
1125 | while (0 > env_off) | 1124 | while (0 > env_off) |
1126 | GNUNET_free_non_null (our_env[--env_off]); | 1125 | GNUNET_free_non_null(our_env[--env_off]); |
1127 | 1126 | ||
1128 | wpath_len = 0; | 1127 | wpath_len = 0; |
1129 | if (NULL == | 1128 | if (NULL == |
1130 | (wpath = | 1129 | (wpath = |
1131 | u8_to_u16 ((uint8_t *) path, 1 + strlen (path), NULL, &wpath_len))) | 1130 | u8_to_u16((uint8_t *)path, 1 + strlen(path), NULL, &wpath_len))) |
1132 | { | 1131 | { |
1133 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1132 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
1134 | "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", | 1133 | "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", |
1135 | path, | 1134 | path, |
1136 | errno); | 1135 | errno); |
1137 | GNUNET_free (env_block); | 1136 | GNUNET_free(env_block); |
1138 | GNUNET_free (cmd); | 1137 | GNUNET_free(cmd); |
1139 | if (lsocks_pipe) | 1138 | if (lsocks_pipe) |
1140 | GNUNET_DISK_pipe_close (lsocks_pipe); | 1139 | GNUNET_DISK_pipe_close(lsocks_pipe); |
1141 | if (GNUNET_YES == pipe_control) | 1140 | if (GNUNET_YES == pipe_control) |
1142 | { | 1141 | { |
1143 | GNUNET_DISK_file_close (childpipe_write); | 1142 | GNUNET_DISK_file_close(childpipe_write); |
1144 | GNUNET_DISK_file_close (childpipe_read); | 1143 | GNUNET_DISK_file_close(childpipe_read); |
1144 | } | ||
1145 | return NULL; | ||
1145 | } | 1146 | } |
1146 | return NULL; | ||
1147 | } | ||
1148 | 1147 | ||
1149 | wcmd_len = 0; | 1148 | wcmd_len = 0; |
1150 | if (NULL == | 1149 | if (NULL == |
1151 | (wcmd = u8_to_u16 ((uint8_t *) cmd, 1 + strlen (cmd), NULL, &wcmd_len))) | 1150 | (wcmd = u8_to_u16((uint8_t *)cmd, 1 + strlen(cmd), NULL, &wcmd_len))) |
1152 | { | 1151 | { |
1153 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1152 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
1154 | "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", | 1153 | "Failed to convert `%s' from UTF-8 to UTF-16: %d\n", |
1155 | cmd, | 1154 | cmd, |
1156 | errno); | 1155 | errno); |
1157 | GNUNET_free (env_block); | 1156 | GNUNET_free(env_block); |
1158 | GNUNET_free (cmd); | 1157 | GNUNET_free(cmd); |
1159 | free (wpath); | 1158 | free(wpath); |
1160 | if (lsocks_pipe) | 1159 | if (lsocks_pipe) |
1161 | GNUNET_DISK_pipe_close (lsocks_pipe); | 1160 | GNUNET_DISK_pipe_close(lsocks_pipe); |
1162 | if (GNUNET_YES == pipe_control) | 1161 | if (GNUNET_YES == pipe_control) |
1163 | { | 1162 | { |
1164 | GNUNET_DISK_file_close (childpipe_write); | 1163 | GNUNET_DISK_file_close(childpipe_write); |
1165 | GNUNET_DISK_file_close (childpipe_read); | 1164 | GNUNET_DISK_file_close(childpipe_read); |
1165 | } | ||
1166 | return NULL; | ||
1166 | } | 1167 | } |
1167 | return NULL; | ||
1168 | } | ||
1169 | 1168 | ||
1170 | create_no_window = 0; | 1169 | create_no_window = 0; |
1171 | { | 1170 | { |
1172 | HANDLE console_input = CreateFile ("CONIN$", | 1171 | HANDLE console_input = CreateFile("CONIN$", |
1173 | GENERIC_READ, | 1172 | GENERIC_READ, |
1174 | FILE_SHARE_READ | FILE_SHARE_WRITE, | 1173 | FILE_SHARE_READ | FILE_SHARE_WRITE, |
1175 | NULL, | 1174 | NULL, |
1176 | OPEN_EXISTING, | 1175 | OPEN_EXISTING, |
1177 | 0, | 1176 | 0, |
1178 | NULL); | 1177 | NULL); |
1179 | if (INVALID_HANDLE_VALUE == console_input) | 1178 | if (INVALID_HANDLE_VALUE == console_input) |
1180 | create_no_window = CREATE_NO_WINDOW; | 1179 | create_no_window = CREATE_NO_WINDOW; |
1181 | else | 1180 | else |
1182 | CloseHandle (console_input); | 1181 | CloseHandle(console_input); |
1183 | } | 1182 | } |
1184 | 1183 | ||
1185 | bresult = CreateProcessW (wpath, | 1184 | bresult = CreateProcessW(wpath, |
1186 | wcmd, | 1185 | wcmd, |
1187 | NULL, | 1186 | NULL, |
1188 | NULL, | 1187 | NULL, |
1189 | GNUNET_YES, | 1188 | GNUNET_YES, |
1190 | create_no_window | CREATE_SUSPENDED, | 1189 | create_no_window | CREATE_SUSPENDED, |
1191 | env_block, | 1190 | env_block, |
1192 | NULL, | 1191 | NULL, |
1193 | &start, | 1192 | &start, |
1194 | &proc); | 1193 | &proc); |
1195 | error_code = GetLastError (); | 1194 | error_code = GetLastError(); |
1196 | 1195 | ||
1197 | if ((NULL == pipe_stdin) && (stdih)) | 1196 | if ((NULL == pipe_stdin) && (stdih)) |
1198 | SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, stdif); | 1197 | SetHandleInformation(stdih, HANDLE_FLAG_INHERIT, stdif); |
1199 | 1198 | ||
1200 | 1199 | ||
1201 | if ((NULL == pipe_stdout) && (stdoh)) | 1200 | if ((NULL == pipe_stdout) && (stdoh)) |
1202 | SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, stdof); | 1201 | SetHandleInformation(stdoh, HANDLE_FLAG_INHERIT, stdof); |
1203 | 1202 | ||
1204 | if (stdeh) | 1203 | if (stdeh) |
1205 | SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, stdef); | 1204 | SetHandleInformation(stdeh, HANDLE_FLAG_INHERIT, stdef); |
1206 | 1205 | ||
1207 | if (! bresult) | 1206 | if (!bresult) |
1208 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1207 | LOG(GNUNET_ERROR_TYPE_ERROR, |
1209 | "CreateProcess(%s, %s) failed: %lu\n", | 1208 | "CreateProcess(%s, %s) failed: %lu\n", |
1210 | path, | 1209 | path, |
1211 | cmd, | 1210 | cmd, |
1212 | error_code); | 1211 | error_code); |
1213 | 1212 | ||
1214 | GNUNET_free (env_block); | 1213 | GNUNET_free(env_block); |
1215 | GNUNET_free (cmd); | 1214 | GNUNET_free(cmd); |
1216 | free (wpath); | 1215 | free(wpath); |
1217 | free (wcmd); | 1216 | free(wcmd); |
1218 | if (GNUNET_YES == pipe_control) | 1217 | if (GNUNET_YES == pipe_control) |
1219 | { | 1218 | { |
1220 | GNUNET_DISK_file_close (childpipe_read); | 1219 | GNUNET_DISK_file_close(childpipe_read); |
1221 | } | 1220 | } |
1222 | 1221 | ||
1223 | if (! bresult) | 1222 | if (!bresult) |
1224 | { | ||
1225 | if (GNUNET_YES == pipe_control) | ||
1226 | { | 1223 | { |
1227 | GNUNET_DISK_file_close (childpipe_write); | 1224 | if (GNUNET_YES == pipe_control) |
1225 | { | ||
1226 | GNUNET_DISK_file_close(childpipe_write); | ||
1227 | } | ||
1228 | if (NULL != lsocks) | ||
1229 | GNUNET_DISK_pipe_close(lsocks_pipe); | ||
1230 | SetErrnoFromWinError(error_code); | ||
1231 | return NULL; | ||
1228 | } | 1232 | } |
1229 | if (NULL != lsocks) | ||
1230 | GNUNET_DISK_pipe_close (lsocks_pipe); | ||
1231 | SetErrnoFromWinError (error_code); | ||
1232 | return NULL; | ||
1233 | } | ||
1234 | 1233 | ||
1235 | gnunet_proc = GNUNET_new (struct GNUNET_OS_Process); | 1234 | gnunet_proc = GNUNET_new(struct GNUNET_OS_Process); |
1236 | gnunet_proc->pid = proc.dwProcessId; | 1235 | gnunet_proc->pid = proc.dwProcessId; |
1237 | gnunet_proc->handle = proc.hProcess; | 1236 | gnunet_proc->handle = proc.hProcess; |
1238 | gnunet_proc->control_pipe = childpipe_write; | 1237 | gnunet_proc->control_pipe = childpipe_write; |
1239 | 1238 | ||
1240 | CreateThread (NULL, 64000, &child_wait_thread, (void *) gnunet_proc, 0, NULL); | 1239 | CreateThread(NULL, 64000, &child_wait_thread, (void *)gnunet_proc, 0, NULL); |
1241 | 1240 | ||
1242 | ResumeThread (proc.hThread); | 1241 | ResumeThread(proc.hThread); |
1243 | CloseHandle (proc.hThread); | 1242 | CloseHandle(proc.hThread); |
1244 | 1243 | ||
1245 | if ((NULL == lsocks) || (INVALID_SOCKET == lsocks[0])) | 1244 | if ((NULL == lsocks) || (INVALID_SOCKET == lsocks[0])) |
1246 | return gnunet_proc; | 1245 | return gnunet_proc; |
1247 | 1246 | ||
1248 | GNUNET_DISK_pipe_close_end (lsocks_pipe, GNUNET_DISK_PIPE_END_READ); | 1247 | GNUNET_DISK_pipe_close_end(lsocks_pipe, GNUNET_DISK_PIPE_END_READ); |
1249 | 1248 | ||
1250 | /* This is a replacement for "goto error" that doesn't use goto */ | 1249 | /* This is a replacement for "goto error" that doesn't use goto */ |
1251 | fail = 1; | 1250 | fail = 1; |
1252 | do | 1251 | do |
1253 | { | 1252 | { |
1254 | ssize_t wrote; | 1253 | ssize_t wrote; |
1255 | uint64_t size; | 1254 | uint64_t size; |
1256 | uint64_t count; | 1255 | uint64_t count; |
1257 | unsigned int i; | 1256 | unsigned int i; |
1258 | 1257 | ||
1259 | /* Tell the number of sockets */ | 1258 | /* Tell the number of sockets */ |
1260 | for (count = 0; lsocks && lsocks[count] != INVALID_SOCKET; count++) | 1259 | for (count = 0; lsocks && lsocks[count] != INVALID_SOCKET; count++) |
1261 | ; | 1260 | ; |
1262 | 1261 | ||
1263 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count)); | 1262 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &count, sizeof(count)); |
1264 | if (sizeof (count) != wrote) | 1263 | if (sizeof(count) != wrote) |
1265 | { | 1264 | { |
1266 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1265 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
1267 | "Failed to write %u count bytes to the child: %lu\n", | 1266 | "Failed to write %u count bytes to the child: %lu\n", |
1268 | sizeof (count), | 1267 | sizeof(count), |
1269 | GetLastError ()); | 1268 | GetLastError()); |
1270 | break; | 1269 | break; |
1271 | } | 1270 | } |
1272 | for (i = 0; lsocks && lsocks[i] != INVALID_SOCKET; i++) | 1271 | for (i = 0; lsocks && lsocks[i] != INVALID_SOCKET; i++) |
1273 | { | 1272 | { |
1274 | WSAPROTOCOL_INFOA pi; | 1273 | WSAPROTOCOL_INFOA pi; |
1275 | /* Get a socket duplication info */ | 1274 | /* Get a socket duplication info */ |
1276 | if (SOCKET_ERROR == | 1275 | if (SOCKET_ERROR == |
1277 | WSADuplicateSocketA (lsocks[i], gnunet_proc->pid, &pi)) | 1276 | WSADuplicateSocketA(lsocks[i], gnunet_proc->pid, &pi)) |
1278 | { | 1277 | { |
1279 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1278 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
1280 | "Failed to duplicate an socket[%u]: %lu\n", | 1279 | "Failed to duplicate an socket[%u]: %lu\n", |
1281 | i, | 1280 | i, |
1282 | GetLastError ()); | 1281 | GetLastError()); |
1283 | break; | 1282 | break; |
1284 | } | 1283 | } |
1285 | /* Synchronous I/O is not nice, but we can't schedule this: | 1284 | /* Synchronous I/O is not nice, but we can't schedule this: |
1286 | * lsocks will be closed/freed by the caller soon, and until | 1285 | * lsocks will be closed/freed by the caller soon, and until |
1287 | * the child creates a duplicate, closing a socket here will | 1286 | * the child creates a duplicate, closing a socket here will |
1288 | * close it for good. | 1287 | * close it for good. |
1289 | */ | 1288 | */ |
1290 | /* Send the size of the structure | 1289 | /* Send the size of the structure |
1291 | * (the child might be built with different headers...) | 1290 | * (the child might be built with different headers...) |
1291 | */ | ||
1292 | size = sizeof(pi); | ||
1293 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &size, sizeof(size)); | ||
1294 | if (sizeof(size) != wrote) | ||
1295 | { | ||
1296 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1297 | "Failed to write %u size[%u] bytes to the child: %lu\n", | ||
1298 | sizeof(size), | ||
1299 | i, | ||
1300 | GetLastError()); | ||
1301 | break; | ||
1302 | } | ||
1303 | /* Finally! Send the data */ | ||
1304 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &pi, sizeof(pi)); | ||
1305 | if (sizeof(pi) != wrote) | ||
1306 | { | ||
1307 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1308 | "Failed to write %u socket[%u] bytes to the child: %lu\n", | ||
1309 | sizeof(pi), | ||
1310 | i, | ||
1311 | GetLastError()); | ||
1312 | break; | ||
1313 | } | ||
1314 | } | ||
1315 | /* This will block us until the child makes a final read or closes | ||
1316 | * the pipe (hence no 'wrote' check), since we have to wait for it | ||
1317 | * to duplicate the last socket, before we return and start closing | ||
1318 | * our own copies) | ||
1292 | */ | 1319 | */ |
1293 | size = sizeof (pi); | 1320 | wrote = GNUNET_DISK_file_write(lsocks_write_fd, &count, sizeof(count)); |
1294 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &size, sizeof (size)); | 1321 | fail = 0; |
1295 | if (sizeof (size) != wrote) | ||
1296 | { | ||
1297 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1298 | "Failed to write %u size[%u] bytes to the child: %lu\n", | ||
1299 | sizeof (size), | ||
1300 | i, | ||
1301 | GetLastError ()); | ||
1302 | break; | ||
1303 | } | ||
1304 | /* Finally! Send the data */ | ||
1305 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &pi, sizeof (pi)); | ||
1306 | if (sizeof (pi) != wrote) | ||
1307 | { | ||
1308 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1309 | "Failed to write %u socket[%u] bytes to the child: %lu\n", | ||
1310 | sizeof (pi), | ||
1311 | i, | ||
1312 | GetLastError ()); | ||
1313 | break; | ||
1314 | } | ||
1315 | } | 1322 | } |
1316 | /* This will block us until the child makes a final read or closes | 1323 | while (fail); |
1317 | * the pipe (hence no 'wrote' check), since we have to wait for it | ||
1318 | * to duplicate the last socket, before we return and start closing | ||
1319 | * our own copies) | ||
1320 | */ | ||
1321 | wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count)); | ||
1322 | fail = 0; | ||
1323 | } while (fail); | ||
1324 | 1324 | ||
1325 | GNUNET_DISK_file_sync (lsocks_write_fd); | 1325 | GNUNET_DISK_file_sync(lsocks_write_fd); |
1326 | GNUNET_DISK_pipe_close (lsocks_pipe); | 1326 | GNUNET_DISK_pipe_close(lsocks_pipe); |
1327 | 1327 | ||
1328 | if (fail) | 1328 | if (fail) |
1329 | { | 1329 | { |
1330 | /* If we can't pass on the socket(s), the child will block forever, | 1330 | /* If we can't pass on the socket(s), the child will block forever, |
1331 | * better put it out of its misery. | 1331 | * better put it out of its misery. |
1332 | */ | 1332 | */ |
1333 | SafeTerminateProcess (gnunet_proc->handle, 0, 0); | 1333 | SafeTerminateProcess(gnunet_proc->handle, 0, 0); |
1334 | CloseHandle (gnunet_proc->handle); | 1334 | CloseHandle(gnunet_proc->handle); |
1335 | if (NULL != gnunet_proc->control_pipe) | 1335 | if (NULL != gnunet_proc->control_pipe) |
1336 | GNUNET_DISK_file_close (gnunet_proc->control_pipe); | 1336 | GNUNET_DISK_file_close(gnunet_proc->control_pipe); |
1337 | GNUNET_free (gnunet_proc); | 1337 | GNUNET_free(gnunet_proc); |
1338 | return NULL; | 1338 | return NULL; |
1339 | } | 1339 | } |
1340 | return gnunet_proc; | 1340 | return gnunet_proc; |
1341 | #endif | 1341 | #endif |
1342 | } | 1342 | } |
@@ -1355,22 +1355,22 @@ start_process (int pipe_control, | |||
1355 | * @return pointer to process structure of the new process, NULL on error | 1355 | * @return pointer to process structure of the new process, NULL on error |
1356 | */ | 1356 | */ |
1357 | struct GNUNET_OS_Process * | 1357 | struct GNUNET_OS_Process * |
1358 | GNUNET_OS_start_process_vap (int pipe_control, | 1358 | GNUNET_OS_start_process_vap(int pipe_control, |
1359 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | 1359 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
1360 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 1360 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
1361 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 1361 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
1362 | struct GNUNET_DISK_PipeHandle *pipe_stderr, | 1362 | struct GNUNET_DISK_PipeHandle *pipe_stderr, |
1363 | const char *filename, | 1363 | const char *filename, |
1364 | char *const argv[]) | 1364 | char *const argv[]) |
1365 | { | 1365 | { |
1366 | return start_process (pipe_control, | 1366 | return start_process(pipe_control, |
1367 | std_inheritance, | 1367 | std_inheritance, |
1368 | pipe_stdin, | 1368 | pipe_stdin, |
1369 | pipe_stdout, | 1369 | pipe_stdout, |
1370 | pipe_stderr, | 1370 | pipe_stderr, |
1371 | NULL, | 1371 | NULL, |
1372 | filename, | 1372 | filename, |
1373 | argv); | 1373 | argv); |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | 1376 | ||
@@ -1387,13 +1387,13 @@ GNUNET_OS_start_process_vap (int pipe_control, | |||
1387 | * @return pointer to process structure of the new process, NULL on error | 1387 | * @return pointer to process structure of the new process, NULL on error |
1388 | */ | 1388 | */ |
1389 | struct GNUNET_OS_Process * | 1389 | struct GNUNET_OS_Process * |
1390 | GNUNET_OS_start_process_va (int pipe_control, | 1390 | GNUNET_OS_start_process_va(int pipe_control, |
1391 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | 1391 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
1392 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 1392 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
1393 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 1393 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
1394 | struct GNUNET_DISK_PipeHandle *pipe_stderr, | 1394 | struct GNUNET_DISK_PipeHandle *pipe_stderr, |
1395 | const char *filename, | 1395 | const char *filename, |
1396 | va_list va) | 1396 | va_list va) |
1397 | { | 1397 | { |
1398 | struct GNUNET_OS_Process *ret; | 1398 | struct GNUNET_OS_Process *ret; |
1399 | va_list ap; | 1399 | va_list ap; |
@@ -1401,24 +1401,24 @@ GNUNET_OS_start_process_va (int pipe_control, | |||
1401 | int argc; | 1401 | int argc; |
1402 | 1402 | ||
1403 | argc = 0; | 1403 | argc = 0; |
1404 | va_copy (ap, va); | 1404 | va_copy(ap, va); |
1405 | while (NULL != va_arg (ap, char *)) | 1405 | while (NULL != va_arg(ap, char *)) |
1406 | argc++; | 1406 | argc++; |
1407 | va_end (ap); | 1407 | va_end(ap); |
1408 | argv = GNUNET_malloc (sizeof (char *) * (argc + 1)); | 1408 | argv = GNUNET_malloc(sizeof(char *) * (argc + 1)); |
1409 | argc = 0; | 1409 | argc = 0; |
1410 | va_copy (ap, va); | 1410 | va_copy(ap, va); |
1411 | while (NULL != (argv[argc] = va_arg (ap, char *))) | 1411 | while (NULL != (argv[argc] = va_arg(ap, char *))) |
1412 | argc++; | 1412 | argc++; |
1413 | va_end (ap); | 1413 | va_end(ap); |
1414 | ret = GNUNET_OS_start_process_vap (pipe_control, | 1414 | ret = GNUNET_OS_start_process_vap(pipe_control, |
1415 | std_inheritance, | 1415 | std_inheritance, |
1416 | pipe_stdin, | 1416 | pipe_stdin, |
1417 | pipe_stdout, | 1417 | pipe_stdout, |
1418 | pipe_stderr, | 1418 | pipe_stderr, |
1419 | filename, | 1419 | filename, |
1420 | argv); | 1420 | argv); |
1421 | GNUNET_free (argv); | 1421 | GNUNET_free(argv); |
1422 | return ret; | 1422 | return ret; |
1423 | } | 1423 | } |
1424 | 1424 | ||
@@ -1435,26 +1435,26 @@ GNUNET_OS_start_process_va (int pipe_control, | |||
1435 | * @return pointer to process structure of the new process, NULL on error | 1435 | * @return pointer to process structure of the new process, NULL on error |
1436 | */ | 1436 | */ |
1437 | struct GNUNET_OS_Process * | 1437 | struct GNUNET_OS_Process * |
1438 | GNUNET_OS_start_process (int pipe_control, | 1438 | GNUNET_OS_start_process(int pipe_control, |
1439 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | 1439 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
1440 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 1440 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
1441 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 1441 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
1442 | struct GNUNET_DISK_PipeHandle *pipe_stderr, | 1442 | struct GNUNET_DISK_PipeHandle *pipe_stderr, |
1443 | const char *filename, | 1443 | const char *filename, |
1444 | ...) | 1444 | ...) |
1445 | { | 1445 | { |
1446 | struct GNUNET_OS_Process *ret; | 1446 | struct GNUNET_OS_Process *ret; |
1447 | va_list ap; | 1447 | va_list ap; |
1448 | 1448 | ||
1449 | va_start (ap, filename); | 1449 | va_start(ap, filename); |
1450 | ret = GNUNET_OS_start_process_va (pipe_control, | 1450 | ret = GNUNET_OS_start_process_va(pipe_control, |
1451 | std_inheritance, | 1451 | std_inheritance, |
1452 | pipe_stdin, | 1452 | pipe_stdin, |
1453 | pipe_stdout, | 1453 | pipe_stdout, |
1454 | pipe_stderr, | 1454 | pipe_stderr, |
1455 | filename, | 1455 | filename, |
1456 | ap); | 1456 | ap); |
1457 | va_end (ap); | 1457 | va_end(ap); |
1458 | return ret; | 1458 | return ret; |
1459 | } | 1459 | } |
1460 | 1460 | ||
@@ -1474,20 +1474,20 @@ GNUNET_OS_start_process (int pipe_control, | |||
1474 | * @return process ID of the new process, -1 on error | 1474 | * @return process ID of the new process, -1 on error |
1475 | */ | 1475 | */ |
1476 | struct GNUNET_OS_Process * | 1476 | struct GNUNET_OS_Process * |
1477 | GNUNET_OS_start_process_v (int pipe_control, | 1477 | GNUNET_OS_start_process_v(int pipe_control, |
1478 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | 1478 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
1479 | const SOCKTYPE *lsocks, | 1479 | const SOCKTYPE *lsocks, |
1480 | const char *filename, | 1480 | const char *filename, |
1481 | char *const argv[]) | 1481 | char *const argv[]) |
1482 | { | 1482 | { |
1483 | return start_process (pipe_control, | 1483 | return start_process(pipe_control, |
1484 | std_inheritance, | 1484 | std_inheritance, |
1485 | NULL, | 1485 | NULL, |
1486 | NULL, | 1486 | NULL, |
1487 | NULL, | 1487 | NULL, |
1488 | lsocks, | 1488 | lsocks, |
1489 | filename, | 1489 | filename, |
1490 | argv); | 1490 | argv); |
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | 1493 | ||
@@ -1510,11 +1510,11 @@ GNUNET_OS_start_process_v (int pipe_control, | |||
1510 | * @return pointer to process structure of the new process, NULL on error | 1510 | * @return pointer to process structure of the new process, NULL on error |
1511 | */ | 1511 | */ |
1512 | struct GNUNET_OS_Process * | 1512 | struct GNUNET_OS_Process * |
1513 | GNUNET_OS_start_process_s (int pipe_control, | 1513 | GNUNET_OS_start_process_s(int pipe_control, |
1514 | unsigned int std_inheritance, | 1514 | unsigned int std_inheritance, |
1515 | const SOCKTYPE *lsocks, | 1515 | const SOCKTYPE *lsocks, |
1516 | const char *filename, | 1516 | const char *filename, |
1517 | ...) | 1517 | ...) |
1518 | { | 1518 | { |
1519 | va_list ap; | 1519 | va_list ap; |
1520 | char **argv; | 1520 | char **argv; |
@@ -1531,101 +1531,103 @@ GNUNET_OS_start_process_s (int pipe_control, | |||
1531 | size_t len; | 1531 | size_t len; |
1532 | 1532 | ||
1533 | argv_size = 1; | 1533 | argv_size = 1; |
1534 | va_start (ap, filename); | 1534 | va_start(ap, filename); |
1535 | arg = filename; | 1535 | arg = filename; |
1536 | last = NULL; | 1536 | last = NULL; |
1537 | do | 1537 | do |
1538 | { | ||
1539 | rpos = arg; | ||
1540 | quote_on = 0; | ||
1541 | while ('\0' != *rpos) | ||
1542 | { | 1538 | { |
1543 | if ('"' == *rpos) | 1539 | rpos = arg; |
1544 | { | 1540 | quote_on = 0; |
1545 | if (1 == quote_on) | 1541 | while ('\0' != *rpos) |
1546 | quote_on = 0; | 1542 | { |
1547 | else | 1543 | if ('"' == *rpos) |
1548 | quote_on = 1; | 1544 | { |
1549 | } | 1545 | if (1 == quote_on) |
1550 | if ((' ' == *rpos) && (0 == quote_on)) | 1546 | quote_on = 0; |
1551 | { | 1547 | else |
1552 | if (NULL != last) | 1548 | quote_on = 1; |
1553 | argv_size++; | 1549 | } |
1554 | last = NULL; | 1550 | if ((' ' == *rpos) && (0 == quote_on)) |
1555 | rpos++; | 1551 | { |
1556 | while (' ' == *rpos) | 1552 | if (NULL != last) |
1557 | rpos++; | 1553 | argv_size++; |
1558 | } | 1554 | last = NULL; |
1559 | if ((NULL == last) && ('\0' != *rpos)) // FIXME: == or !=? | 1555 | rpos++; |
1560 | last = rpos; | 1556 | while (' ' == *rpos) |
1561 | if ('\0' != *rpos) | 1557 | rpos++; |
1562 | rpos++; | 1558 | } |
1559 | if ((NULL == last) && ('\0' != *rpos)) // FIXME: == or !=? | ||
1560 | last = rpos; | ||
1561 | if ('\0' != *rpos) | ||
1562 | rpos++; | ||
1563 | } | ||
1564 | if (NULL != last) | ||
1565 | argv_size++; | ||
1563 | } | 1566 | } |
1564 | if (NULL != last) | 1567 | while (NULL != (arg = (va_arg(ap, const char *)))); |
1565 | argv_size++; | 1568 | va_end(ap); |
1566 | } while (NULL != (arg = (va_arg (ap, const char *)))); | ||
1567 | va_end (ap); | ||
1568 | 1569 | ||
1569 | argv = GNUNET_malloc (argv_size * sizeof (char *)); | 1570 | argv = GNUNET_malloc(argv_size * sizeof(char *)); |
1570 | argv_size = 0; | 1571 | argv_size = 0; |
1571 | va_start (ap, filename); | 1572 | va_start(ap, filename); |
1572 | arg = filename; | 1573 | arg = filename; |
1573 | last = NULL; | 1574 | last = NULL; |
1574 | do | 1575 | do |
1575 | { | ||
1576 | cp = GNUNET_strdup (arg); | ||
1577 | quote_on = 0; | ||
1578 | pos = cp; | ||
1579 | while ('\0' != *pos) | ||
1580 | { | 1576 | { |
1581 | if ('"' == *pos) | 1577 | cp = GNUNET_strdup(arg); |
1582 | { | 1578 | quote_on = 0; |
1583 | if (1 == quote_on) | 1579 | pos = cp; |
1584 | quote_on = 0; | 1580 | while ('\0' != *pos) |
1585 | else | 1581 | { |
1586 | quote_on = 1; | 1582 | if ('"' == *pos) |
1587 | } | 1583 | { |
1588 | if ((' ' == *pos) && (0 == quote_on)) | 1584 | if (1 == quote_on) |
1589 | { | 1585 | quote_on = 0; |
1590 | *pos = '\0'; | 1586 | else |
1591 | if (NULL != last) | 1587 | quote_on = 1; |
1592 | argv[argv_size++] = GNUNET_strdup (last); | 1588 | } |
1593 | last = NULL; | 1589 | if ((' ' == *pos) && (0 == quote_on)) |
1594 | pos++; | 1590 | { |
1595 | while (' ' == *pos) | 1591 | *pos = '\0'; |
1596 | pos++; | 1592 | if (NULL != last) |
1597 | } | 1593 | argv[argv_size++] = GNUNET_strdup(last); |
1598 | if ((NULL == last) && ('\0' != *pos)) // FIXME: == or !=? | 1594 | last = NULL; |
1599 | last = pos; | 1595 | pos++; |
1600 | if ('\0' != *pos) | 1596 | while (' ' == *pos) |
1601 | pos++; | 1597 | pos++; |
1602 | } | 1598 | } |
1603 | if (NULL != last) | 1599 | if ((NULL == last) && ('\0' != *pos)) // FIXME: == or !=? |
1604 | argv[argv_size++] = GNUNET_strdup (last); | 1600 | last = pos; |
1605 | last = NULL; | 1601 | if ('\0' != *pos) |
1606 | GNUNET_free (cp); | 1602 | pos++; |
1607 | } while (NULL != (arg = (va_arg (ap, const char *)))); | 1603 | } |
1608 | va_end (ap); | 1604 | if (NULL != last) |
1605 | argv[argv_size++] = GNUNET_strdup(last); | ||
1606 | last = NULL; | ||
1607 | GNUNET_free(cp); | ||
1608 | } | ||
1609 | while (NULL != (arg = (va_arg(ap, const char *)))); | ||
1610 | va_end(ap); | ||
1609 | argv[argv_size] = NULL; | 1611 | argv[argv_size] = NULL; |
1610 | 1612 | ||
1611 | for (i = 0; i < argv_size; i++) | 1613 | for (i = 0; i < argv_size; i++) |
1612 | { | ||
1613 | len = strlen (argv[i]); | ||
1614 | if ((argv[i][0] == '"') && (argv[i][len - 1] == '"')) | ||
1615 | { | 1614 | { |
1616 | memmove (&argv[i][0], &argv[i][1], len - 2); | 1615 | len = strlen(argv[i]); |
1617 | argv[i][len - 2] = '\0'; | 1616 | if ((argv[i][0] == '"') && (argv[i][len - 1] == '"')) |
1617 | { | ||
1618 | memmove(&argv[i][0], &argv[i][1], len - 2); | ||
1619 | argv[i][len - 2] = '\0'; | ||
1620 | } | ||
1618 | } | 1621 | } |
1619 | } | ||
1620 | binary_path = argv[0]; | 1622 | binary_path = argv[0]; |
1621 | proc = GNUNET_OS_start_process_v (pipe_control, | 1623 | proc = GNUNET_OS_start_process_v(pipe_control, |
1622 | std_inheritance, | 1624 | std_inheritance, |
1623 | lsocks, | 1625 | lsocks, |
1624 | binary_path, | 1626 | binary_path, |
1625 | argv); | 1627 | argv); |
1626 | while (argv_size > 0) | 1628 | while (argv_size > 0) |
1627 | GNUNET_free (argv[--argv_size]); | 1629 | GNUNET_free(argv[--argv_size]); |
1628 | GNUNET_free (argv); | 1630 | GNUNET_free(argv); |
1629 | return proc; | 1631 | return proc; |
1630 | } | 1632 | } |
1631 | 1633 | ||
@@ -1641,60 +1643,60 @@ GNUNET_OS_start_process_s (int pipe_control, | |||
1641 | * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise | 1643 | * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise |
1642 | */ | 1644 | */ |
1643 | static int | 1645 | static int |
1644 | process_status (struct GNUNET_OS_Process *proc, | 1646 | process_status(struct GNUNET_OS_Process *proc, |
1645 | enum GNUNET_OS_ProcessStatusType *type, | 1647 | enum GNUNET_OS_ProcessStatusType *type, |
1646 | unsigned long *code, | 1648 | unsigned long *code, |
1647 | int options) | 1649 | int options) |
1648 | { | 1650 | { |
1649 | #ifndef MINGW | 1651 | #ifndef MINGW |
1650 | int status; | 1652 | int status; |
1651 | int ret; | 1653 | int ret; |
1652 | 1654 | ||
1653 | GNUNET_assert (0 != proc); | 1655 | GNUNET_assert(0 != proc); |
1654 | ret = waitpid (proc->pid, &status, options); | 1656 | ret = waitpid(proc->pid, &status, options); |
1655 | if (ret < 0) | 1657 | if (ret < 0) |
1656 | { | 1658 | { |
1657 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid"); | 1659 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "waitpid"); |
1658 | return GNUNET_SYSERR; | 1660 | return GNUNET_SYSERR; |
1659 | } | 1661 | } |
1660 | if (0 == ret) | 1662 | if (0 == ret) |
1661 | { | 1663 | { |
1662 | *type = GNUNET_OS_PROCESS_RUNNING; | 1664 | *type = GNUNET_OS_PROCESS_RUNNING; |
1663 | *code = 0; | 1665 | *code = 0; |
1664 | return GNUNET_NO; | 1666 | return GNUNET_NO; |
1665 | } | 1667 | } |
1666 | if (proc->pid != ret) | 1668 | if (proc->pid != ret) |
1667 | { | 1669 | { |
1668 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid"); | 1670 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "waitpid"); |
1669 | return GNUNET_SYSERR; | 1671 | return GNUNET_SYSERR; |
1670 | } | 1672 | } |
1671 | if (WIFEXITED (status)) | 1673 | if (WIFEXITED(status)) |
1672 | { | 1674 | { |
1673 | *type = GNUNET_OS_PROCESS_EXITED; | 1675 | *type = GNUNET_OS_PROCESS_EXITED; |
1674 | *code = WEXITSTATUS (status); | 1676 | *code = WEXITSTATUS(status); |
1675 | } | 1677 | } |
1676 | else if (WIFSIGNALED (status)) | 1678 | else if (WIFSIGNALED(status)) |
1677 | { | 1679 | { |
1678 | *type = GNUNET_OS_PROCESS_SIGNALED; | 1680 | *type = GNUNET_OS_PROCESS_SIGNALED; |
1679 | *code = WTERMSIG (status); | 1681 | *code = WTERMSIG(status); |
1680 | } | 1682 | } |
1681 | else if (WIFSTOPPED (status)) | 1683 | else if (WIFSTOPPED(status)) |
1682 | { | 1684 | { |
1683 | *type = GNUNET_OS_PROCESS_SIGNALED; | 1685 | *type = GNUNET_OS_PROCESS_SIGNALED; |
1684 | *code = WSTOPSIG (status); | 1686 | *code = WSTOPSIG(status); |
1685 | } | 1687 | } |
1686 | #ifdef WIFCONTINUED | 1688 | #ifdef WIFCONTINUED |
1687 | else if (WIFCONTINUED (status)) | 1689 | else if (WIFCONTINUED(status)) |
1688 | { | 1690 | { |
1689 | *type = GNUNET_OS_PROCESS_RUNNING; | 1691 | *type = GNUNET_OS_PROCESS_RUNNING; |
1690 | *code = 0; | 1692 | *code = 0; |
1691 | } | 1693 | } |
1692 | #endif | 1694 | #endif |
1693 | else | 1695 | else |
1694 | { | 1696 | { |
1695 | *type = GNUNET_OS_PROCESS_UNKNOWN; | 1697 | *type = GNUNET_OS_PROCESS_UNKNOWN; |
1696 | *code = 0; | 1698 | *code = 0; |
1697 | } | 1699 | } |
1698 | #else | 1700 | #else |
1699 | #ifndef WNOHANG | 1701 | #ifndef WNOHANG |
1700 | #define WNOHANG 42 /* just a flag for W32, purely internal at this point */ | 1702 | #define WNOHANG 42 /* just a flag for W32, purely internal at this point */ |
@@ -1706,39 +1708,39 @@ process_status (struct GNUNET_OS_Process *proc, | |||
1706 | h = proc->handle; | 1708 | h = proc->handle; |
1707 | ret = proc->pid; | 1709 | ret = proc->pid; |
1708 | if (h == NULL || ret == 0) | 1710 | if (h == NULL || ret == 0) |
1709 | { | 1711 | { |
1710 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1712 | LOG(GNUNET_ERROR_TYPE_WARNING, |
1711 | "Invalid process information {%d, %08X}\n", | 1713 | "Invalid process information {%d, %08X}\n", |
1712 | ret, | 1714 | ret, |
1713 | h); | 1715 | h); |
1714 | return GNUNET_SYSERR; | 1716 | return GNUNET_SYSERR; |
1715 | } | 1717 | } |
1716 | if (h == NULL) | 1718 | if (h == NULL) |
1717 | h = GetCurrentProcess (); | 1719 | h = GetCurrentProcess(); |
1718 | 1720 | ||
1719 | if (WNOHANG != options) | 1721 | if (WNOHANG != options) |
1720 | { | ||
1721 | if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) | ||
1722 | { | 1722 | { |
1723 | SetErrnoFromWinError (GetLastError ()); | 1723 | if (WAIT_OBJECT_0 != WaitForSingleObject(h, INFINITE)) |
1724 | return GNUNET_SYSERR; | 1724 | { |
1725 | SetErrnoFromWinError(GetLastError()); | ||
1726 | return GNUNET_SYSERR; | ||
1727 | } | ||
1725 | } | 1728 | } |
1726 | } | 1729 | SetLastError(0); |
1727 | SetLastError (0); | 1730 | ret = GetExitCodeProcess(h, &c); |
1728 | ret = GetExitCodeProcess (h, &c); | 1731 | error_code = GetLastError(); |
1729 | error_code = GetLastError (); | ||
1730 | if (ret == 0 || error_code != NO_ERROR) | 1732 | if (ret == 0 || error_code != NO_ERROR) |
1731 | { | 1733 | { |
1732 | SetErrnoFromWinError (error_code); | 1734 | SetErrnoFromWinError(error_code); |
1733 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess"); | 1735 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess"); |
1734 | return GNUNET_SYSERR; | 1736 | return GNUNET_SYSERR; |
1735 | } | 1737 | } |
1736 | if (STILL_ACTIVE == c) | 1738 | if (STILL_ACTIVE == c) |
1737 | { | 1739 | { |
1738 | *type = GNUNET_OS_PROCESS_RUNNING; | 1740 | *type = GNUNET_OS_PROCESS_RUNNING; |
1739 | *code = 0; | 1741 | *code = 0; |
1740 | return GNUNET_NO; | 1742 | return GNUNET_NO; |
1741 | } | 1743 | } |
1742 | *type = GNUNET_OS_PROCESS_EXITED; | 1744 | *type = GNUNET_OS_PROCESS_EXITED; |
1743 | *code = c; | 1745 | *code = c; |
1744 | #endif | 1746 | #endif |
@@ -1757,11 +1759,11 @@ process_status (struct GNUNET_OS_Process *proc, | |||
1757 | * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise | 1759 | * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise |
1758 | */ | 1760 | */ |
1759 | int | 1761 | int |
1760 | GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, | 1762 | GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, |
1761 | enum GNUNET_OS_ProcessStatusType *type, | 1763 | enum GNUNET_OS_ProcessStatusType *type, |
1762 | unsigned long *code) | 1764 | unsigned long *code) |
1763 | { | 1765 | { |
1764 | return process_status (proc, type, code, WNOHANG); | 1766 | return process_status(proc, type, code, WNOHANG); |
1765 | } | 1767 | } |
1766 | 1768 | ||
1767 | 1769 | ||
@@ -1775,11 +1777,11 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, | |||
1775 | * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise | 1777 | * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise |
1776 | */ | 1778 | */ |
1777 | int | 1779 | int |
1778 | GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc, | 1780 | GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc, |
1779 | enum GNUNET_OS_ProcessStatusType *type, | 1781 | enum GNUNET_OS_ProcessStatusType *type, |
1780 | unsigned long *code) | 1782 | unsigned long *code) |
1781 | { | 1783 | { |
1782 | return process_status (proc, type, code, 0); | 1784 | return process_status(proc, type, code, 0); |
1783 | } | 1785 | } |
1784 | 1786 | ||
1785 | 1787 | ||
@@ -1794,40 +1796,40 @@ GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc, | |||
1794 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | 1796 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise |
1795 | */ | 1797 | */ |
1796 | int | 1798 | int |
1797 | GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc) | 1799 | GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc) |
1798 | { | 1800 | { |
1799 | #ifndef MINGW | 1801 | #ifndef MINGW |
1800 | pid_t pid = proc->pid; | 1802 | pid_t pid = proc->pid; |
1801 | pid_t ret; | 1803 | pid_t ret; |
1802 | 1804 | ||
1803 | while ((pid != (ret = waitpid (pid, NULL, 0))) && (EINTR == errno)) | 1805 | while ((pid != (ret = waitpid(pid, NULL, 0))) && (EINTR == errno)) |
1804 | ; | 1806 | ; |
1805 | if (pid != ret) | 1807 | if (pid != ret) |
1806 | { | 1808 | { |
1807 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "waitpid"); | 1809 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "waitpid"); |
1808 | return GNUNET_SYSERR; | 1810 | return GNUNET_SYSERR; |
1809 | } | 1811 | } |
1810 | return GNUNET_OK; | 1812 | return GNUNET_OK; |
1811 | #else | 1813 | #else |
1812 | HANDLE h; | 1814 | HANDLE h; |
1813 | 1815 | ||
1814 | h = proc->handle; | 1816 | h = proc->handle; |
1815 | if (NULL == h) | 1817 | if (NULL == h) |
1816 | { | 1818 | { |
1817 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1819 | LOG(GNUNET_ERROR_TYPE_WARNING, |
1818 | "Invalid process information {%d, %08X}\n", | 1820 | "Invalid process information {%d, %08X}\n", |
1819 | proc->pid, | 1821 | proc->pid, |
1820 | h); | 1822 | h); |
1821 | return GNUNET_SYSERR; | 1823 | return GNUNET_SYSERR; |
1822 | } | 1824 | } |
1823 | if (NULL == h) | 1825 | if (NULL == h) |
1824 | h = GetCurrentProcess (); | 1826 | h = GetCurrentProcess(); |
1825 | 1827 | ||
1826 | if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) | 1828 | if (WAIT_OBJECT_0 != WaitForSingleObject(h, INFINITE)) |
1827 | { | 1829 | { |
1828 | SetErrnoFromWinError (GetLastError ()); | 1830 | SetErrnoFromWinError(GetLastError()); |
1829 | return GNUNET_SYSERR; | 1831 | return GNUNET_SYSERR; |
1830 | } | 1832 | } |
1831 | return GNUNET_OK; | 1833 | return GNUNET_OK; |
1832 | #endif | 1834 | #endif |
1833 | } | 1835 | } |
@@ -1836,9 +1838,7 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc) | |||
1836 | /** | 1838 | /** |
1837 | * Handle to a command. | 1839 | * Handle to a command. |
1838 | */ | 1840 | */ |
1839 | struct GNUNET_OS_CommandHandle | 1841 | struct GNUNET_OS_CommandHandle { |
1840 | { | ||
1841 | |||
1842 | /** | 1842 | /** |
1843 | * Process handle. | 1843 | * Process handle. |
1844 | */ | 1844 | */ |
@@ -1894,18 +1894,18 @@ struct GNUNET_OS_CommandHandle | |||
1894 | * @param cmd handle to the process | 1894 | * @param cmd handle to the process |
1895 | */ | 1895 | */ |
1896 | void | 1896 | void |
1897 | GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd) | 1897 | GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd) |
1898 | { | 1898 | { |
1899 | if (NULL != cmd->proc) | 1899 | if (NULL != cmd->proc) |
1900 | { | 1900 | { |
1901 | GNUNET_assert (NULL != cmd->rtask); | 1901 | GNUNET_assert(NULL != cmd->rtask); |
1902 | GNUNET_SCHEDULER_cancel (cmd->rtask); | 1902 | GNUNET_SCHEDULER_cancel(cmd->rtask); |
1903 | } | 1903 | } |
1904 | (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL); | 1904 | (void)GNUNET_OS_process_kill(cmd->eip, SIGKILL); |
1905 | GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (cmd->eip)); | 1905 | GNUNET_break(GNUNET_OK == GNUNET_OS_process_wait(cmd->eip)); |
1906 | GNUNET_OS_process_destroy (cmd->eip); | 1906 | GNUNET_OS_process_destroy(cmd->eip); |
1907 | GNUNET_DISK_pipe_close (cmd->opipe); | 1907 | GNUNET_DISK_pipe_close(cmd->opipe); |
1908 | GNUNET_free (cmd); | 1908 | GNUNET_free(cmd); |
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | 1911 | ||
@@ -1915,7 +1915,7 @@ GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd) | |||
1915 | * @param cls the `struct GNUNET_OS_CommandHandle *` | 1915 | * @param cls the `struct GNUNET_OS_CommandHandle *` |
1916 | */ | 1916 | */ |
1917 | static void | 1917 | static void |
1918 | cmd_read (void *cls) | 1918 | cmd_read(void *cls) |
1919 | { | 1919 | { |
1920 | struct GNUNET_OS_CommandHandle *cmd = cls; | 1920 | struct GNUNET_OS_CommandHandle *cmd = cls; |
1921 | const struct GNUNET_SCHEDULER_TaskContext *tc; | 1921 | const struct GNUNET_SCHEDULER_TaskContext *tc; |
@@ -1924,46 +1924,46 @@ cmd_read (void *cls) | |||
1924 | ssize_t ret; | 1924 | ssize_t ret; |
1925 | 1925 | ||
1926 | cmd->rtask = NULL; | 1926 | cmd->rtask = NULL; |
1927 | tc = GNUNET_SCHEDULER_get_task_context (); | 1927 | tc = GNUNET_SCHEDULER_get_task_context(); |
1928 | if (GNUNET_YES != GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, cmd->r)) | 1928 | if (GNUNET_YES != GNUNET_NETWORK_fdset_handle_isset(tc->read_ready, cmd->r)) |
1929 | { | 1929 | { |
1930 | /* timeout */ | 1930 | /* timeout */ |
1931 | proc = cmd->proc; | 1931 | proc = cmd->proc; |
1932 | cmd->proc = NULL; | 1932 | cmd->proc = NULL; |
1933 | proc (cmd->proc_cls, NULL); | 1933 | proc(cmd->proc_cls, NULL); |
1934 | return; | 1934 | return; |
1935 | } | 1935 | } |
1936 | ret = GNUNET_DISK_file_read (cmd->r, | 1936 | ret = GNUNET_DISK_file_read(cmd->r, |
1937 | &cmd->buf[cmd->off], | 1937 | &cmd->buf[cmd->off], |
1938 | sizeof (cmd->buf) - cmd->off); | 1938 | sizeof(cmd->buf) - cmd->off); |
1939 | if (ret <= 0) | 1939 | if (ret <= 0) |
1940 | { | ||
1941 | if ((cmd->off > 0) && (cmd->off < sizeof (cmd->buf))) | ||
1942 | { | 1940 | { |
1943 | cmd->buf[cmd->off] = '\0'; | 1941 | if ((cmd->off > 0) && (cmd->off < sizeof(cmd->buf))) |
1944 | cmd->proc (cmd->proc_cls, cmd->buf); | 1942 | { |
1943 | cmd->buf[cmd->off] = '\0'; | ||
1944 | cmd->proc(cmd->proc_cls, cmd->buf); | ||
1945 | } | ||
1946 | proc = cmd->proc; | ||
1947 | cmd->proc = NULL; | ||
1948 | proc(cmd->proc_cls, NULL); | ||
1949 | return; | ||
1945 | } | 1950 | } |
1946 | proc = cmd->proc; | 1951 | end = memchr(&cmd->buf[cmd->off], '\n', ret); |
1947 | cmd->proc = NULL; | ||
1948 | proc (cmd->proc_cls, NULL); | ||
1949 | return; | ||
1950 | } | ||
1951 | end = memchr (&cmd->buf[cmd->off], '\n', ret); | ||
1952 | cmd->off += ret; | 1952 | cmd->off += ret; |
1953 | while (NULL != end) | 1953 | while (NULL != end) |
1954 | { | 1954 | { |
1955 | *end = '\0'; | 1955 | *end = '\0'; |
1956 | cmd->proc (cmd->proc_cls, cmd->buf); | 1956 | cmd->proc(cmd->proc_cls, cmd->buf); |
1957 | memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf)); | 1957 | memmove(cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf)); |
1958 | cmd->off -= (end + 1 - cmd->buf); | 1958 | cmd->off -= (end + 1 - cmd->buf); |
1959 | end = memchr (cmd->buf, '\n', cmd->off); | 1959 | end = memchr(cmd->buf, '\n', cmd->off); |
1960 | } | 1960 | } |
1961 | cmd->rtask = | 1961 | cmd->rtask = |
1962 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining ( | 1962 | GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_absolute_get_remaining( |
1963 | cmd->timeout), | 1963 | cmd->timeout), |
1964 | cmd->r, | 1964 | cmd->r, |
1965 | &cmd_read, | 1965 | &cmd_read, |
1966 | cmd); | 1966 | cmd); |
1967 | } | 1967 | } |
1968 | 1968 | ||
1969 | 1969 | ||
@@ -1979,39 +1979,39 @@ cmd_read (void *cls) | |||
1979 | * @return NULL on error | 1979 | * @return NULL on error |
1980 | */ | 1980 | */ |
1981 | struct GNUNET_OS_CommandHandle * | 1981 | struct GNUNET_OS_CommandHandle * |
1982 | GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, | 1982 | GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc, |
1983 | void *proc_cls, | 1983 | void *proc_cls, |
1984 | struct GNUNET_TIME_Relative timeout, | 1984 | struct GNUNET_TIME_Relative timeout, |
1985 | const char *binary, | 1985 | const char *binary, |
1986 | ...) | 1986 | ...) |
1987 | { | 1987 | { |
1988 | struct GNUNET_OS_CommandHandle *cmd; | 1988 | struct GNUNET_OS_CommandHandle *cmd; |
1989 | struct GNUNET_OS_Process *eip; | 1989 | struct GNUNET_OS_Process *eip; |
1990 | struct GNUNET_DISK_PipeHandle *opipe; | 1990 | struct GNUNET_DISK_PipeHandle *opipe; |
1991 | va_list ap; | 1991 | va_list ap; |
1992 | 1992 | ||
1993 | opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); | 1993 | opipe = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); |
1994 | if (NULL == opipe) | 1994 | if (NULL == opipe) |
1995 | return NULL; | 1995 | return NULL; |
1996 | va_start (ap, binary); | 1996 | va_start(ap, binary); |
1997 | /* redirect stdout, don't inherit stderr/stdin */ | 1997 | /* redirect stdout, don't inherit stderr/stdin */ |
1998 | eip = | 1998 | eip = |
1999 | GNUNET_OS_start_process_va (GNUNET_NO, 0, NULL, opipe, NULL, binary, ap); | 1999 | GNUNET_OS_start_process_va(GNUNET_NO, 0, NULL, opipe, NULL, binary, ap); |
2000 | va_end (ap); | 2000 | va_end(ap); |
2001 | if (NULL == eip) | 2001 | if (NULL == eip) |
2002 | { | 2002 | { |
2003 | GNUNET_DISK_pipe_close (opipe); | 2003 | GNUNET_DISK_pipe_close(opipe); |
2004 | return NULL; | 2004 | return NULL; |
2005 | } | 2005 | } |
2006 | GNUNET_DISK_pipe_close_end (opipe, GNUNET_DISK_PIPE_END_WRITE); | 2006 | GNUNET_DISK_pipe_close_end(opipe, GNUNET_DISK_PIPE_END_WRITE); |
2007 | cmd = GNUNET_new (struct GNUNET_OS_CommandHandle); | 2007 | cmd = GNUNET_new(struct GNUNET_OS_CommandHandle); |
2008 | cmd->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 2008 | cmd->timeout = GNUNET_TIME_relative_to_absolute(timeout); |
2009 | cmd->eip = eip; | 2009 | cmd->eip = eip; |
2010 | cmd->opipe = opipe; | 2010 | cmd->opipe = opipe; |
2011 | cmd->proc = proc; | 2011 | cmd->proc = proc; |
2012 | cmd->proc_cls = proc_cls; | 2012 | cmd->proc_cls = proc_cls; |
2013 | cmd->r = GNUNET_DISK_pipe_handle (opipe, GNUNET_DISK_PIPE_END_READ); | 2013 | cmd->r = GNUNET_DISK_pipe_handle(opipe, GNUNET_DISK_PIPE_END_READ); |
2014 | cmd->rtask = GNUNET_SCHEDULER_add_read_file (timeout, cmd->r, &cmd_read, cmd); | 2014 | cmd->rtask = GNUNET_SCHEDULER_add_read_file(timeout, cmd->r, &cmd_read, cmd); |
2015 | return cmd; | 2015 | return cmd; |
2016 | } | 2016 | } |
2017 | 2017 | ||