/* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** * \file subprocess.c * \brief Launch and monitor other processes. **/ #define SUBPROCESS_PRIVATE #include "lib/process/subprocess.h" #include "lib/container/smartlist.h" #include "lib/err/torerr.h" #include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/log/win32err.h" #include "lib/malloc/malloc.h" #include "lib/process/env.h" #include "lib/process/waitpid.h" #include "lib/string/compat_ctype.h" #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_PRCTL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SIGNAL_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_SYS_WAIT_H #include #endif #include #include /** Format a single argument for being put on a Windows command line. * Returns a newly allocated string */ static char * format_win_cmdline_argument(const char *arg) { char *formatted_arg; char need_quotes; const char *c; int i; int bs_counter = 0; /* Backslash we can point to when one is inserted into the string */ const char backslash = '\\'; /* Smartlist of *char */ smartlist_t *arg_chars; arg_chars = smartlist_new(); /* Quote string if it contains whitespace or is empty */ need_quotes = (strchr(arg, ' ') || strchr(arg, '\t') || '\0' == arg[0]); /* Build up smartlist of *chars */ for (c=arg; *c != '\0'; c++) { if ('"' == *c) { /* Double up backslashes preceding a quote */ for (i=0; i<(bs_counter*2); i++) smartlist_add(arg_chars, (void*)&backslash); bs_counter = 0; /* Escape the quote */ smartlist_add(arg_chars, (void*)&backslash); smartlist_add(arg_chars, (void*)c); } else if ('\\' == *c) { /* Count backslashes until we know whether to double up */ bs_counter++; } else { /* Don't double up slashes preceding a non-quote */ for (i=0; i