Move remaining code from subprocess.{h,c} to more appropriate places.
[tor.git] / src / lib / process / process_win32.c
blob73e19d518fd424730f3384697ec42ed78c81b543
1 /* Copyright (c) 2003, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2018, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 /**
7 * \file process_win32.c
8 * \brief Module for working with Windows processes.
9 **/
11 #define PROCESS_WIN32_PRIVATE
12 #include "lib/intmath/cmp.h"
13 #include "lib/container/buffers.h"
14 #include "lib/net/buffers_net.h"
15 #include "lib/container/smartlist.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"
20 #include "lib/process/process_win32.h"
21 #include "lib/process/env.h"
23 #ifdef HAVE_SYS_TIME_H
24 #include <sys/time.h>
25 #endif
27 #ifdef HAVE_STRING_H
28 #include <string.h>
29 #endif
31 #ifdef _WIN32
33 /** The size of our intermediate buffers. */
34 #define BUFFER_SIZE (1024)
36 /** Timer that ticks once a second and calls the process_win32_timer_callback()
37 * function. */
38 static periodic_timer_t *periodic_timer;
40 /** Structure to represent the state around the pipe HANDLE.
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. */
45 struct process_win32_handle_t {
46 /** Standard out pipe handle. */
47 HANDLE pipe;
49 /** True iff we have reached EOF from the pipe. */
50 bool reached_eof;
52 /** How much data is available in buffer. */
53 size_t data_available;
55 /** Intermediate buffer for ReadFileEx() and WriteFileEx(). */
56 char buffer[BUFFER_SIZE];
58 /** Overlapped structure for ReadFileEx() and WriteFileEx(). */
59 OVERLAPPED overlapped;
61 /** Are we waiting for another I/O operation to complete? */
62 bool busy;
65 /** Structure to represent the Windows specific implementation details of this
66 * Process backend.
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. */
71 struct process_win32_t {
72 /** Standard in state. */
73 process_win32_handle_t stdin_handle;
75 /** Standard out state. */
76 process_win32_handle_t stdout_handle;
78 /** Standard error state. */
79 process_win32_handle_t stderr_handle;
81 /** Process Information. */
82 PROCESS_INFORMATION process_information;
85 /** Create a new <b>process_win32_t</b>.
87 * This function constructs a new <b>process_win32_t</b> and initializes the
88 * default values. */
89 process_win32_t *
90 process_win32_new(void)
92 process_win32_t *win32_process;
93 win32_process = tor_malloc_zero(sizeof(process_win32_t));
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;
99 return win32_process;
102 /** Free a given <b>process_win32_t</b>.
104 * This function deinitializes and frees up the resources allocated for the
105 * given <b>process_win32_t</b>. */
106 void
107 process_win32_free_(process_win32_t *win32_process)
109 if (! win32_process)
110 return;
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);
117 tor_free(win32_process);
120 /** Initialize the Windows backend of the Process subsystem. */
121 void
122 process_win32_init(void)
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. */
129 /** Deinitialize the Windows backend of the Process subsystem. */
130 void
131 process_win32_deinit(void)
133 /* Stop our timer, but only if it's running. */
134 if (process_win32_timer_running())
135 process_win32_timer_stop();
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. */
141 process_status_t
142 process_win32_exec(process_t *process)
144 tor_assert(process);
146 process_win32_t *win32_process = process_get_win32_process(process);
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 const char *filename = process_get_command(process);
157 /* Not much we can do if we haven't been told what to start. */
158 if (BUG(filename == NULL))
159 return PROCESS_STATUS_ERROR;
161 /* Setup our security attributes. */
162 SECURITY_ATTRIBUTES security_attributes;
163 security_attributes.nLength = sizeof(security_attributes);
164 security_attributes.bInheritHandle = TRUE;
165 /* FIXME: should we set explicit security attributes?
166 * (See Ticket #2046, comment 5) */
167 security_attributes.lpSecurityDescriptor = NULL;
169 /* Create our standard out pipe. */
170 if (! process_win32_create_pipe(&stdout_pipe_read,
171 &stdout_pipe_write,
172 &security_attributes,
173 PROCESS_WIN32_PIPE_TYPE_READER)) {
174 return PROCESS_STATUS_ERROR;
177 /* Create our standard error pipe. */
178 if (! process_win32_create_pipe(&stderr_pipe_read,
179 &stderr_pipe_write,
180 &security_attributes,
181 PROCESS_WIN32_PIPE_TYPE_READER)) {
182 return PROCESS_STATUS_ERROR;
185 /* Create out standard in pipe. */
186 if (! process_win32_create_pipe(&stdin_pipe_read,
187 &stdin_pipe_write,
188 &security_attributes,
189 PROCESS_WIN32_PIPE_TYPE_WRITER)) {
190 return PROCESS_STATUS_ERROR;
193 /* Configure startup info for our child process. */
194 STARTUPINFOA startup_info;
196 memset(&startup_info, 0, sizeof(startup_info));
197 startup_info.cb = sizeof(startup_info);
198 startup_info.hStdError = stderr_pipe_write;
199 startup_info.hStdOutput = stdout_pipe_write;
200 startup_info.hStdInput = stdin_pipe_read;
201 startup_info.dwFlags |= STARTF_USESTDHANDLES;
203 /* Create the env value for our new process. */
204 process_environment_t *env = process_get_environment(process);
206 /* Create the argv value for our new process. */
207 char **argv = process_get_argv(process);
209 /* Windows expects argv to be a whitespace delimited string, so join argv up
211 char *joined_argv = tor_join_win_cmdline((const char **)argv);
213 /* Create the child process */
214 ret = CreateProcessA(filename,
215 joined_argv,
216 NULL,
217 NULL,
218 TRUE,
219 CREATE_NO_WINDOW,
220 env->windows_environment_block[0] == '\0' ?
221 NULL : env->windows_environment_block,
222 NULL,
223 &startup_info,
224 &win32_process->process_information);
226 tor_free(argv);
227 tor_free(joined_argv);
228 process_environment_free(env);
230 if (! ret) {
231 log_warn(LD_PROCESS, "CreateProcessA() failed: %s",
232 format_win32_error(GetLastError()));
234 /* Cleanup our handles. */
235 CloseHandle(stdout_pipe_read);
236 CloseHandle(stdout_pipe_write);
237 CloseHandle(stderr_pipe_read);
238 CloseHandle(stderr_pipe_write);
239 CloseHandle(stdin_pipe_read);
240 CloseHandle(stdin_pipe_write);
242 return PROCESS_STATUS_ERROR;
245 /* TODO: Should we close hProcess and hThread in
246 * process_handle->process_information? */
247 win32_process->stdout_handle.pipe = stdout_pipe_read;
248 win32_process->stderr_handle.pipe = stderr_pipe_read;
249 win32_process->stdin_handle.pipe = stdin_pipe_write;
251 /* Used by the callback functions from ReadFileEx() and WriteFileEx() such
252 * that we can figure out which process_t that was responsible for the event.
254 * Warning, here be dragons:
256 * MSDN says that the hEvent member of the overlapped structure is unused
257 * for ReadFileEx() and WriteFileEx, which allows us to store a pointer to
258 * our process state there.
260 win32_process->stdout_handle.overlapped.hEvent = (HANDLE)process;
261 win32_process->stderr_handle.overlapped.hEvent = (HANDLE)process;
262 win32_process->stdin_handle.overlapped.hEvent = (HANDLE)process;
264 /* Start our timer if it is not already running. */
265 if (! process_win32_timer_running())
266 process_win32_timer_start();
268 /* We use Windows Extended I/O functions, so our completion callbacks are
269 * called automatically for us when there is data to read. Because of this
270 * we start the read of standard out and error right away. */
271 process_notify_event_stdout(process);
272 process_notify_event_stderr(process);
274 return PROCESS_STATUS_RUNNING;
277 /** Terminate the given process. Returns true on success, otherwise false. */
278 bool
279 process_win32_terminate(process_t *process)
281 tor_assert(process);
283 process_win32_t *win32_process = process_get_win32_process(process);
285 /* Terminate our process. */
286 BOOL ret;
288 ret = TerminateProcess(win32_process->process_information.hProcess, 0);
290 if (! ret) {
291 log_warn(LD_PROCESS, "TerminateProcess() failed: %s",
292 format_win32_error(GetLastError()));
293 return false;
296 return true;
299 /** Returns the unique process identifier for the given <b>process</b>. */
300 process_pid_t
301 process_win32_get_pid(process_t *process)
303 tor_assert(process);
305 process_win32_t *win32_process = process_get_win32_process(process);
306 return (process_pid_t)win32_process->process_information.dwProcessId;
309 /** Schedule an async write of the data found in <b>buffer</b> for the given
310 * process. This function runs an async write operation of the content of
311 * buffer, if we are not already waiting for a pending I/O request. Returns the
312 * number of bytes that Windows will hopefully write for us in the background.
313 * */
315 process_win32_write(struct process_t *process, buf_t *buffer)
317 tor_assert(process);
318 tor_assert(buffer);
320 process_win32_t *win32_process = process_get_win32_process(process);
321 BOOL ret = FALSE;
322 const size_t buffer_size = buf_datalen(buffer);
324 /* Windows is still writing our buffer. */
325 if (win32_process->stdin_handle.busy)
326 return 0;
328 /* Nothing for us to do right now. */
329 if (buffer_size == 0)
330 return 0;
332 /* We have reached end of file already? */
333 if (BUG(win32_process->stdin_handle.reached_eof))
334 return 0;
336 /* Figure out how much data we should read. */
337 const size_t write_size = MIN(buffer_size,
338 sizeof(win32_process->stdin_handle.buffer));
340 /* Read data from the process_t buffer into our intermediate buffer. */
341 buf_get_bytes(buffer, win32_process->stdin_handle.buffer, write_size);
343 /* Schedule our write. */
344 ret = WriteFileEx(win32_process->stdin_handle.pipe,
345 win32_process->stdin_handle.buffer,
346 write_size,
347 &win32_process->stdin_handle.overlapped,
348 process_win32_stdin_write_done);
350 if (! ret) {
351 log_warn(LD_PROCESS, "WriteFileEx() failed: %s",
352 format_win32_error(GetLastError()));
353 return 0;
356 /* This cast should be safe since our buffer can maximum be BUFFER_SIZE
357 * large. */
358 return (int)write_size;
361 /** This function is called from the Process subsystem whenever the Windows
362 * backend says it has data ready. This function also ensures that we are
363 * starting a new background read from the standard output of the child process
364 * and asks Windows to call process_win32_stdout_read_done() when that
365 * operation is finished. Returns the number of bytes moved into <b>buffer</b>.
366 * */
368 process_win32_read_stdout(struct process_t *process, buf_t *buffer)
370 tor_assert(process);
371 tor_assert(buffer);
373 process_win32_t *win32_process = process_get_win32_process(process);
375 return process_win32_read_from_handle(&win32_process->stdout_handle,
376 buffer,
377 process_win32_stdout_read_done);
380 /** This function is called from the Process subsystem whenever the Windows
381 * backend says it has data ready. This function also ensures that we are
382 * starting a new background read from the standard error of the child process
383 * and asks Windows to call process_win32_stderr_read_done() when that
384 * operation is finished. Returns the number of bytes moved into <b>buffer</b>.
385 * */
387 process_win32_read_stderr(struct process_t *process, buf_t *buffer)
389 tor_assert(process);
390 tor_assert(buffer);
392 process_win32_t *win32_process = process_get_win32_process(process);
394 return process_win32_read_from_handle(&win32_process->stderr_handle,
395 buffer,
396 process_win32_stderr_read_done);
399 /** This function is responsible for moving the Tor process into what Microsoft
400 * calls an "alertable" state. Once the process is in an alertable state the
401 * Windows kernel will notify us when our background I/O requests have finished
402 * and the callbacks will be executed. */
403 void
404 process_win32_trigger_completion_callbacks(void)
406 DWORD ret;
408 /* The call to SleepEx(dwMilliseconds, dwAlertable) makes the process sleep
409 * for dwMilliseconds and if dwAlertable is set to TRUE it will also cause
410 * the process to enter alertable state, where the Windows kernel will notify
411 * us about completed I/O requests from ReadFileEx() and WriteFileEX(), which
412 * will cause our completion callbacks to be executed.
414 * This function returns 0 if the time interval expired or WAIT_IO_COMPLETION
415 * if one or more I/O callbacks were executed. */
416 ret = SleepEx(0, TRUE);
418 /* Warn us if the function returned something we did not anticipate. */
419 if (ret != 0 && ret != WAIT_IO_COMPLETION) {
420 log_warn(LD_PROCESS, "SleepEx() returned %lu", ret);
424 /** Start the periodic timer which is reponsible for checking whether processes
425 * are still alive and to make sure that the Tor process is periodically being
426 * moved into an alertable state. */
427 STATIC void
428 process_win32_timer_start(void)
430 /* Make sure we never start our timer if it's already running. */
431 if (BUG(process_win32_timer_running()))
432 return;
434 /* Wake up once a second. */
435 static const struct timeval interval = {1, 0};
437 log_info(LD_PROCESS, "Starting Windows Process I/O timer");
438 periodic_timer = periodic_timer_new(tor_libevent_get_base(),
439 &interval,
440 process_win32_timer_callback,
441 NULL);
444 /** Stops the periodic timer. */
445 STATIC void
446 process_win32_timer_stop(void)
448 if (BUG(periodic_timer == NULL))
449 return;
451 log_info(LD_PROCESS, "Stopping Windows Process I/O timer");
452 periodic_timer_free(periodic_timer);
455 /** Returns true iff the periodic timer is running. */
456 STATIC bool
457 process_win32_timer_running(void)
459 return periodic_timer != NULL;
462 /** This function is called whenever the periodic_timer ticks. The function is
463 * responsible for moving the Tor process into an alertable state once a second
464 * and checking for whether our child processes have terminated since the last
465 * tick. */
466 STATIC void
467 process_win32_timer_callback(periodic_timer_t *timer, void *data)
469 tor_assert(timer == periodic_timer);
470 tor_assert(data == NULL);
472 log_debug(LD_PROCESS, "Windows Process I/O timer ticked");
474 /* Move the process into an alertable state. */
475 process_win32_trigger_completion_callbacks();
477 /* Check if our processes are still alive. */
478 const smartlist_t *processes = process_get_all_processes();
480 SMARTLIST_FOREACH(processes, process_t *, p,
481 process_win32_timer_test_process(p));
484 /** Test whether a given process is still alive. Notify the Process subsystem
485 * if our process have died. */
486 STATIC void
487 process_win32_timer_test_process(process_t *process)
489 tor_assert(process);
491 /* No need to look at processes that don't claim they are running. */
492 if (process_get_status(process) != PROCESS_STATUS_RUNNING)
493 return;
495 process_win32_t *win32_process = process_get_win32_process(process);
496 BOOL ret = FALSE;
497 DWORD exit_code = 0;
499 /* We start by testing whether our process is still running. */
500 ret = GetExitCodeProcess(win32_process->process_information.hProcess,
501 &exit_code);
503 if (! ret) {
504 log_warn(LD_PROCESS, "GetExitCodeProcess() failed: %s",
505 format_win32_error(GetLastError()));
506 return;
509 /* Notify our process_t that our process have terminated. */
510 if (exit_code != STILL_ACTIVE)
511 process_notify_event_exit(process, exit_code);
514 /** Create a new overlapped named pipe. This function creates a new connected,
515 * named, pipe in <b>*read_pipe</b> and <b>*write_pipe</b> if the function is
516 * succesful. Returns true on sucess, false on failure. */
517 STATIC bool
518 process_win32_create_pipe(HANDLE *read_pipe,
519 HANDLE *write_pipe,
520 SECURITY_ATTRIBUTES *attributes,
521 process_win32_pipe_type_t pipe_type)
523 tor_assert(read_pipe);
524 tor_assert(write_pipe);
525 tor_assert(attributes);
527 BOOL ret = FALSE;
529 /* Buffer size. */
530 const size_t size = 4096;
532 /* Our additional read/write modes that depends on which pipe type we are
533 * creating. */
534 DWORD read_mode = 0;
535 DWORD write_mode = 0;
537 /* Generate the unique pipe name. */
538 char pipe_name[MAX_PATH];
539 static DWORD process_id = 0;
540 static DWORD counter = 0;
542 if (process_id == 0)
543 process_id = GetCurrentProcessId();
545 tor_snprintf(pipe_name, sizeof(pipe_name),
546 "\\\\.\\Pipe\\Tor-Process-Pipe-%lu-%lu",
547 process_id, counter++);
549 /* Only one of our handles can be overlapped. */
550 switch (pipe_type) {
551 case PROCESS_WIN32_PIPE_TYPE_READER:
552 read_mode = FILE_FLAG_OVERLAPPED;
553 break;
554 case PROCESS_WIN32_PIPE_TYPE_WRITER:
555 write_mode = FILE_FLAG_OVERLAPPED;
556 break;
557 default:
558 /* LCOV_EXCL_START */
559 tor_assert_nonfatal_unreached_once();
560 /* LCOV_EXCL_STOP */
563 /* Setup our read and write handles. */
564 HANDLE read_handle;
565 HANDLE write_handle;
567 /* Create our named pipe. */
568 read_handle = CreateNamedPipeA(pipe_name,
569 (PIPE_ACCESS_INBOUND|read_mode),
570 (PIPE_TYPE_BYTE|PIPE_WAIT),
572 size,
573 size,
574 1000,
575 attributes);
577 if (read_handle == INVALID_HANDLE_VALUE) {
578 log_warn(LD_PROCESS, "CreateNamedPipeA() failed: %s",
579 format_win32_error(GetLastError()));
580 return false;
583 /* Create our file in the pipe namespace. */
584 write_handle = CreateFileA(pipe_name,
585 GENERIC_WRITE,
587 attributes,
588 OPEN_EXISTING,
589 (FILE_ATTRIBUTE_NORMAL|write_mode),
590 NULL);
592 if (write_handle == INVALID_HANDLE_VALUE) {
593 log_warn(LD_PROCESS, "CreateFileA() failed: %s",
594 format_win32_error(GetLastError()));
596 CloseHandle(read_handle);
598 return false;
601 /* Set the inherit flag for our pipe. */
602 switch (pipe_type) {
603 case PROCESS_WIN32_PIPE_TYPE_READER:
604 ret = SetHandleInformation(read_handle, HANDLE_FLAG_INHERIT, 0);
605 break;
606 case PROCESS_WIN32_PIPE_TYPE_WRITER:
607 ret = SetHandleInformation(write_handle, HANDLE_FLAG_INHERIT, 0);
608 break;
609 default:
610 /* LCOV_EXCL_START */
611 tor_assert_nonfatal_unreached_once();
612 /* LCOV_EXCL_STOP */
615 if (! ret) {
616 log_warn(LD_PROCESS, "SetHandleInformation() failed: %s",
617 format_win32_error(GetLastError()));
619 CloseHandle(read_handle);
620 CloseHandle(write_handle);
622 return false;
625 /* Everything is good. */
626 *read_pipe = read_handle;
627 *write_pipe = write_handle;
629 return true;
632 /** Cleanup a given <b>handle</b>. */
633 STATIC void
634 process_win32_cleanup_handle(process_win32_handle_t *handle)
636 tor_assert(handle);
638 #if 0
639 /* FIXME(ahf): My compiler does not set _WIN32_WINNT to a high enough value
640 * for this code to be available. Should we force it? CancelIoEx() is
641 * available from Windows 7 and above. If we decide to require this, we need
642 * to update the checks in all the three I/O completion callbacks to handle
643 * the ERROR_OPERATION_ABORTED as well as ERROR_BROKEN_PIPE. */
645 #if _WIN32_WINNT >= 0x0600
646 /* This code is only supported from Windows 7 and onwards. */
647 BOOL ret;
648 DWORD error_code;
650 /* Cancel any pending I/O requests. */
651 ret = CancelIoEx(handle->pipe, &handle->overlapped);
653 if (! ret) {
654 error_code = GetLastError();
656 /* There was no pending I/O requests for our handle. */
657 if (error_code != ERROR_NOT_FOUND) {
658 log_warn(LD_PROCESS, "CancelIoEx() failed: %s",
659 format_win32_error(error_code));
662 #endif
663 #endif
665 /* Close our handle. */
666 if (handle->pipe != INVALID_HANDLE_VALUE) {
667 CloseHandle(handle->pipe);
668 handle->pipe = INVALID_HANDLE_VALUE;
672 /** This function is called when ReadFileEx() completes its background read
673 * from the child process's standard output. We notify the Process subsystem if
674 * there is data available for it to read from us. */
675 STATIC VOID WINAPI
676 process_win32_stdout_read_done(DWORD error_code,
677 DWORD byte_count,
678 LPOVERLAPPED overlapped)
680 tor_assert(overlapped);
681 tor_assert(overlapped->hEvent);
683 /* This happens when we have asked ReadFileEx() to read some data, but we
684 * then decided to call CloseHandle() on the HANDLE. This can happen if
685 * someone runs process_free() in the exit_callback of process_t, which means
686 * we cannot call process_get_win32_process() here. */
687 if (error_code == ERROR_BROKEN_PIPE) {
688 log_debug(LD_PROCESS, "Process reported broken pipe on standard out");
689 return;
692 /* Extract our process_t from the hEvent member of OVERLAPPED. */
693 process_t *process = (process_t *)overlapped->hEvent;
694 process_win32_t *win32_process = process_get_win32_process(process);
696 if (process_win32_handle_read_completion(&win32_process->stdout_handle,
697 error_code,
698 byte_count)) {
699 /* Schedule our next read. */
700 process_notify_event_stdout(process);
704 /** This function is called when ReadFileEx() completes its background read
705 * from the child process's standard error. We notify the Process subsystem if
706 * there is data available for it to read from us. */
707 STATIC VOID WINAPI
708 process_win32_stderr_read_done(DWORD error_code,
709 DWORD byte_count,
710 LPOVERLAPPED overlapped)
712 tor_assert(overlapped);
713 tor_assert(overlapped->hEvent);
715 /* This happens when we have asked ReadFileEx() to read some data, but we
716 * then decided to call CloseHandle() on the HANDLE. This can happen if
717 * someone runs process_free() in the exit_callback of process_t, which means
718 * we cannot call process_get_win32_process() here. */
719 if (error_code == ERROR_BROKEN_PIPE) {
720 log_debug(LD_PROCESS, "Process reported broken pipe on standard error");
721 return;
724 /* Extract our process_t from the hEvent member of OVERLAPPED. */
725 process_t *process = (process_t *)overlapped->hEvent;
726 process_win32_t *win32_process = process_get_win32_process(process);
728 if (process_win32_handle_read_completion(&win32_process->stderr_handle,
729 error_code,
730 byte_count)) {
731 /* Schedule our next read. */
732 process_notify_event_stderr(process);
736 /** This function is called when WriteFileEx() completes its background write
737 * to the child process's standard input. We notify the Process subsystem that
738 * it can write data to us again. */
739 STATIC VOID WINAPI
740 process_win32_stdin_write_done(DWORD error_code,
741 DWORD byte_count,
742 LPOVERLAPPED overlapped)
744 tor_assert(overlapped);
745 tor_assert(overlapped->hEvent);
747 (void)byte_count;
749 /* This happens when we have asked WriteFileEx() to write some data, but we
750 * then decided to call CloseHandle() on the HANDLE. This can happen if
751 * someone runs process_free() in the exit_callback of process_t, which means
752 * we cannot call process_get_win32_process() here. */
753 if (error_code == ERROR_BROKEN_PIPE) {
754 log_debug(LD_PROCESS, "Process reported broken pipe on standard input");
755 return;
758 process_t *process = (process_t *)overlapped->hEvent;
759 process_win32_t *win32_process = process_get_win32_process(process);
761 /* Mark our handle as not having any outstanding I/O requests. */
762 win32_process->stdin_handle.busy = false;
764 /* Check if we have been asked to write to the handle that have been marked
765 * as having reached EOF. */
766 if (BUG(win32_process->stdin_handle.reached_eof))
767 return;
769 if (error_code == 0) {
770 /** Our data have been succesfully written. Clear our state and schedule
771 * the next write. */
772 win32_process->stdin_handle.data_available = 0;
773 memset(win32_process->stdin_handle.buffer, 0,
774 sizeof(win32_process->stdin_handle.buffer));
776 /* Schedule the next write. */
777 process_notify_event_stdin(process);
778 } else if (error_code == ERROR_HANDLE_EOF) {
779 /* Our WriteFileEx() call was succesful, but we reached the end of our
780 * file. We mark our handle as having reached EOF and returns. */
781 tor_assert(byte_count == 0);
783 win32_process->stdin_handle.reached_eof = true;
784 } else {
785 /* An error happened: We warn the user and mark our handle as having
786 * reached EOF */
787 log_warn(LD_PROCESS,
788 "Error in I/O completion routine from WriteFileEx(): %s",
789 format_win32_error(error_code));
790 win32_process->stdin_handle.reached_eof = true;
794 /** This function reads data from the given <b>handle</b>'s internal buffer and
795 * moves it into the given <b>buffer</b>. Additionally, we start the next
796 * ReadFileEx() background operation with the given <b>callback</b> as
797 * completion callback. Returns the number of bytes written to the buffer. */
798 STATIC int
799 process_win32_read_from_handle(process_win32_handle_t *handle,
800 buf_t *buffer,
801 LPOVERLAPPED_COMPLETION_ROUTINE callback)
803 tor_assert(handle);
804 tor_assert(buffer);
805 tor_assert(callback);
807 BOOL ret = FALSE;
808 int bytes_available = 0;
810 /* We already have a request to read data that isn't complete yet. */
811 if (BUG(handle->busy))
812 return 0;
814 /* Check if we have been asked to read from a handle that have already told
815 * us that we have reached the end of the file. */
816 if (BUG(handle->reached_eof))
817 return 0;
819 /* This cast should be safe since our buffer can be at maximum up to
820 * BUFFER_SIZE in size. */
821 bytes_available = (int)handle->data_available;
823 if (handle->data_available > 0) {
824 /* Read data from our intermediate buffer into the process_t buffer. */
825 buf_add(buffer, handle->buffer, handle->data_available);
827 /* Reset our read state. */
828 handle->data_available = 0;
829 memset(handle->buffer, 0, sizeof(handle->buffer));
832 /* Ask the Windows kernel to read data from our pipe into our buffer and call
833 * the callback function when it is done. */
834 ret = ReadFileEx(handle->pipe,
835 handle->buffer,
836 sizeof(handle->buffer),
837 &handle->overlapped,
838 callback);
840 if (! ret) {
841 log_warn(LD_PROCESS, "ReadFileEx() failed: %s",
842 format_win32_error(GetLastError()));
843 return bytes_available;
846 /* We mark our handle as having a pending I/O request. */
847 handle->busy = true;
849 return bytes_available;
852 /** This function checks the callback values from ReadFileEx() in
853 * <b>error_code</b> and <b>byte_count</b> if we have read data. Returns true
854 * iff our caller should request more data from ReadFileEx(). */
855 STATIC bool
856 process_win32_handle_read_completion(process_win32_handle_t *handle,
857 DWORD error_code,
858 DWORD byte_count)
860 tor_assert(handle);
862 /* Mark our handle as not having any outstanding I/O requests. */
863 handle->busy = false;
865 if (error_code == 0) {
866 /* Our ReadFileEx() call was succesful and there is data for us. */
868 /* This cast should be safe since byte_count should never be larger than
869 * BUFFER_SIZE. */
870 tor_assert(byte_count <= BUFFER_SIZE);
871 handle->data_available = (size_t)byte_count;
873 /* Tell our caller to schedule the next read. */
874 return true;
875 } else if (error_code == ERROR_HANDLE_EOF) {
876 /* Our ReadFileEx() call was succesful, but we reached the end of our file.
877 * We mark our handle as having reached EOF and returns. */
878 tor_assert(byte_count == 0);
880 handle->reached_eof = true;
881 } else {
882 /* An error happened: We warn the user and mark our handle as having
883 * reached EOF */
884 log_warn(LD_PROCESS,
885 "Error in I/O completion routine from ReadFileEx(): %s",
886 format_win32_error(error_code));
888 handle->reached_eof = true;
891 /* Our caller should NOT schedule the next read. */
892 return false;
895 /** Format a single argument for being put on a Windows command line.
896 * Returns a newly allocated string */
897 STATIC char *
898 format_win_cmdline_argument(const char *arg)
900 char *formatted_arg;
901 char need_quotes;
902 const char *c;
903 int i;
904 int bs_counter = 0;
905 /* Backslash we can point to when one is inserted into the string */
906 const char backslash = '\\';
908 /* Smartlist of *char */
909 smartlist_t *arg_chars;
910 arg_chars = smartlist_new();
912 /* Quote string if it contains whitespace or is empty */
913 need_quotes = (strchr(arg, ' ') || strchr(arg, '\t') || '\0' == arg[0]);
915 /* Build up smartlist of *chars */
916 for (c=arg; *c != '\0'; c++) {
917 if ('"' == *c) {
918 /* Double up backslashes preceding a quote */
919 for (i=0; i<(bs_counter*2); i++)
920 smartlist_add(arg_chars, (void*)&backslash);
921 bs_counter = 0;
922 /* Escape the quote */
923 smartlist_add(arg_chars, (void*)&backslash);
924 smartlist_add(arg_chars, (void*)c);
925 } else if ('\\' == *c) {
926 /* Count backslashes until we know whether to double up */
927 bs_counter++;
928 } else {
929 /* Don't double up slashes preceding a non-quote */
930 for (i=0; i<bs_counter; i++)
931 smartlist_add(arg_chars, (void*)&backslash);
932 bs_counter = 0;
933 smartlist_add(arg_chars, (void*)c);
936 /* Don't double up trailing backslashes */
937 for (i=0; i<bs_counter; i++)
938 smartlist_add(arg_chars, (void*)&backslash);
940 /* Allocate space for argument, quotes (if needed), and terminator */
941 const size_t formatted_arg_len = smartlist_len(arg_chars) +
942 (need_quotes ? 2 : 0) + 1;
943 formatted_arg = tor_malloc_zero(formatted_arg_len);
945 /* Add leading quote */
946 i=0;
947 if (need_quotes)
948 formatted_arg[i++] = '"';
950 /* Add characters */
951 SMARTLIST_FOREACH(arg_chars, char*, ch,
953 formatted_arg[i++] = *ch;
956 /* Add trailing quote */
957 if (need_quotes)
958 formatted_arg[i++] = '"';
959 formatted_arg[i] = '\0';
961 smartlist_free(arg_chars);
962 return formatted_arg;
965 /** Format a command line for use on Windows, which takes the command as a
966 * string rather than string array. Follows the rules from "Parsing C++
967 * Command-Line Arguments" in MSDN. Algorithm based on list2cmdline in the
968 * Python subprocess module. Returns a newly allocated string */
969 STATIC char *
970 tor_join_win_cmdline(const char *argv[])
972 smartlist_t *argv_list;
973 char *joined_argv;
974 int i;
976 /* Format each argument and put the result in a smartlist */
977 argv_list = smartlist_new();
978 for (i=0; argv[i] != NULL; i++) {
979 smartlist_add(argv_list, (void *)format_win_cmdline_argument(argv[i]));
982 /* Join the arguments with whitespace */
983 joined_argv = smartlist_join_strings(argv_list, " ", 0, NULL);
985 /* Free the newly allocated arguments, and the smartlist */
986 SMARTLIST_FOREACH(argv_list, char *, arg,
988 tor_free(arg);
990 smartlist_free(argv_list);
992 return joined_argv;
995 #endif /* ! defined(_WIN32). */