Tor 0.4.9.0-alpha-dev
process_win32.c
Go to the documentation of this file.
1/* Copyright (c) 2003, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4/* See LICENSE for licensing information */
5
6/**
7 * \file process_win32.c
8 * \brief Module for working with Windows processes.
9 **/
10
11#define PROCESS_WIN32_PRIVATE
12#include "lib/intmath/cmp.h"
13#include "lib/buf/buffers.h"
14#include "lib/net/buffers_net.h"
16#include "lib/log/log.h"
17#include "lib/log/util_bug.h"
18#include "lib/log/win32err.h"
19#include "lib/process/process.h"
21#include "lib/process/env.h"
22
23#ifdef HAVE_SYS_TIME_H
24#include <sys/time.h>
25#endif
26
27#ifdef HAVE_STRING_H
28#include <string.h>
29#endif
30
31#ifdef _WIN32
32
33/** The size of our intermediate buffers. */
34#define BUFFER_SIZE (1024)
35
36/** Timer that ticks once a second and calls the process_win32_timer_callback()
37 * function. */
38static periodic_timer_t *periodic_timer;
39
40/** Structure to represent the state around the pipe HANDLE.
41 *
42 * This structure is used to store state about a given HANDLE, including
43 * whether we have reached end of file, its intermediate buffers, and how much
44 * data that is available in the intermediate buffer. */
45struct process_win32_handle_t {
46 /** Standard out pipe handle. */
47 HANDLE pipe;
48
49 /** True iff we have reached EOF from the pipe. */
50 bool reached_eof;
51
52 /** How much data is available in buffer. */
53 size_t data_available;
54
55 /** Intermediate buffer for ReadFileEx() and WriteFileEx(). */
56 char buffer[BUFFER_SIZE];
57
58 /** Overlapped structure for ReadFileEx() and WriteFileEx(). */
59 OVERLAPPED overlapped;
60
61 /** Are we waiting for another I/O operation to complete? */
62 bool busy;
63};
64
65/** Structure to represent the Windows specific implementation details of this
66 * Process backend.
67 *
68 * This structure is attached to <b>process_t</b> (see process.h) and is
69 * reachable from <b>process_t</b> via the <b>process_get_win32_process()</b>
70 * method. */
71struct process_win32_t {
72 /** Standard in state. */
73 process_win32_handle_t stdin_handle;
74
75 /** Standard out state. */
76 process_win32_handle_t stdout_handle;
77
78 /** Standard error state. */
79 process_win32_handle_t stderr_handle;
80
81 /** Process Information. */
82 PROCESS_INFORMATION process_information;
83};
84
85/** Create a new <b>process_win32_t</b>.
86 *
87 * This function constructs a new <b>process_win32_t</b> and initializes the
88 * default values. */
89process_win32_t *
90process_win32_new(void)
91{
92 process_win32_t *win32_process;
93 win32_process = tor_malloc_zero(sizeof(process_win32_t));
94
95 win32_process->stdin_handle.pipe = INVALID_HANDLE_VALUE;
96 win32_process->stdout_handle.pipe = INVALID_HANDLE_VALUE;
97 win32_process->stderr_handle.pipe = INVALID_HANDLE_VALUE;
98
99 return win32_process;
100}
101
102/** Free a given <b>process_win32_t</b>.
103 *
104 * This function deinitializes and frees up the resources allocated for the
105 * given <b>process_win32_t</b>. */
106void
107process_win32_free_(process_win32_t *win32_process)
108{
109 if (! win32_process)
110 return;
111
112 /* Cleanup our handles. */
113 process_win32_cleanup_handle(&win32_process->stdin_handle);
114 process_win32_cleanup_handle(&win32_process->stdout_handle);
115 process_win32_cleanup_handle(&win32_process->stderr_handle);
116
117 tor_free(win32_process);
118}
119
120/** Initialize the Windows backend of the Process subsystem. */
121void
122process_win32_init(void)
123{
124 /* We don't start the periodic timer here because it makes no sense to have
125 * the timer running until we have some processes that benefits from the
126 * timer timer ticks. */
127}
128
129/** Deinitialize the Windows backend of the Process subsystem. */
130void
131process_win32_deinit(void)
132{
133 /* Stop our timer, but only if it's running. */
134 if (process_win32_timer_running())
135 process_win32_timer_stop();
136}
137
138/** Execute the given process. This function is responsible for setting up
139 * named pipes for I/O between the child process and the Tor process. Returns
140 * <b>PROCESS_STATUS_RUNNING</b> upon success. */
142process_win32_exec(process_t *process)
143{
144 tor_assert(process);
145
146 process_win32_t *win32_process = process_get_win32_process(process);
147
148 HANDLE stdout_pipe_read = NULL;
149 HANDLE stdout_pipe_write = NULL;
150 HANDLE stderr_pipe_read = NULL;
151 HANDLE stderr_pipe_write = NULL;
152 HANDLE stdin_pipe_read = NULL;
153 HANDLE stdin_pipe_write = NULL;
154 BOOL ret = FALSE;
155
156 /* Setup our security attributes. */
157 SECURITY_ATTRIBUTES security_attributes;
158 security_attributes.nLength = sizeof(security_attributes);
159 security_attributes.bInheritHandle = TRUE;
160 /* FIXME: should we set explicit security attributes?
161 * (See Ticket #2046, comment 5) */
162 security_attributes.lpSecurityDescriptor = NULL;
163
164 /* Create our standard out pipe. */
165 if (! process_win32_create_pipe(&stdout_pipe_read,
166 &stdout_pipe_write,
167 &security_attributes,
168 PROCESS_WIN32_PIPE_TYPE_READER)) {
170 }
171
172 /* Create our standard error pipe. */
173 if (! process_win32_create_pipe(&stderr_pipe_read,
174 &stderr_pipe_write,
175 &security_attributes,
176 PROCESS_WIN32_PIPE_TYPE_READER)) {
178 }
179
180 /* Create out standard in pipe. */
181 if (! process_win32_create_pipe(&stdin_pipe_read,
182 &stdin_pipe_write,
183 &security_attributes,
184 PROCESS_WIN32_PIPE_TYPE_WRITER)) {
186 }
187
188 /* Configure startup info for our child process. */
189 STARTUPINFOA startup_info;
190
191 memset(&startup_info, 0, sizeof(startup_info));
192 startup_info.cb = sizeof(startup_info);
193 startup_info.hStdError = stderr_pipe_write;
194 startup_info.hStdOutput = stdout_pipe_write;
195 startup_info.hStdInput = stdin_pipe_read;
196 startup_info.dwFlags |= STARTF_USESTDHANDLES;
197
198 /* Create the env value for our new process. */
200
201 /* Create the argv value for our new process. */
202 char **argv = process_get_argv(process);
203
204 /* Windows expects argv to be a whitespace delimited string, so join argv up
205 */
206 char *joined_argv = tor_join_win_cmdline((const char **)argv);
207
208 /* Create the child process */
209 ret = CreateProcessA(NULL,
210 joined_argv,
211 NULL,
212 NULL,
213 TRUE,
214 CREATE_NO_WINDOW,
215 env->windows_environment_block[0] == '\0' ?
216 NULL : env->windows_environment_block,
217 NULL,
218 &startup_info,
219 &win32_process->process_information);
220
221 tor_free(argv);
222 tor_free(joined_argv);
223 process_environment_free(env);
224
225 if (! ret) {
226 log_warn(LD_PROCESS, "CreateProcessA() failed: %s",
227 format_win32_error(GetLastError()));
228
229 /* Cleanup our handles. */
230 CloseHandle(stdout_pipe_read);
231 CloseHandle(stdout_pipe_write);
232 CloseHandle(stderr_pipe_read);
233 CloseHandle(stderr_pipe_write);
234 CloseHandle(stdin_pipe_read);
235 CloseHandle(stdin_pipe_write);
236
237 /* In the Unix backend, we do not get an error in the Tor process when a
238 * child process fails to spawn its target executable since we need to
239 * first do the fork() call in the Tor process and then the child process
240 * is responsible for doing the call to execve().
241 *
242 * This means that the user of the process_exec() API must check for
243 * whether it returns PROCESS_STATUS_ERROR, which will rarely happen on
244 * Unix, but will happen for error cases on Windows where it does not
245 * happen on Unix. For example: when the target executable does not exist
246 * on the file system.
247 *
248 * To have somewhat feature compatibility between the Unix and the Windows
249 * backend, we here notify the process_t owner that the process have exited
250 * (even though it never managed to run) to ensure that the exit callback
251 * is executed.
252 */
253 process_notify_event_exit(process, 0);
254
256 }
257
258 /* TODO: Should we close hProcess and hThread in
259 * process_handle->process_information? */
260 win32_process->stdout_handle.pipe = stdout_pipe_read;
261 win32_process->stderr_handle.pipe = stderr_pipe_read;
262 win32_process->stdin_handle.pipe = stdin_pipe_write;
263
264 /* Close our ends of the pipes that is now owned by the child process. */
265 CloseHandle(stdout_pipe_write);
266 CloseHandle(stderr_pipe_write);
267 CloseHandle(stdin_pipe_read);
268
269 /* Used by the callback functions from ReadFileEx() and WriteFileEx() such
270 * that we can figure out which process_t that was responsible for the event.
271 *
272 * Warning, here be dragons:
273 *
274 * MSDN says that the hEvent member of the overlapped structure is unused
275 * for ReadFileEx() and WriteFileEx, which allows us to store a pointer to
276 * our process state there.
277 */
278 win32_process->stdout_handle.overlapped.hEvent = (HANDLE)process;
279 win32_process->stderr_handle.overlapped.hEvent = (HANDLE)process;
280 win32_process->stdin_handle.overlapped.hEvent = (HANDLE)process;
281
282 /* Start our timer if it is not already running. */
283 if (! process_win32_timer_running())
284 process_win32_timer_start();
285
286 /* We use Windows Extended I/O functions, so our completion callbacks are
287 * called automatically for us when there is data to read. Because of this
288 * we start the read of standard out and error right away. */
291
293}
294
295/** Terminate the given process. Returns true on success, otherwise false. */
296bool
297process_win32_terminate(process_t *process)
298{
299 tor_assert(process);
300
301 process_win32_t *win32_process = process_get_win32_process(process);
302
303 /* Terminate our process. */
304 BOOL ret;
305
306 ret = TerminateProcess(win32_process->process_information.hProcess, 0);
307
308 if (! ret) {
309 log_warn(LD_PROCESS, "TerminateProcess() failed: %s",
310 format_win32_error(GetLastError()));
311 return false;
312 }
313
314 /* Cleanup our handles. */
315 process_win32_cleanup_handle(&win32_process->stdin_handle);
316 process_win32_cleanup_handle(&win32_process->stdout_handle);
317 process_win32_cleanup_handle(&win32_process->stderr_handle);
318
319 return true;
320}
321
322/** Returns the unique process identifier for the given <b>process</b>. */
323process_pid_t
324process_win32_get_pid(process_t *process)
325{
326 tor_assert(process);
327
328 process_win32_t *win32_process = process_get_win32_process(process);
329 return (process_pid_t)win32_process->process_information.dwProcessId;
330}
331
332/** Schedule an async write of the data found in <b>buffer</b> for the given
333 * process. This function runs an async write operation of the content of
334 * buffer, if we are not already waiting for a pending I/O request. Returns the
335 * number of bytes that Windows will hopefully write for us in the background.
336 * */
337int
338process_win32_write(struct process_t *process, buf_t *buffer)
339{
340 tor_assert(process);
341 tor_assert(buffer);
342
343 process_win32_t *win32_process = process_get_win32_process(process);
344 BOOL ret = FALSE;
345 DWORD error_code = 0;
346 const size_t buffer_size = buf_datalen(buffer);
347
348 /* Windows is still writing our buffer. */
349 if (win32_process->stdin_handle.busy)
350 return 0;
351
352 /* Nothing for us to do right now. */
353 if (buffer_size == 0)
354 return 0;
355
356 /* We have reached end of file already? */
357 if (BUG(win32_process->stdin_handle.reached_eof))
358 return 0;
359
360 /* Figure out how much data we should read. */
361 const size_t write_size = MIN(buffer_size,
362 sizeof(win32_process->stdin_handle.buffer));
363
364 /* Read data from the process_t buffer into our intermediate buffer. */
365 buf_get_bytes(buffer, win32_process->stdin_handle.buffer, write_size);
366
367 /* Because of the slightly weird API for WriteFileEx() we must set this to 0
368 * before we call WriteFileEx() because WriteFileEx() does not reset the last
369 * error itself when it's successful. See comment below after the call to
370 * GetLastError(). */
371 SetLastError(0);
372
373 /* Schedule our write. */
374 ret = WriteFileEx(win32_process->stdin_handle.pipe,
375 win32_process->stdin_handle.buffer,
376 write_size,
377 &win32_process->stdin_handle.overlapped,
378 process_win32_stdin_write_done);
379
380 if (! ret) {
381 error_code = GetLastError();
382
383 /* No need to log at warning level for these two. */
384 if (error_code == ERROR_HANDLE_EOF || error_code == ERROR_BROKEN_PIPE) {
385 log_debug(LD_PROCESS, "WriteFileEx() returned EOF from pipe: %s",
386 format_win32_error(error_code));
387 } else {
388 log_warn(LD_PROCESS, "WriteFileEx() failed: %s",
389 format_win32_error(error_code));
390 }
391
392 win32_process->stdin_handle.reached_eof = true;
393 return 0;
394 }
395
396 /* Here be dragons: According to MSDN's documentation for WriteFileEx() we
397 * should check GetLastError() after a call to WriteFileEx() even though the
398 * `ret` return value was successful. If everything is good, GetLastError()
399 * returns `ERROR_SUCCESS` and nothing happens.
400 *
401 * XXX(ahf): I have not managed to trigger this code while stress-testing
402 * this code. */
403 error_code = GetLastError();
404
405 if (error_code != ERROR_SUCCESS) {
406 /* LCOV_EXCL_START */
407 log_warn(LD_PROCESS, "WriteFileEx() failed after returning success: %s",
408 format_win32_error(error_code));
409 win32_process->stdin_handle.reached_eof = true;
410 return 0;
411 /* LCOV_EXCL_STOP */
412 }
413
414 /* This cast should be safe since our buffer can maximum be BUFFER_SIZE
415 * large. */
416 return (int)write_size;
417}
418
419/** This function is called from the Process subsystem whenever the Windows
420 * backend says it has data ready. This function also ensures that we are
421 * starting a new background read from the standard output of the child process
422 * and asks Windows to call process_win32_stdout_read_done() when that
423 * operation is finished. Returns the number of bytes moved into <b>buffer</b>.
424 * */
425int
426process_win32_read_stdout(struct process_t *process, buf_t *buffer)
427{
428 tor_assert(process);
429 tor_assert(buffer);
430
431 process_win32_t *win32_process = process_get_win32_process(process);
432
433 return process_win32_read_from_handle(&win32_process->stdout_handle,
434 buffer,
435 process_win32_stdout_read_done);
436}
437
438/** This function is called from the Process subsystem whenever the Windows
439 * backend says it has data ready. This function also ensures that we are
440 * starting a new background read from the standard error of the child process
441 * and asks Windows to call process_win32_stderr_read_done() when that
442 * operation is finished. Returns the number of bytes moved into <b>buffer</b>.
443 * */
444int
445process_win32_read_stderr(struct process_t *process, buf_t *buffer)
446{
447 tor_assert(process);
448 tor_assert(buffer);
449
450 process_win32_t *win32_process = process_get_win32_process(process);
451
452 return process_win32_read_from_handle(&win32_process->stderr_handle,
453 buffer,
454 process_win32_stderr_read_done);
455}
456
457/** This function is responsible for moving the Tor process into what Microsoft
458 * calls an "alertable" state. Once the process is in an alertable state the
459 * Windows kernel will notify us when our background I/O requests have finished
460 * and the callbacks will be executed. */
461void
462process_win32_trigger_completion_callbacks(void)
463{
464 DWORD ret;
465
466 /* The call to SleepEx(dwMilliseconds, dwAlertable) makes the process sleep
467 * for dwMilliseconds and if dwAlertable is set to TRUE it will also cause
468 * the process to enter alertable state, where the Windows kernel will notify
469 * us about completed I/O requests from ReadFileEx() and WriteFileEX(), which
470 * will cause our completion callbacks to be executed.
471 *
472 * This function returns 0 if the time interval expired or WAIT_IO_COMPLETION
473 * if one or more I/O callbacks were executed. */
474 ret = SleepEx(0, TRUE);
475
476 /* Warn us if the function returned something we did not anticipate. */
477 if (ret != 0 && ret != WAIT_IO_COMPLETION) {
478 log_warn(LD_PROCESS, "SleepEx() returned %lu", ret);
479 }
480}
481
482/** Start the periodic timer which is responsible for checking whether
483 * processes are still alive and to make sure that the Tor process is
484 * periodically being moved into an alertable state. */
485void
486process_win32_timer_start(void)
487{
488 /* Make sure we never start our timer if it's already running. */
489 if (BUG(process_win32_timer_running()))
490 return;
491
492 /* Wake up once a second. */
493 static const struct timeval interval = {1, 0};
494
495 log_info(LD_PROCESS, "Starting Windows Process I/O timer");
496 periodic_timer = periodic_timer_new(tor_libevent_get_base(),
497 &interval,
498 process_win32_timer_callback,
499 NULL);
500}
501
502/** Stops the periodic timer. */
503void
504process_win32_timer_stop(void)
505{
506 if (BUG(periodic_timer == NULL))
507 return;
508
509 log_info(LD_PROCESS, "Stopping Windows Process I/O timer");
510 periodic_timer_free(periodic_timer);
511}
512
513/** Returns true iff the periodic timer is running. */
514bool
515process_win32_timer_running(void)
516{
517 return periodic_timer != NULL;
518}
519
520/** This function is called whenever the periodic_timer ticks. The function is
521 * responsible for moving the Tor process into an alertable state once a second
522 * and checking for whether our child processes have terminated since the last
523 * tick. */
524STATIC void
525process_win32_timer_callback(periodic_timer_t *timer, void *data)
526{
527 tor_assert(timer == periodic_timer);
528 tor_assert(data == NULL);
529
530 /* Move the process into an alertable state. */
531 process_win32_trigger_completion_callbacks();
532
533 /* Check if our processes are still alive. */
534
535 /* Since the call to process_win32_timer_test_process() might call
536 * process_notify_event_exit() which again might call process_free() which
537 * updates the list of processes returned by process_get_all_processes() it
538 * is important here that we make sure to not touch the list of processes if
539 * the call to process_win32_timer_test_process() returns true. */
540 bool done;
541
542 do {
544 done = true;
545
547 /* If process_win32_timer_test_process() returns true, it means that
548 * smartlist_remove() might have been called on the list returned by
549 * process_get_all_processes(). We start the loop over again until we
550 * have a successful run over the entire list where the list was not
551 * modified. */
552 if (process_win32_timer_test_process(process)) {
553 done = false;
554 break;
555 }
556 } SMARTLIST_FOREACH_END(process);
557 } while (! done);
558}
559
560/** Test whether a given process is still alive. Notify the Process subsystem
561 * if our process have died. Returns true iff the given process have
562 * terminated. */
563STATIC bool
564process_win32_timer_test_process(process_t *process)
565{
566 tor_assert(process);
567
568 /* No need to look at processes that don't claim they are running. */
570 return false;
571
572 process_win32_t *win32_process = process_get_win32_process(process);
573 BOOL ret = FALSE;
574 DWORD exit_code = 0;
575
576 /* Sometimes the Windows kernel won't give us the EOF/Broken Pipe error
577 * message until some time after the process have actually terminated. We
578 * make sure that our ReadFileEx() calls for the process have *all* returned
579 * and both standard out and error have been marked as EOF before we try to
580 * see if the process terminated.
581 *
582 * This ensures that we *never* call the exit callback of the `process_t`,
583 * which potentially ends up calling `process_free()` on our `process_t`,
584 * before all data have been received from the process.
585 *
586 * We do NOT have a check here for whether standard in reached EOF since
587 * standard in's WriteFileEx() function is only called on-demand when we have
588 * something to write and is thus usually not awaiting to finish any
589 * operations. If we WriteFileEx() to a file that has terminated we'll simply
590 * get an error from ReadFileEx() or its completion routine and move on with
591 * life. */
592 if (! win32_process->stdout_handle.reached_eof)
593 return false;
594
595 if (! win32_process->stderr_handle.reached_eof)
596 return false;
597
598 /* We start by testing whether our process is still running. */
599 ret = GetExitCodeProcess(win32_process->process_information.hProcess,
600 &exit_code);
601
602 if (! ret) {
603 log_warn(LD_PROCESS, "GetExitCodeProcess() failed: %s",
604 format_win32_error(GetLastError()));
605 return false;
606 }
607
608 /* Notify our process_t that our process have terminated. Since our
609 * exit_callback might decide to process_free() our process handle it is very
610 * important that we do not touch the process_t after the call to
611 * process_notify_event_exit(). */
612 if (exit_code != STILL_ACTIVE) {
613 process_notify_event_exit(process, exit_code);
614 return true;
615 }
616
617 return false;
618}
619
620/** Create a new overlapped named pipe. This function creates a new connected,
621 * named, pipe in <b>*read_pipe</b> and <b>*write_pipe</b> if the function is
622 * successful. Returns true on success, false on failure. */
623STATIC bool
624process_win32_create_pipe(HANDLE *read_pipe,
625 HANDLE *write_pipe,
626 SECURITY_ATTRIBUTES *attributes,
627 process_win32_pipe_type_t pipe_type)
628{
629 tor_assert(read_pipe);
630 tor_assert(write_pipe);
631 tor_assert(attributes);
632
633 BOOL ret = FALSE;
634
635 /* Buffer size. */
636 const size_t size = 4096;
637
638 /* Our additional read/write modes that depends on which pipe type we are
639 * creating. */
640 DWORD read_mode = 0;
641 DWORD write_mode = 0;
642
643 /* Generate the unique pipe name. */
644 char pipe_name[MAX_PATH];
645 static DWORD process_id = 0;
646 static DWORD counter = 0;
647
648 if (process_id == 0)
649 process_id = GetCurrentProcessId();
650
651 tor_snprintf(pipe_name, sizeof(pipe_name),
652 "\\\\.\\Pipe\\Tor-Process-Pipe-%lu-%lu",
653 process_id, counter++);
654
655 /* Only one of our handles can be overlapped. */
656 switch (pipe_type) {
657 case PROCESS_WIN32_PIPE_TYPE_READER:
658 read_mode = FILE_FLAG_OVERLAPPED;
659 break;
660 case PROCESS_WIN32_PIPE_TYPE_WRITER:
661 write_mode = FILE_FLAG_OVERLAPPED;
662 break;
663 default:
664 /* LCOV_EXCL_START */
665 tor_assert_nonfatal_unreached_once();
666 /* LCOV_EXCL_STOP */
667 }
668
669 /* Setup our read and write handles. */
670 HANDLE read_handle;
671 HANDLE write_handle;
672
673 /* Create our named pipe. */
674 read_handle = CreateNamedPipeA(pipe_name,
675 (PIPE_ACCESS_INBOUND|read_mode),
676 (PIPE_TYPE_BYTE|PIPE_WAIT),
677 1,
678 size,
679 size,
680 1000,
681 attributes);
682
683 if (read_handle == INVALID_HANDLE_VALUE) {
684 log_warn(LD_PROCESS, "CreateNamedPipeA() failed: %s",
685 format_win32_error(GetLastError()));
686 return false;
687 }
688
689 /* Create our file in the pipe namespace. */
690 write_handle = CreateFileA(pipe_name,
691 GENERIC_WRITE,
692 0,
693 attributes,
694 OPEN_EXISTING,
695 (FILE_ATTRIBUTE_NORMAL|write_mode),
696 NULL);
697
698 if (write_handle == INVALID_HANDLE_VALUE) {
699 log_warn(LD_PROCESS, "CreateFileA() failed: %s",
700 format_win32_error(GetLastError()));
701
702 CloseHandle(read_handle);
703
704 return false;
705 }
706
707 /* Set the inherit flag for our pipe. */
708 switch (pipe_type) {
709 case PROCESS_WIN32_PIPE_TYPE_READER:
710 ret = SetHandleInformation(read_handle, HANDLE_FLAG_INHERIT, 0);
711 break;
712 case PROCESS_WIN32_PIPE_TYPE_WRITER:
713 ret = SetHandleInformation(write_handle, HANDLE_FLAG_INHERIT, 0);
714 break;
715 default:
716 /* LCOV_EXCL_START */
717 tor_assert_nonfatal_unreached_once();
718 /* LCOV_EXCL_STOP */
719 }
720
721 if (! ret) {
722 log_warn(LD_PROCESS, "SetHandleInformation() failed: %s",
723 format_win32_error(GetLastError()));
724
725 CloseHandle(read_handle);
726 CloseHandle(write_handle);
727
728 return false;
729 }
730
731 /* Everything is good. */
732 *read_pipe = read_handle;
733 *write_pipe = write_handle;
734
735 return true;
736}
737
738/** Cleanup a given <b>handle</b>. */
739STATIC void
740process_win32_cleanup_handle(process_win32_handle_t *handle)
741{
742 tor_assert(handle);
743
744#if 0
745 BOOL ret;
746 DWORD error_code;
747
748 /* Cancel any pending I/O requests: This means that instead of getting
749 * ERROR_BROKEN_PIPE we get ERROR_OPERATION_ABORTED, but it doesn't seem
750 * like this is needed. */
751 ret = CancelIo(handle->pipe);
752
753 if (! ret) {
754 error_code = GetLastError();
755
756 /* There was no pending I/O requests for our handle. */
757 if (error_code != ERROR_NOT_FOUND) {
758 log_warn(LD_PROCESS, "CancelIo() failed: %s",
759 format_win32_error(error_code));
760 }
761 }
762#endif /* 0 */
763
764 /* Close our handle. */
765 if (handle->pipe != INVALID_HANDLE_VALUE) {
766 CloseHandle(handle->pipe);
767 handle->pipe = INVALID_HANDLE_VALUE;
768 handle->reached_eof = true;
769 }
770}
771
772/** This function is called when ReadFileEx() completes its background read
773 * from the child process's standard output. We notify the Process subsystem if
774 * there is data available for it to read from us. */
775STATIC VOID WINAPI
776process_win32_stdout_read_done(DWORD error_code,
777 DWORD byte_count,
778 LPOVERLAPPED overlapped)
779{
780 tor_assert(overlapped);
781 tor_assert(overlapped->hEvent);
782
783 /* Extract our process_t from the hEvent member of OVERLAPPED. */
784 process_t *process = (process_t *)overlapped->hEvent;
785 process_win32_t *win32_process = process_get_win32_process(process);
786
787 if (process_win32_handle_read_completion(&win32_process->stdout_handle,
788 error_code,
789 byte_count)) {
790 /* Schedule our next read. */
792 }
793}
794
795/** This function is called when ReadFileEx() completes its background read
796 * from the child process's standard error. We notify the Process subsystem if
797 * there is data available for it to read from us. */
798STATIC VOID WINAPI
799process_win32_stderr_read_done(DWORD error_code,
800 DWORD byte_count,
801 LPOVERLAPPED overlapped)
802{
803 tor_assert(overlapped);
804 tor_assert(overlapped->hEvent);
805
806 /* Extract our process_t from the hEvent member of OVERLAPPED. */
807 process_t *process = (process_t *)overlapped->hEvent;
808 process_win32_t *win32_process = process_get_win32_process(process);
809
810 if (process_win32_handle_read_completion(&win32_process->stderr_handle,
811 error_code,
812 byte_count)) {
813 /* Schedule our next read. */
815 }
816}
817
818/** This function is called when WriteFileEx() completes its background write
819 * to the child process's standard input. We notify the Process subsystem that
820 * it can write data to us again. */
821STATIC VOID WINAPI
822process_win32_stdin_write_done(DWORD error_code,
823 DWORD byte_count,
824 LPOVERLAPPED overlapped)
825{
826 tor_assert(overlapped);
827 tor_assert(overlapped->hEvent);
828
829 (void)byte_count;
830
831 process_t *process = (process_t *)overlapped->hEvent;
832 process_win32_t *win32_process = process_get_win32_process(process);
833
834 /* Mark our handle as not having any outstanding I/O requests. */
835 win32_process->stdin_handle.busy = false;
836
837 /* Check if we have been asked to write to the handle that have been marked
838 * as having reached EOF. */
839 if (BUG(win32_process->stdin_handle.reached_eof))
840 return;
841
842 if (error_code == 0) {
843 /** Our data have been successfully written. Clear our state and schedule
844 * the next write. */
845 win32_process->stdin_handle.data_available = 0;
846 memset(win32_process->stdin_handle.buffer, 0,
847 sizeof(win32_process->stdin_handle.buffer));
848
849 /* Schedule the next write. */
851 } else if (error_code == ERROR_HANDLE_EOF ||
852 error_code == ERROR_BROKEN_PIPE) {
853 /* Our WriteFileEx() call was successful, but we reached the end of our
854 * file. We mark our handle as having reached EOF and returns. */
855 tor_assert(byte_count == 0);
856
857 win32_process->stdin_handle.reached_eof = true;
858 } else {
859 /* An error happened: We warn the user and mark our handle as having
860 * reached EOF */
861 log_warn(LD_PROCESS,
862 "Error in I/O completion routine from WriteFileEx(): %s",
863 format_win32_error(error_code));
864 win32_process->stdin_handle.reached_eof = true;
865 }
866}
867
868/** This function reads data from the given <b>handle</b>'s internal buffer and
869 * moves it into the given <b>buffer</b>. Additionally, we start the next
870 * ReadFileEx() background operation with the given <b>callback</b> as
871 * completion callback. Returns the number of bytes written to the buffer. */
872STATIC int
873process_win32_read_from_handle(process_win32_handle_t *handle,
874 buf_t *buffer,
875 LPOVERLAPPED_COMPLETION_ROUTINE callback)
876{
877 tor_assert(handle);
878 tor_assert(buffer);
879 tor_assert(callback);
880
881 BOOL ret = FALSE;
882 int bytes_available = 0;
883 DWORD error_code = 0;
884
885 /* We already have a request to read data that isn't complete yet. */
886 if (BUG(handle->busy))
887 return 0;
888
889 /* Check if we have been asked to read from a handle that have already told
890 * us that we have reached the end of the file. */
891 if (handle->reached_eof)
892 return 0;
893
894 /* This cast should be safe since our buffer can be at maximum up to
895 * BUFFER_SIZE in size. */
896 bytes_available = (int)handle->data_available;
897
898 if (handle->data_available > 0) {
899 /* Read data from our intermediate buffer into the process_t buffer. */
900 buf_add(buffer, handle->buffer, handle->data_available);
901
902 /* Reset our read state. */
903 handle->data_available = 0;
904 memset(handle->buffer, 0, sizeof(handle->buffer));
905 }
906
907 /* Because of the slightly weird API for ReadFileEx() we must set this to 0
908 * before we call ReadFileEx() because ReadFileEx() does not reset the last
909 * error itself when it's successful. See comment below after the call to
910 * GetLastError(). */
911 SetLastError(0);
912
913 /* Ask the Windows kernel to read data from our pipe into our buffer and call
914 * the callback function when it is done. */
915 ret = ReadFileEx(handle->pipe,
916 handle->buffer,
917 sizeof(handle->buffer),
918 &handle->overlapped,
919 callback);
920
921 if (! ret) {
922 error_code = GetLastError();
923
924 /* No need to log at warning level for these two. */
925 if (error_code == ERROR_HANDLE_EOF || error_code == ERROR_BROKEN_PIPE) {
926 log_debug(LD_PROCESS, "ReadFileEx() returned EOF from pipe: %s",
927 format_win32_error(error_code));
928 } else {
929 log_warn(LD_PROCESS, "ReadFileEx() failed: %s",
930 format_win32_error(error_code));
931 }
932
933 handle->reached_eof = true;
934 return bytes_available;
935 }
936
937 /* Here be dragons: According to MSDN's documentation for ReadFileEx() we
938 * should check GetLastError() after a call to ReadFileEx() even though the
939 * `ret` return value was successful. If everything is good, GetLastError()
940 * returns `ERROR_SUCCESS` and nothing happens.
941 *
942 * XXX(ahf): I have not managed to trigger this code while stress-testing
943 * this code. */
944 error_code = GetLastError();
945
946 if (error_code != ERROR_SUCCESS) {
947 /* LCOV_EXCL_START */
948 log_warn(LD_PROCESS, "ReadFileEx() failed after returning success: %s",
949 format_win32_error(error_code));
950 handle->reached_eof = true;
951 return bytes_available;
952 /* LCOV_EXCL_STOP */
953 }
954
955 /* We mark our handle as having a pending I/O request. */
956 handle->busy = true;
957
958 return bytes_available;
959}
960
961/** This function checks the callback values from ReadFileEx() in
962 * <b>error_code</b> and <b>byte_count</b> if we have read data. Returns true
963 * iff our caller should request more data from ReadFileEx(). */
964STATIC bool
965process_win32_handle_read_completion(process_win32_handle_t *handle,
966 DWORD error_code,
967 DWORD byte_count)
968{
969 tor_assert(handle);
970
971 /* Mark our handle as not having any outstanding I/O requests. */
972 handle->busy = false;
973
974 if (error_code == 0) {
975 /* Our ReadFileEx() call was successful and there is data for us. */
976
977 /* This cast should be safe since byte_count should never be larger than
978 * BUFFER_SIZE. */
979 tor_assert(byte_count <= BUFFER_SIZE);
980 handle->data_available = (size_t)byte_count;
981
982 /* Tell our caller to schedule the next read. */
983 return true;
984 } else if (error_code == ERROR_HANDLE_EOF ||
985 error_code == ERROR_BROKEN_PIPE) {
986 /* Our ReadFileEx() finished, but we reached the end of our file. We mark
987 * our handle as having reached EOF and returns. */
988 tor_assert(byte_count == 0);
989
990 handle->reached_eof = true;
991 } else {
992 /* An error happened: We warn the user and mark our handle as having
993 * reached EOF */
994 log_warn(LD_PROCESS,
995 "Error in I/O completion routine from ReadFileEx(): %s",
996 format_win32_error(error_code));
997
998 handle->reached_eof = true;
999 }
1000
1001 /* Our caller should NOT schedule the next read. */
1002 return false;
1003}
1004
1005/** Format a single argument for being put on a Windows command line.
1006 * Returns a newly allocated string */
1007STATIC char *
1008format_win_cmdline_argument(const char *arg)
1009{
1010 char *formatted_arg;
1011 char need_quotes;
1012 const char *c;
1013 int i;
1014 int bs_counter = 0;
1015 /* Backslash we can point to when one is inserted into the string */
1016 const char backslash = '\\';
1017
1018 /* Smartlist of *char */
1019 smartlist_t *arg_chars;
1020 arg_chars = smartlist_new();
1021
1022 /* Quote string if it contains whitespace or is empty */
1023 need_quotes = (strchr(arg, ' ') || strchr(arg, '\t') || '\0' == arg[0]);
1024
1025 /* Build up smartlist of *chars */
1026 for (c=arg; *c != '\0'; c++) {
1027 if ('"' == *c) {
1028 /* Double up backslashes preceding a quote */
1029 for (i=0; i<(bs_counter*2); i++)
1030 smartlist_add(arg_chars, (void*)&backslash);
1031 bs_counter = 0;
1032 /* Escape the quote */
1033 smartlist_add(arg_chars, (void*)&backslash);
1034 smartlist_add(arg_chars, (void*)c);
1035 } else if ('\\' == *c) {
1036 /* Count backslashes until we know whether to double up */
1037 bs_counter++;
1038 } else {
1039 /* Don't double up slashes preceding a non-quote */
1040 for (i=0; i<bs_counter; i++)
1041 smartlist_add(arg_chars, (void*)&backslash);
1042 bs_counter = 0;
1043 smartlist_add(arg_chars, (void*)c);
1044 }
1045 }
1046 /* Don't double up trailing backslashes */
1047 for (i=0; i<bs_counter; i++)
1048 smartlist_add(arg_chars, (void*)&backslash);
1049
1050 /* Allocate space for argument, quotes (if needed), and terminator */
1051 const size_t formatted_arg_len = smartlist_len(arg_chars) +
1052 (need_quotes ? 2 : 0) + 1;
1053 formatted_arg = tor_malloc_zero(formatted_arg_len);
1054
1055 /* Add leading quote */
1056 i=0;
1057 if (need_quotes)
1058 formatted_arg[i++] = '"';
1059
1060 /* Add characters */
1061 SMARTLIST_FOREACH(arg_chars, char*, ch,
1062 {
1063 formatted_arg[i++] = *ch;
1064 });
1065
1066 /* Add trailing quote */
1067 if (need_quotes)
1068 formatted_arg[i++] = '"';
1069 formatted_arg[i] = '\0';
1070
1071 smartlist_free(arg_chars);
1072 return formatted_arg;
1073}
1074
1075/** Format a command line for use on Windows, which takes the command as a
1076 * string rather than string array. Follows the rules from "Parsing C++
1077 * Command-Line Arguments" in MSDN. Algorithm based on list2cmdline in the
1078 * Python subprocess module. Returns a newly allocated string */
1079STATIC char *
1080tor_join_win_cmdline(const char *argv[])
1081{
1082 smartlist_t *argv_list;
1083 char *joined_argv;
1084 int i;
1085
1086 /* Format each argument and put the result in a smartlist */
1087 argv_list = smartlist_new();
1088 for (i=0; argv[i] != NULL; i++) {
1089 smartlist_add(argv_list, (void *)format_win_cmdline_argument(argv[i]));
1090 }
1091
1092 /* Join the arguments with whitespace */
1093 joined_argv = smartlist_join_strings(argv_list, " ", 0, NULL);
1094
1095 /* Free the newly allocated arguments, and the smartlist */
1096 SMARTLIST_FOREACH(argv_list, char *, arg,
1097 {
1098 tor_free(arg);
1099 });
1100 smartlist_free(argv_list);
1101
1102 return joined_argv;
1103}
1104
1105#endif /* defined(_WIN32) */
int buf_add(buf_t *buf, const char *string, size_t string_len)
Definition: buffers.c:527
size_t buf_datalen(const buf_t *buf)
Definition: buffers.c:394
int buf_get_bytes(buf_t *buf, char *string, size_t string_len)
Definition: buffers.c:637
Header file for buffers.c.
Header file for buffers_net.c.
Macro definitions for MIN, MAX, and CLAMP.
periodic_timer_t * periodic_timer_new(struct event_base *base, const struct timeval *tv, void(*cb)(periodic_timer_t *timer, void *data), void *data)
struct event_base * tor_libevent_get_base(void)
Header for env.c.
Headers for log.c.
#define LD_PROCESS
Definition: log.h:115
#define tor_free(p)
Definition: malloc.h:56
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
void process_notify_event_stdout(process_t *process)
Definition: process.c:577
static smartlist_t * processes
Definition: process.c:27
void process_notify_event_exit(process_t *process, process_exit_code_t exit_code)
Definition: process.c:623
void process_notify_event_stderr(process_t *process)
Definition: process.c:594
const smartlist_t * process_get_all_processes(void)
Definition: process.c:166
process_status_t process_get_status(const process_t *process)
Definition: process.c:411
process_environment_t * process_get_environment(const process_t *process)
Definition: process.c:501
void process_notify_event_stdin(process_t *process)
Definition: process.c:610
char ** process_get_argv(const process_t *process)
Definition: process.c:439
Header for process.c.
process_status_t
Definition: process.h:26
@ PROCESS_STATUS_RUNNING
Definition: process.h:31
@ PROCESS_STATUS_ERROR
Definition: process.h:34
Header for process_win32.c.
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
Header for smartlist.c.
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
char * windows_environment_block
Definition: env.h:24
#define STATIC
Definition: testsupport.h:32
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103
Header for win32err.c.