char * system_quote (enum system_command_interpreter interpreter, const char *string) { switch (interpreter) { #if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) case SCI_SYSTEM: #endif case SCI_POSIX_SH: return shell_quote (string); #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ case SCI_WINDOWS_CREATEPROCESS: case SCI_SYSTEM: case SCI_WINDOWS_CMD: { size_t length = system_quote_length (interpreter, string); char *quoted = XNMALLOC (length, char); system_quote_copy (quoted, interpreter, string); return quoted; } #endif default: /* Invalid interpreter. */ abort (); } }
char * system_quote_argv (enum system_command_interpreter interpreter, char * const *argv) { if (*argv != NULL) { char * const *argp; size_t length; char *command; char *p; length = 0; for (argp = argv; ; ) { length += system_quote_length (interpreter, *argp) + 1; argp++; if (*argp == NULL) break; } command = XNMALLOC (length, char); p = command; for (argp = argv; ; ) { p = system_quote_copy (p, interpreter, *argp); argp++; if (*argp == NULL) break; *p++ = ' '; } *p = '\0'; return command; }
static void check_one (enum system_command_interpreter interpreter, const char *prog, const char *input) { char buf[1000]; size_t output_len; char *output; char *bufend; output_len = system_quote_length (interpreter, input); output = system_quote (interpreter, input); ASSERT (strlen (output) == output_len); ASSERT (output_len <= sizeof (buf) - 2); memset (buf, '\0', output_len + 1); buf[output_len + 1] = '%'; bufend = system_quote_copy (buf, interpreter, input); ASSERT (bufend == buf + output_len); ASSERT (memcmp (buf, output, output_len + 1) == 0); ASSERT (buf[output_len + 1] == '%'); /* Store INPUT in EXPECTED_DATA_FILE, for verification by the child process. */ { FILE *fp = fopen (EXPECTED_DATA_FILE, "wb"); if (fp == NULL) exit (3); if (fwrite (input, 1, strlen (input), fp) != strlen (input)) exit (4); if (fclose (fp)) exit (5); } /* Invoke the child process through system() and popen(). */ { char command[1000]; sprintf (command, "%s %s", prog, output); switch (interpreter) { case SCI_SYSTEM: #ifdef WINDOWS_NATIVE case SCI_WINDOWS_CMD: #endif { int exitcode = system (command); if (exitcode != 0) { fprintf (stderr, "for input = |%s|: system() command failed with status %d: %s\n", input, exitcode, command); failed = 1; } } { FILE *fp = popen (command, "r"); int exitcode = pclose (fp); if (exitcode != 0) { fprintf (stderr, "for input = |%s|: popen() command failed with status %d: %s\n", input, exitcode, command); failed = 1; } } break; #ifdef WINDOWS_NATIVE case SCI_WINDOWS_CREATEPROCESS: { PROCESS_INFORMATION pinfo; STARTUPINFO sinfo; sinfo.cb = sizeof (STARTUPINFO); sinfo.lpReserved = NULL; sinfo.lpDesktop = NULL; sinfo.lpTitle = NULL; sinfo.cbReserved2 = 0; sinfo.lpReserved2 = NULL; sinfo.dwFlags = STARTF_USESTDHANDLES; sinfo.hStdInput = GetStdHandle (STD_INPUT_HANDLE); sinfo.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE); sinfo.hStdError = GetStdHandle (STD_ERROR_HANDLE); if (CreateProcess (NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo)) { DWORD exitcode; CloseHandle (pinfo.hThread); if (WaitForSingleObject (pinfo.hProcess, INFINITE) == WAIT_OBJECT_0) { if (GetExitCodeProcess (pinfo.hProcess, &exitcode)) { if (exitcode != 0) { fprintf (stderr, "for input = |%s|: CreateProcess() command failed with status %d: %s\n", input, exitcode, command); failed = 1; } } else { fprintf (stderr, "for input = |%s|: GetExitCodeProcess failed, GetLastError() = %u\n", input, GetLastError ()); failed = 1; } } else { fprintf (stderr, "for input = |%s|: WaitForSingleObject failed\n", input); failed = 1; } CloseHandle (pinfo.hProcess); } else { fprintf (stderr, "for input = |%s|: CreateProcess failed, GetLastError() = %u\n", input, GetLastError ()); failed = 1; } } break; #endif default: break; } } free (output); }