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 */
7 * \file process_win32.c
8 * \brief Module for working with Windows processes.
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
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()
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. */
49 /** True iff we have reached EOF from the pipe. */
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? */
65 /** Structure to represent the Windows specific implementation details of this
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>
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
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
;
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>. */
107 process_win32_free_(process_win32_t
*win32_process
)
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. */
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. */
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. */
142 process_win32_exec(process_t
*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
;
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
,
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
,
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
,
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
,
220 env
->windows_environment_block
[0] == '\0' ?
221 NULL
: env
->windows_environment_block
,
224 &win32_process
->process_information
);
227 tor_free(joined_argv
);
228 process_environment_free(env
);
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. */
279 process_win32_terminate(process_t
*process
)
283 process_win32_t
*win32_process
= process_get_win32_process(process
);
285 /* Terminate our process. */
288 ret
= TerminateProcess(win32_process
->process_information
.hProcess
, 0);
291 log_warn(LD_PROCESS
, "TerminateProcess() failed: %s",
292 format_win32_error(GetLastError()));
299 /** Returns the unique process identifier for the given <b>process</b>. */
301 process_win32_get_pid(process_t
*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.
315 process_win32_write(struct process_t
*process
, buf_t
*buffer
)
320 process_win32_t
*win32_process
= process_get_win32_process(process
);
322 const size_t buffer_size
= buf_datalen(buffer
);
324 /* Windows is still writing our buffer. */
325 if (win32_process
->stdin_handle
.busy
)
328 /* Nothing for us to do right now. */
329 if (buffer_size
== 0)
332 /* We have reached end of file already? */
333 if (BUG(win32_process
->stdin_handle
.reached_eof
))
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
,
347 &win32_process
->stdin_handle
.overlapped
,
348 process_win32_stdin_write_done
);
351 log_warn(LD_PROCESS
, "WriteFileEx() failed: %s",
352 format_win32_error(GetLastError()));
356 /* This cast should be safe since our buffer can maximum be BUFFER_SIZE
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>.
368 process_win32_read_stdout(struct process_t
*process
, buf_t
*buffer
)
373 process_win32_t
*win32_process
= process_get_win32_process(process
);
375 return process_win32_read_from_handle(&win32_process
->stdout_handle
,
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>.
387 process_win32_read_stderr(struct process_t
*process
, buf_t
*buffer
)
392 process_win32_t
*win32_process
= process_get_win32_process(process
);
394 return process_win32_read_from_handle(&win32_process
->stderr_handle
,
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. */
404 process_win32_trigger_completion_callbacks(void)
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. */
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()))
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(),
440 process_win32_timer_callback
,
444 /** Stops the periodic timer. */
446 process_win32_timer_stop(void)
448 if (BUG(periodic_timer
== NULL
))
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. */
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
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. */
487 process_win32_timer_test_process(process_t
*process
)
491 /* No need to look at processes that don't claim they are running. */
492 if (process_get_status(process
) != PROCESS_STATUS_RUNNING
)
495 process_win32_t
*win32_process
= process_get_win32_process(process
);
499 /* We start by testing whether our process is still running. */
500 ret
= GetExitCodeProcess(win32_process
->process_information
.hProcess
,
504 log_warn(LD_PROCESS
, "GetExitCodeProcess() failed: %s",
505 format_win32_error(GetLastError()));
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. */
518 process_win32_create_pipe(HANDLE
*read_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
);
530 const size_t size
= 4096;
532 /* Our additional read/write modes that depends on which pipe type we are
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;
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. */
551 case PROCESS_WIN32_PIPE_TYPE_READER
:
552 read_mode
= FILE_FLAG_OVERLAPPED
;
554 case PROCESS_WIN32_PIPE_TYPE_WRITER
:
555 write_mode
= FILE_FLAG_OVERLAPPED
;
558 /* LCOV_EXCL_START */
559 tor_assert_nonfatal_unreached_once();
563 /* Setup our read and write handles. */
567 /* Create our named pipe. */
568 read_handle
= CreateNamedPipeA(pipe_name
,
569 (PIPE_ACCESS_INBOUND
|read_mode
),
570 (PIPE_TYPE_BYTE
|PIPE_WAIT
),
577 if (read_handle
== INVALID_HANDLE_VALUE
) {
578 log_warn(LD_PROCESS
, "CreateNamedPipeA() failed: %s",
579 format_win32_error(GetLastError()));
583 /* Create our file in the pipe namespace. */
584 write_handle
= CreateFileA(pipe_name
,
589 (FILE_ATTRIBUTE_NORMAL
|write_mode
),
592 if (write_handle
== INVALID_HANDLE_VALUE
) {
593 log_warn(LD_PROCESS
, "CreateFileA() failed: %s",
594 format_win32_error(GetLastError()));
596 CloseHandle(read_handle
);
601 /* Set the inherit flag for our pipe. */
603 case PROCESS_WIN32_PIPE_TYPE_READER
:
604 ret
= SetHandleInformation(read_handle
, HANDLE_FLAG_INHERIT
, 0);
606 case PROCESS_WIN32_PIPE_TYPE_WRITER
:
607 ret
= SetHandleInformation(write_handle
, HANDLE_FLAG_INHERIT
, 0);
610 /* LCOV_EXCL_START */
611 tor_assert_nonfatal_unreached_once();
616 log_warn(LD_PROCESS
, "SetHandleInformation() failed: %s",
617 format_win32_error(GetLastError()));
619 CloseHandle(read_handle
);
620 CloseHandle(write_handle
);
625 /* Everything is good. */
626 *read_pipe
= read_handle
;
627 *write_pipe
= write_handle
;
632 /** Cleanup a given <b>handle</b>. */
634 process_win32_cleanup_handle(process_win32_handle_t
*handle
)
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. */
650 /* Cancel any pending I/O requests. */
651 ret
= CancelIoEx(handle
->pipe
, &handle
->overlapped
);
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
));
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. */
676 process_win32_stdout_read_done(DWORD error_code
,
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");
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
,
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. */
708 process_win32_stderr_read_done(DWORD error_code
,
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");
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
,
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. */
740 process_win32_stdin_write_done(DWORD error_code
,
742 LPOVERLAPPED overlapped
)
744 tor_assert(overlapped
);
745 tor_assert(overlapped
->hEvent
);
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");
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
))
769 if (error_code
== 0) {
770 /** Our data have been succesfully written. Clear our state and schedule
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;
785 /* An error happened: We warn the user and mark our handle as having
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. */
799 process_win32_read_from_handle(process_win32_handle_t
*handle
,
801 LPOVERLAPPED_COMPLETION_ROUTINE callback
)
805 tor_assert(callback
);
808 int bytes_available
= 0;
810 /* We already have a request to read data that isn't complete yet. */
811 if (BUG(handle
->busy
))
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
))
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
,
836 sizeof(handle
->buffer
),
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. */
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(). */
856 process_win32_handle_read_completion(process_win32_handle_t
*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
870 tor_assert(byte_count
<= BUFFER_SIZE
);
871 handle
->data_available
= (size_t)byte_count
;
873 /* Tell our caller to schedule the next read. */
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;
882 /* An error happened: We warn the user and mark our handle as having
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. */
895 /** Format a single argument for being put on a Windows command line.
896 * Returns a newly allocated string */
898 format_win_cmdline_argument(const char *arg
)
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
++) {
918 /* Double up backslashes preceding a quote */
919 for (i
=0; i
<(bs_counter
*2); i
++)
920 smartlist_add(arg_chars
, (void*)&backslash
);
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 */
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
);
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 */
948 formatted_arg
[i
++] = '"';
951 SMARTLIST_FOREACH(arg_chars
, char*, ch
,
953 formatted_arg
[i
++] = *ch
;
956 /* Add trailing quote */
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 */
970 tor_join_win_cmdline(const char *argv
[])
972 smartlist_t
*argv_list
;
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
,
990 smartlist_free(argv_list
);
995 #endif /* ! defined(_WIN32). */