tor  0.4.2.1-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-2019, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
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 
34 #define BUFFER_SIZE (1024)
35 
38 static periodic_timer_t *periodic_timer;
39 
45 struct process_win32_handle_t {
47  HANDLE pipe;
48 
50  bool reached_eof;
51 
53  size_t data_available;
54 
56  char buffer[BUFFER_SIZE];
57 
59  OVERLAPPED overlapped;
60 
62  bool busy;
63 };
64 
71 struct process_win32_t {
73  process_win32_handle_t stdin_handle;
74 
76  process_win32_handle_t stdout_handle;
77 
79  process_win32_handle_t stderr_handle;
80 
82  PROCESS_INFORMATION process_information;
83 };
84 
89 process_win32_t *
90 process_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 
106 void
107 process_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 
121 void
122 process_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 
130 void
131 process_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 
142 process_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)) {
169  return PROCESS_STATUS_ERROR;
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)) {
177  return PROCESS_STATUS_ERROR;
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)) {
185  return PROCESS_STATUS_ERROR;
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  return PROCESS_STATUS_ERROR;
238  }
239 
240  /* TODO: Should we close hProcess and hThread in
241  * process_handle->process_information? */
242  win32_process->stdout_handle.pipe = stdout_pipe_read;
243  win32_process->stderr_handle.pipe = stderr_pipe_read;
244  win32_process->stdin_handle.pipe = stdin_pipe_write;
245 
246  /* Close our ends of the pipes that is now owned by the child process. */
247  CloseHandle(stdout_pipe_write);
248  CloseHandle(stderr_pipe_write);
249  CloseHandle(stdin_pipe_read);
250 
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.
253  *
254  * Warning, here be dragons:
255  *
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.
259  */
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;
263 
264  /* Start our timer if it is not already running. */
265  if (! process_win32_timer_running())
266  process_win32_timer_start();
267 
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. */
273 
274  return PROCESS_STATUS_RUNNING;
275 }
276 
278 bool
279 process_win32_terminate(process_t *process)
280 {
281  tor_assert(process);
282 
283  process_win32_t *win32_process = process_get_win32_process(process);
284 
285  /* Terminate our process. */
286  BOOL ret;
287 
288  ret = TerminateProcess(win32_process->process_information.hProcess, 0);
289 
290  if (! ret) {
291  log_warn(LD_PROCESS, "TerminateProcess() failed: %s",
292  format_win32_error(GetLastError()));
293  return false;
294  }
295 
296  /* Cleanup our handles. */
297  process_win32_cleanup_handle(&win32_process->stdin_handle);
298  process_win32_cleanup_handle(&win32_process->stdout_handle);
299  process_win32_cleanup_handle(&win32_process->stderr_handle);
300 
301  return true;
302 }
303 
305 process_pid_t
306 process_win32_get_pid(process_t *process)
307 {
308  tor_assert(process);
309 
310  process_win32_t *win32_process = process_get_win32_process(process);
311  return (process_pid_t)win32_process->process_information.dwProcessId;
312 }
313 
319 int
320 process_win32_write(struct process_t *process, buf_t *buffer)
321 {
322  tor_assert(process);
323  tor_assert(buffer);
324 
325  process_win32_t *win32_process = process_get_win32_process(process);
326  BOOL ret = FALSE;
327  DWORD error_code = 0;
328  const size_t buffer_size = buf_datalen(buffer);
329 
330  /* Windows is still writing our buffer. */
331  if (win32_process->stdin_handle.busy)
332  return 0;
333 
334  /* Nothing for us to do right now. */
335  if (buffer_size == 0)
336  return 0;
337 
338  /* We have reached end of file already? */
339  if (BUG(win32_process->stdin_handle.reached_eof))
340  return 0;
341 
342  /* Figure out how much data we should read. */
343  const size_t write_size = MIN(buffer_size,
344  sizeof(win32_process->stdin_handle.buffer));
345 
346  /* Read data from the process_t buffer into our intermediate buffer. */
347  buf_get_bytes(buffer, win32_process->stdin_handle.buffer, write_size);
348 
349  /* Because of the slightly weird API for WriteFileEx() we must set this to 0
350  * before we call WriteFileEx() because WriteFileEx() does not reset the last
351  * error itself when it's succesful. See comment below after the call to
352  * GetLastError(). */
353  SetLastError(0);
354 
355  /* Schedule our write. */
356  ret = WriteFileEx(win32_process->stdin_handle.pipe,
357  win32_process->stdin_handle.buffer,
358  write_size,
359  &win32_process->stdin_handle.overlapped,
360  process_win32_stdin_write_done);
361 
362  if (! ret) {
363  error_code = GetLastError();
364 
365  /* No need to log at warning level for these two. */
366  if (error_code == ERROR_HANDLE_EOF || error_code == ERROR_BROKEN_PIPE) {
367  log_debug(LD_PROCESS, "WriteFileEx() returned EOF from pipe: %s",
368  format_win32_error(error_code));
369  } else {
370  log_warn(LD_PROCESS, "WriteFileEx() failed: %s",
371  format_win32_error(error_code));
372  }
373 
374  win32_process->stdin_handle.reached_eof = true;
375  return 0;
376  }
377 
378  /* Here be dragons: According to MSDN's documentation for WriteFileEx() we
379  * should check GetLastError() after a call to WriteFileEx() even though the
380  * `ret` return value was successful. If everything is good, GetLastError()
381  * returns `ERROR_SUCCESS` and nothing happens.
382  *
383  * XXX(ahf): I have not managed to trigger this code while stress-testing
384  * this code. */
385  error_code = GetLastError();
386 
387  if (error_code != ERROR_SUCCESS) {
388  /* LCOV_EXCL_START */
389  log_warn(LD_PROCESS, "WriteFileEx() failed after returning success: %s",
390  format_win32_error(error_code));
391  win32_process->stdin_handle.reached_eof = true;
392  return 0;
393  /* LCOV_EXCL_STOP */
394  }
395 
396  /* This cast should be safe since our buffer can maximum be BUFFER_SIZE
397  * large. */
398  return (int)write_size;
399 }
400 
407 int
408 process_win32_read_stdout(struct process_t *process, buf_t *buffer)
409 {
410  tor_assert(process);
411  tor_assert(buffer);
412 
413  process_win32_t *win32_process = process_get_win32_process(process);
414 
415  return process_win32_read_from_handle(&win32_process->stdout_handle,
416  buffer,
417  process_win32_stdout_read_done);
418 }
419 
426 int
427 process_win32_read_stderr(struct process_t *process, buf_t *buffer)
428 {
429  tor_assert(process);
430  tor_assert(buffer);
431 
432  process_win32_t *win32_process = process_get_win32_process(process);
433 
434  return process_win32_read_from_handle(&win32_process->stderr_handle,
435  buffer,
436  process_win32_stderr_read_done);
437 }
438 
443 void
444 process_win32_trigger_completion_callbacks(void)
445 {
446  DWORD ret;
447 
448  /* The call to SleepEx(dwMilliseconds, dwAlertable) makes the process sleep
449  * for dwMilliseconds and if dwAlertable is set to TRUE it will also cause
450  * the process to enter alertable state, where the Windows kernel will notify
451  * us about completed I/O requests from ReadFileEx() and WriteFileEX(), which
452  * will cause our completion callbacks to be executed.
453  *
454  * This function returns 0 if the time interval expired or WAIT_IO_COMPLETION
455  * if one or more I/O callbacks were executed. */
456  ret = SleepEx(0, TRUE);
457 
458  /* Warn us if the function returned something we did not anticipate. */
459  if (ret != 0 && ret != WAIT_IO_COMPLETION) {
460  log_warn(LD_PROCESS, "SleepEx() returned %lu", ret);
461  }
462 }
463 
467 void
468 process_win32_timer_start(void)
469 {
470  /* Make sure we never start our timer if it's already running. */
471  if (BUG(process_win32_timer_running()))
472  return;
473 
474  /* Wake up once a second. */
475  static const struct timeval interval = {1, 0};
476 
477  log_info(LD_PROCESS, "Starting Windows Process I/O timer");
478  periodic_timer = periodic_timer_new(tor_libevent_get_base(),
479  &interval,
480  process_win32_timer_callback,
481  NULL);
482 }
483 
485 void
486 process_win32_timer_stop(void)
487 {
488  if (BUG(periodic_timer == NULL))
489  return;
490 
491  log_info(LD_PROCESS, "Stopping Windows Process I/O timer");
492  periodic_timer_free(periodic_timer);
493 }
494 
496 bool
497 process_win32_timer_running(void)
498 {
499  return periodic_timer != NULL;
500 }
501 
506 STATIC void
507 process_win32_timer_callback(periodic_timer_t *timer, void *data)
508 {
509  tor_assert(timer == periodic_timer);
510  tor_assert(data == NULL);
511 
512  /* Move the process into an alertable state. */
513  process_win32_trigger_completion_callbacks();
514 
515  /* Check if our processes are still alive. */
516 
517  /* Since the call to process_win32_timer_test_process() might call
518  * process_notify_event_exit() which again might call process_free() which
519  * updates the list of processes returned by process_get_all_processes() it
520  * is important here that we make sure to not touch the list of processes if
521  * the call to process_win32_timer_test_process() returns true. */
522  bool done;
523 
524  do {
526  done = true;
527 
529  /* If process_win32_timer_test_process() returns true, it means that
530  * smartlist_remove() might have been called on the list returned by
531  * process_get_all_processes(). We start the loop over again until we
532  * have a succesful run over the entire list where the list was not
533  * modified. */
534  if (process_win32_timer_test_process(process)) {
535  done = false;
536  break;
537  }
538  } SMARTLIST_FOREACH_END(process);
539  } while (! done);
540 }
541 
545 STATIC bool
546 process_win32_timer_test_process(process_t *process)
547 {
548  tor_assert(process);
549 
550  /* No need to look at processes that don't claim they are running. */
552  return false;
553 
554  process_win32_t *win32_process = process_get_win32_process(process);
555  BOOL ret = FALSE;
556  DWORD exit_code = 0;
557 
558  /* Sometimes the Windows kernel wont give us the EOF/Broken Pipe error
559  * message until some time after the process have actually terminated. We
560  * make sure that our ReadFileEx() calls for the process have *all* returned
561  * and both standard out and error have been marked as EOF before we try to
562  * see if the process terminated.
563  *
564  * This ensures that we *never* call the exit callback of the `process_t`,
565  * which potentially ends up calling `process_free()` on our `process_t`,
566  * before all data have been received from the process.
567  *
568  * We do NOT have a check here for whether standard in reached EOF since
569  * standard in's WriteFileEx() function is only called on-demand when we have
570  * something to write and is thus usually not awaiting to finish any
571  * operations. If we WriteFileEx() to a file that has terminated we'll simply
572  * get an error from ReadFileEx() or its completion routine and move on with
573  * life. */
574  if (! win32_process->stdout_handle.reached_eof)
575  return false;
576 
577  if (! win32_process->stderr_handle.reached_eof)
578  return false;
579 
580  /* We start by testing whether our process is still running. */
581  ret = GetExitCodeProcess(win32_process->process_information.hProcess,
582  &exit_code);
583 
584  if (! ret) {
585  log_warn(LD_PROCESS, "GetExitCodeProcess() failed: %s",
586  format_win32_error(GetLastError()));
587  return false;
588  }
589 
590  /* Notify our process_t that our process have terminated. Since our
591  * exit_callback might decide to process_free() our process handle it is very
592  * important that we do not touch the process_t after the call to
593  * process_notify_event_exit(). */
594  if (exit_code != STILL_ACTIVE) {
595  process_notify_event_exit(process, exit_code);
596  return true;
597  }
598 
599  return false;
600 }
601 
605 STATIC bool
606 process_win32_create_pipe(HANDLE *read_pipe,
607  HANDLE *write_pipe,
608  SECURITY_ATTRIBUTES *attributes,
609  process_win32_pipe_type_t pipe_type)
610 {
611  tor_assert(read_pipe);
612  tor_assert(write_pipe);
613  tor_assert(attributes);
614 
615  BOOL ret = FALSE;
616 
617  /* Buffer size. */
618  const size_t size = 4096;
619 
620  /* Our additional read/write modes that depends on which pipe type we are
621  * creating. */
622  DWORD read_mode = 0;
623  DWORD write_mode = 0;
624 
625  /* Generate the unique pipe name. */
626  char pipe_name[MAX_PATH];
627  static DWORD process_id = 0;
628  static DWORD counter = 0;
629 
630  if (process_id == 0)
631  process_id = GetCurrentProcessId();
632 
633  tor_snprintf(pipe_name, sizeof(pipe_name),
634  "\\\\.\\Pipe\\Tor-Process-Pipe-%lu-%lu",
635  process_id, counter++);
636 
637  /* Only one of our handles can be overlapped. */
638  switch (pipe_type) {
639  case PROCESS_WIN32_PIPE_TYPE_READER:
640  read_mode = FILE_FLAG_OVERLAPPED;
641  break;
642  case PROCESS_WIN32_PIPE_TYPE_WRITER:
643  write_mode = FILE_FLAG_OVERLAPPED;
644  break;
645  default:
646  /* LCOV_EXCL_START */
647  tor_assert_nonfatal_unreached_once();
648  /* LCOV_EXCL_STOP */
649  }
650 
651  /* Setup our read and write handles. */
652  HANDLE read_handle;
653  HANDLE write_handle;
654 
655  /* Create our named pipe. */
656  read_handle = CreateNamedPipeA(pipe_name,
657  (PIPE_ACCESS_INBOUND|read_mode),
658  (PIPE_TYPE_BYTE|PIPE_WAIT),
659  1,
660  size,
661  size,
662  1000,
663  attributes);
664 
665  if (read_handle == INVALID_HANDLE_VALUE) {
666  log_warn(LD_PROCESS, "CreateNamedPipeA() failed: %s",
667  format_win32_error(GetLastError()));
668  return false;
669  }
670 
671  /* Create our file in the pipe namespace. */
672  write_handle = CreateFileA(pipe_name,
673  GENERIC_WRITE,
674  0,
675  attributes,
676  OPEN_EXISTING,
677  (FILE_ATTRIBUTE_NORMAL|write_mode),
678  NULL);
679 
680  if (write_handle == INVALID_HANDLE_VALUE) {
681  log_warn(LD_PROCESS, "CreateFileA() failed: %s",
682  format_win32_error(GetLastError()));
683 
684  CloseHandle(read_handle);
685 
686  return false;
687  }
688 
689  /* Set the inherit flag for our pipe. */
690  switch (pipe_type) {
691  case PROCESS_WIN32_PIPE_TYPE_READER:
692  ret = SetHandleInformation(read_handle, HANDLE_FLAG_INHERIT, 0);
693  break;
694  case PROCESS_WIN32_PIPE_TYPE_WRITER:
695  ret = SetHandleInformation(write_handle, HANDLE_FLAG_INHERIT, 0);
696  break;
697  default:
698  /* LCOV_EXCL_START */
699  tor_assert_nonfatal_unreached_once();
700  /* LCOV_EXCL_STOP */
701  }
702 
703  if (! ret) {
704  log_warn(LD_PROCESS, "SetHandleInformation() failed: %s",
705  format_win32_error(GetLastError()));
706 
707  CloseHandle(read_handle);
708  CloseHandle(write_handle);
709 
710  return false;
711  }
712 
713  /* Everything is good. */
714  *read_pipe = read_handle;
715  *write_pipe = write_handle;
716 
717  return true;
718 }
719 
721 STATIC void
722 process_win32_cleanup_handle(process_win32_handle_t *handle)
723 {
724  tor_assert(handle);
725 
726 #if 0
727  BOOL ret;
728  DWORD error_code;
729 
730  /* Cancel any pending I/O requests: This means that instead of getting
731  * ERROR_BROKEN_PIPE we get ERROR_OPERATION_ABORTED, but it doesn't seem
732  * like this is needed. */
733  ret = CancelIo(handle->pipe);
734 
735  if (! ret) {
736  error_code = GetLastError();
737 
738  /* There was no pending I/O requests for our handle. */
739  if (error_code != ERROR_NOT_FOUND) {
740  log_warn(LD_PROCESS, "CancelIo() failed: %s",
741  format_win32_error(error_code));
742  }
743  }
744 #endif /* 0 */
745 
746  /* Close our handle. */
747  if (handle->pipe != INVALID_HANDLE_VALUE) {
748  CloseHandle(handle->pipe);
749  handle->pipe = INVALID_HANDLE_VALUE;
750  handle->reached_eof = true;
751  }
752 }
753 
757 STATIC VOID WINAPI
758 process_win32_stdout_read_done(DWORD error_code,
759  DWORD byte_count,
760  LPOVERLAPPED overlapped)
761 {
762  tor_assert(overlapped);
763  tor_assert(overlapped->hEvent);
764 
765  /* Extract our process_t from the hEvent member of OVERLAPPED. */
766  process_t *process = (process_t *)overlapped->hEvent;
767  process_win32_t *win32_process = process_get_win32_process(process);
768 
769  if (process_win32_handle_read_completion(&win32_process->stdout_handle,
770  error_code,
771  byte_count)) {
772  /* Schedule our next read. */
774  }
775 }
776 
780 STATIC VOID WINAPI
781 process_win32_stderr_read_done(DWORD error_code,
782  DWORD byte_count,
783  LPOVERLAPPED overlapped)
784 {
785  tor_assert(overlapped);
786  tor_assert(overlapped->hEvent);
787 
788  /* Extract our process_t from the hEvent member of OVERLAPPED. */
789  process_t *process = (process_t *)overlapped->hEvent;
790  process_win32_t *win32_process = process_get_win32_process(process);
791 
792  if (process_win32_handle_read_completion(&win32_process->stderr_handle,
793  error_code,
794  byte_count)) {
795  /* Schedule our next read. */
797  }
798 }
799 
803 STATIC VOID WINAPI
804 process_win32_stdin_write_done(DWORD error_code,
805  DWORD byte_count,
806  LPOVERLAPPED overlapped)
807 {
808  tor_assert(overlapped);
809  tor_assert(overlapped->hEvent);
810 
811  (void)byte_count;
812 
813  process_t *process = (process_t *)overlapped->hEvent;
814  process_win32_t *win32_process = process_get_win32_process(process);
815 
816  /* Mark our handle as not having any outstanding I/O requests. */
817  win32_process->stdin_handle.busy = false;
818 
819  /* Check if we have been asked to write to the handle that have been marked
820  * as having reached EOF. */
821  if (BUG(win32_process->stdin_handle.reached_eof))
822  return;
823 
824  if (error_code == 0) {
827  win32_process->stdin_handle.data_available = 0;
828  memset(win32_process->stdin_handle.buffer, 0,
829  sizeof(win32_process->stdin_handle.buffer));
830 
831  /* Schedule the next write. */
833  } else if (error_code == ERROR_HANDLE_EOF ||
834  error_code == ERROR_BROKEN_PIPE) {
835  /* Our WriteFileEx() call was succesful, but we reached the end of our
836  * file. We mark our handle as having reached EOF and returns. */
837  tor_assert(byte_count == 0);
838 
839  win32_process->stdin_handle.reached_eof = true;
840  } else {
841  /* An error happened: We warn the user and mark our handle as having
842  * reached EOF */
843  log_warn(LD_PROCESS,
844  "Error in I/O completion routine from WriteFileEx(): %s",
845  format_win32_error(error_code));
846  win32_process->stdin_handle.reached_eof = true;
847  }
848 }
849 
854 STATIC int
855 process_win32_read_from_handle(process_win32_handle_t *handle,
856  buf_t *buffer,
857  LPOVERLAPPED_COMPLETION_ROUTINE callback)
858 {
859  tor_assert(handle);
860  tor_assert(buffer);
861  tor_assert(callback);
862 
863  BOOL ret = FALSE;
864  int bytes_available = 0;
865  DWORD error_code = 0;
866 
867  /* We already have a request to read data that isn't complete yet. */
868  if (BUG(handle->busy))
869  return 0;
870 
871  /* Check if we have been asked to read from a handle that have already told
872  * us that we have reached the end of the file. */
873  if (BUG(handle->reached_eof))
874  return 0;
875 
876  /* This cast should be safe since our buffer can be at maximum up to
877  * BUFFER_SIZE in size. */
878  bytes_available = (int)handle->data_available;
879 
880  if (handle->data_available > 0) {
881  /* Read data from our intermediate buffer into the process_t buffer. */
882  buf_add(buffer, handle->buffer, handle->data_available);
883 
884  /* Reset our read state. */
885  handle->data_available = 0;
886  memset(handle->buffer, 0, sizeof(handle->buffer));
887  }
888 
889  /* Because of the slightly weird API for ReadFileEx() we must set this to 0
890  * before we call ReadFileEx() because ReadFileEx() does not reset the last
891  * error itself when it's succesful. See comment below after the call to
892  * GetLastError(). */
893  SetLastError(0);
894 
895  /* Ask the Windows kernel to read data from our pipe into our buffer and call
896  * the callback function when it is done. */
897  ret = ReadFileEx(handle->pipe,
898  handle->buffer,
899  sizeof(handle->buffer),
900  &handle->overlapped,
901  callback);
902 
903  if (! ret) {
904  error_code = GetLastError();
905 
906  /* No need to log at warning level for these two. */
907  if (error_code == ERROR_HANDLE_EOF || error_code == ERROR_BROKEN_PIPE) {
908  log_debug(LD_PROCESS, "ReadFileEx() returned EOF from pipe: %s",
909  format_win32_error(error_code));
910  } else {
911  log_warn(LD_PROCESS, "ReadFileEx() failed: %s",
912  format_win32_error(error_code));
913  }
914 
915  handle->reached_eof = true;
916  return bytes_available;
917  }
918 
919  /* Here be dragons: According to MSDN's documentation for ReadFileEx() we
920  * should check GetLastError() after a call to ReadFileEx() even though the
921  * `ret` return value was successful. If everything is good, GetLastError()
922  * returns `ERROR_SUCCESS` and nothing happens.
923  *
924  * XXX(ahf): I have not managed to trigger this code while stress-testing
925  * this code. */
926  error_code = GetLastError();
927 
928  if (error_code != ERROR_SUCCESS) {
929  /* LCOV_EXCL_START */
930  log_warn(LD_PROCESS, "ReadFileEx() failed after returning success: %s",
931  format_win32_error(error_code));
932  handle->reached_eof = true;
933  return bytes_available;
934  /* LCOV_EXCL_STOP */
935  }
936 
937  /* We mark our handle as having a pending I/O request. */
938  handle->busy = true;
939 
940  return bytes_available;
941 }
942 
946 STATIC bool
947 process_win32_handle_read_completion(process_win32_handle_t *handle,
948  DWORD error_code,
949  DWORD byte_count)
950 {
951  tor_assert(handle);
952 
953  /* Mark our handle as not having any outstanding I/O requests. */
954  handle->busy = false;
955 
956  if (error_code == 0) {
957  /* Our ReadFileEx() call was succesful and there is data for us. */
958 
959  /* This cast should be safe since byte_count should never be larger than
960  * BUFFER_SIZE. */
961  tor_assert(byte_count <= BUFFER_SIZE);
962  handle->data_available = (size_t)byte_count;
963 
964  /* Tell our caller to schedule the next read. */
965  return true;
966  } else if (error_code == ERROR_HANDLE_EOF ||
967  error_code == ERROR_BROKEN_PIPE) {
968  /* Our ReadFileEx() finished, but we reached the end of our file. We mark
969  * our handle as having reached EOF and returns. */
970  tor_assert(byte_count == 0);
971 
972  handle->reached_eof = true;
973  } else {
974  /* An error happened: We warn the user and mark our handle as having
975  * reached EOF */
976  log_warn(LD_PROCESS,
977  "Error in I/O completion routine from ReadFileEx(): %s",
978  format_win32_error(error_code));
979 
980  handle->reached_eof = true;
981  }
982 
983  /* Our caller should NOT schedule the next read. */
984  return false;
985 }
986 
989 STATIC char *
990 format_win_cmdline_argument(const char *arg)
991 {
992  char *formatted_arg;
993  char need_quotes;
994  const char *c;
995  int i;
996  int bs_counter = 0;
997  /* Backslash we can point to when one is inserted into the string */
998  const char backslash = '\\';
999 
1000  /* Smartlist of *char */
1001  smartlist_t *arg_chars;
1002  arg_chars = smartlist_new();
1003 
1004  /* Quote string if it contains whitespace or is empty */
1005  need_quotes = (strchr(arg, ' ') || strchr(arg, '\t') || '\0' == arg[0]);
1006 
1007  /* Build up smartlist of *chars */
1008  for (c=arg; *c != '\0'; c++) {
1009  if ('"' == *c) {
1010  /* Double up backslashes preceding a quote */
1011  for (i=0; i<(bs_counter*2); i++)
1012  smartlist_add(arg_chars, (void*)&backslash);
1013  bs_counter = 0;
1014  /* Escape the quote */
1015  smartlist_add(arg_chars, (void*)&backslash);
1016  smartlist_add(arg_chars, (void*)c);
1017  } else if ('\\' == *c) {
1018  /* Count backslashes until we know whether to double up */
1019  bs_counter++;
1020  } else {
1021  /* Don't double up slashes preceding a non-quote */
1022  for (i=0; i<bs_counter; i++)
1023  smartlist_add(arg_chars, (void*)&backslash);
1024  bs_counter = 0;
1025  smartlist_add(arg_chars, (void*)c);
1026  }
1027  }
1028  /* Don't double up trailing backslashes */
1029  for (i=0; i<bs_counter; i++)
1030  smartlist_add(arg_chars, (void*)&backslash);
1031 
1032  /* Allocate space for argument, quotes (if needed), and terminator */
1033  const size_t formatted_arg_len = smartlist_len(arg_chars) +
1034  (need_quotes ? 2 : 0) + 1;
1035  formatted_arg = tor_malloc_zero(formatted_arg_len);
1036 
1037  /* Add leading quote */
1038  i=0;
1039  if (need_quotes)
1040  formatted_arg[i++] = '"';
1041 
1042  /* Add characters */
1043  SMARTLIST_FOREACH(arg_chars, char*, ch,
1044  {
1045  formatted_arg[i++] = *ch;
1046  });
1047 
1048  /* Add trailing quote */
1049  if (need_quotes)
1050  formatted_arg[i++] = '"';
1051  formatted_arg[i] = '\0';
1052 
1053  smartlist_free(arg_chars);
1054  return formatted_arg;
1055 }
1056 
1061 STATIC char *
1062 tor_join_win_cmdline(const char *argv[])
1063 {
1064  smartlist_t *argv_list;
1065  char *joined_argv;
1066  int i;
1067 
1068  /* Format each argument and put the result in a smartlist */
1069  argv_list = smartlist_new();
1070  for (i=0; argv[i] != NULL; i++) {
1071  smartlist_add(argv_list, (void *)format_win_cmdline_argument(argv[i]));
1072  }
1073 
1074  /* Join the arguments with whitespace */
1075  joined_argv = smartlist_join_strings(argv_list, " ", 0, NULL);
1076 
1077  /* Free the newly allocated arguments, and the smartlist */
1078  SMARTLIST_FOREACH(argv_list, char *, arg,
1079  {
1080  tor_free(arg);
1081  });
1082  smartlist_free(argv_list);
1083 
1084  return joined_argv;
1085 }
1086 
1087 #endif /* defined(_WIN32) */
Header for smartlist.c.
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
Header for win32err.c.
const smartlist_t * process_get_all_processes(void)
Definition: process.c:166
Macro definitions for MIN, MAX, and CLAMP.
char * windows_environment_block
Definition: env.h:24
void smartlist_add(smartlist_t *sl, void *element)
#define tor_free(p)
Definition: malloc.h:52
Header for env.c.
static smartlist_t * processes
Definition: process.c:27
void process_notify_event_stderr(process_t *process)
Definition: process.c:593
void process_notify_event_stdin(process_t *process)
Definition: process.c:609
tor_assert(buffer)
int buf_get_bytes(buf_t *buf, char *string, size_t string_len)
Definition: buffers.c:634
char ** process_get_argv(const process_t *process)
Definition: process.c:439
periodic_timer_t * periodic_timer_new(struct event_base *base, const struct timeval *tv, void(*cb)(periodic_timer_t *timer, void *data), void *data)
void process_notify_event_stdout(process_t *process)
Definition: process.c:576
Header for process_win32.c.
#define LD_PROCESS
Definition: log.h:113
int buf_add(buf_t *buf, const char *string, size_t string_len)
Definition: buffers.c:525
Header file for buffers_net.c.
Header for process.c.
process_status_t
Definition: process.h:24
process_status_t process_get_status(const process_t *process)
Definition: process.c:411
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
#define SMARTLIST_FOREACH(sl, type, var, cmd)
process_environment_t * process_get_environment(const process_t *process)
Definition: process.c:501
Header file for buffers.c.
Headers for log.c.
void process_notify_event_exit(process_t *process, process_exit_code_t exit_code)
Definition: process.c:622
Macros to manage assertions, fatal and non-fatal.