* non-zero on error == berrno status
*
*/
-int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[])
+int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[], bool cmd_string_opt)
{
BPIPE *bpipe;
int stat1=0, stat2=0, stat3=0;
mode = (char *)"re";
}
+#ifdef HAVE_WIN32
+ bpipe = open_bpipe(prog, wait, mode, env, cmd_string_opt);
+#else
+ (void) cmd_string_opt;
bpipe = open_bpipe(prog, wait, mode, env);
+#endif
if (!bpipe) {
stat1 = ENOENT;
goto bail_out;
int run_program_full_output(char *prog, int wait, POOLMEM *&results, char *env[])
{
char *errors = NULL;
- return run_program_full_output_and_error(prog, wait, results, errors, env);
+ return run_program_full_output_and_error(prog, wait, results, errors, env, false);
}
/*
int bget_msg(BSOCK *sock);
/* bpipe.c */
+#ifdef HAVE_WIN32
+/* cmd_string_opt adds /s option to cmd invocation (win32 only)*/
+BPIPE * open_bpipe(char *prog, int wait, const char *mode, char *envp[]=NULL, bool cmd_string_opt = false);
+#else
BPIPE * open_bpipe(char *prog, int wait, const char *mode, char *envp[]=NULL);
+#endif
int close_wpipe(BPIPE *bpipe);
int close_epipe(BPIPE *bpipe);
int close_bpipe(BPIPE *bpipe);
void jobstatus_to_ascii_gui (int JobStatus, char *msg, int maxlen);
int run_program (char *prog, int wait, POOLMEM *&results);
int run_program_full_output (char *prog, int wait, POOLMEM *&results, char *env[]=NULL);
-int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[]=NULL);
+int run_program_full_output_and_error(char *prog, int wait, POOLMEM *&results, POOLMEM *&errors, char *env[]=NULL, bool cmd_string_opt=false);
char * action_on_purge_to_string(int aop, POOL_MEM &ret);
const char * job_type_to_str (int type);
const char * job_status_to_str (int stat, int errors);
*/
HANDLE
CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err,
- char * envp[] = NULL)
+ char * envp[] = NULL, bool cmd_string_opt = false)
{
static const char *comspec = NULL;
PROCESS_INFORMATION piProcInfo;
}
POOL_MEM cmdLine(PM_FNAME);
- Mmsg(cmdLine, "%s /c \"%s\"%s", comspec, exeFile, argStart);
+ if (cmd_string_opt) {
+ /* For working around multiple double quotes in the exe and arguments, we use the /s cmd option */
+ /* /s skips the parsing rules of /c and only strips the first and last quote so:
+ /* cmd.exe /s /c ""C:\program files\myexe.exe" -file "C:\program files\args.txt"" will respect both */
+ /* "C:\program files\myexe.exe" and "C:\program files\args.txt" quotes */
+ Mmsg(cmdLine, "%s /s /c \"\"%s\"%s\"", comspec, exeFile, argStart);
+ } else {
+ /* regular cmd call: cmd.exe /c "C:\program files\myexe.exe" -args C:\PROGR~1\args.txt */
+ /* arguments should not contain double quotes */
+ Mmsg(cmdLine, "%s /c \"%s\"%s", comspec, exeFile, argStart);
+ }
+
free(exeFile);
#define MODE_NOSTDERR 16
BPIPE *
-open_bpipe(char *prog, int wait, const char *mode, char *envp[])
+open_bpipe(char *prog, int wait, const char *mode, char *envp[], bool cmd_string_opt)
{
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hChildStdoutWr, // stdout HANDLE
(mode_map & MODE_STDERR || mode_map & MODE_NOSTDERR)
? hChildStderrWr:hChildStdoutWr, // stderr HANDLE
- envp); // envp environment variables are added to the current process env var set.
+ envp,
+ cmd_string_opt); // envp environment variables are added to the current process env var set.
if ((HANDLE) bpipe->worker_pid == INVALID_HANDLE_VALUE) {
ErrorExit("CreateChildProcess failed");