static int _rw_vsystem (const char *cmd, va_list va) { RW_ASSERT (0 != cmd); char *buf = 0; rw_vasnprintf (&buf, 0, cmd, va); rw_note (0, "file:" __FILE__, __LINE__, "executing \"%s\"", buf); // avoid using const in order to prevent gcc warning on Linux // issued for WIFSIGNALED() et al: cast from `const int*' to // `int*' discards qualifiers from pointer target type: // see http://sourceware.org/bugzilla/show_bug.cgi?id=1392 /* const */ int ret = system (buf); if (ret) { #ifndef _WIN32 if (-1 == ret) { // system() failed, e.g., because fork() failed rw_error (0, __FILE__, __LINE__, "system (\"%s\") failed: errno = %{#m} (%{m})", buf); } else if (WIFSIGNALED (ret)) { // command exited with a signal const int signo = WTERMSIG (ret); rw_error (0, __FILE__, __LINE__, "the command \"%s\" exited with signal %d (%{K})", buf, signo, signo); } else { // command exited with a non-zero status const int status = WEXITSTATUS (ret); rw_error (0, __FILE__, __LINE__, "the command \"%s\" exited with status %d", buf, status); } #else // if defined (_WIN32) // FIXME: make this more descriptive rw_error (0, __FILE__, __LINE__, "the command \"%s\" failed with code %d", buf, ret); #endif // _WIN32 } free (buf); return ret; }
static rw_pid_t _rw_vprocess_create (const char* cmd, va_list va) { RW_ASSERT (0 != cmd); char *buf = 0; rw_vasnprintf (&buf, 0, cmd, va); rw_pid_t ret = -1; #ifdef _WIN32 STARTUPINFO si = { sizeof (si) }; PROCESS_INFORMATION pi; if (CreateProcess (0, buf, 0, 0, FALSE, CREATE_NEW_PROCESS_GROUP, 0, 0, &si, &pi)) { CloseHandle (pi.hThread); ret = rw_pid_t (pi.hProcess); } else { const DWORD err = GetLastError (); rw_error (0, __FILE__, __LINE__, "CreateProcess () failed: GetLastError() = %zu", size_t (err)); errno = _rw_map_errno (err); } #else // #if !defined (_WIN32) const size_t MAX_PARAMS = 63; char* argv [MAX_PARAMS + 1] = { 0 }; size_t argc = _rw_split_cmd (buf, argv, MAX_PARAMS); if (0 < argc && MAX_PARAMS >= argc) ret = rw_process_create (argv [0], argv); else errno = E2BIG; #endif // _WIN32 free (buf); return ret; }
static void _rw_vissue_diag (diag_t diag, int severity, const char *file, int line, const char *fmt, va_list va) { CHECK_INIT (true, "_rw_vissue_diag()"); if (0 == fmt) fmt = ""; static char fmterr[] = "*** formatting error ***"; char *usrbuf = 0; const int nchars = rw_vasnprintf (&usrbuf, 0, fmt, va); if (nchars < 0 || 0 == usrbuf) usrbuf = fmterr; // compute the number of newline characters in the text int nlines = 0; #ifdef __ARMCC__ #pragma diag_suppress 1293 #endif for (const char *nl = usrbuf; (nl = strchr (nl, '\n')); ++nl) ++nlines; static const int use_color = _rw_use_color (); const char* const diagstr[] = { use_color ? diag_msgs [severity].esc_pfx : "", *diag_msgs [severity].code ? diag_msgs [severity].code : "UNKNOWN", use_color ? diag_msgs [severity].esc_sfx : "", _rw_opt_verbose (0, 0) && *diag_msgs [severity].desc ? diag_msgs [severity].desc : 0 }; const char* const traced_diag = 0 == severity && diag_msgs [diag].code ? diag_msgs [diag].code : 0; const char* const slash = file ? strrchr (file, _RWSTD_PATH_SEP) : 0; if (slash) file = slash + 1; char *mybuf = 0; if (_rw_opt_csv) { // format all fields as comma separated values (CSV): // -- a field containing the quote character, the comma, // or the newline or linefeed character must be enclosed // in a pair of double quotes // -- every occurrence of the double quote character in a field // must be escaped by prepening another double quote character // to it // escape all double quotes by prepending the double // quote character to each according to the CSV format char* const newbuf = _rw_escape (usrbuf, 0, '"'); if (newbuf != usrbuf) { free (usrbuf); usrbuf = newbuf; } mybuf = rw_sprintfa ("%d, " // severity "\"%s%s" // diagnostic "%{?}_%s%{;}%s\", " // traced diagnostic "\"%s\", " // clause "\"%s\", " // file "%d, " // line "\"%s\"", // user text severity, diagstr [0], diagstr [1], 0 != traced_diag, traced_diag, diagstr [2], clause_id, 0 != file ? file : "", line, usrbuf); } else { nlines += 2 + ('\0' != *clause_id) + (0 != file) + (0 < line); mybuf = rw_sprintfa ("# %s" // escape prefix "%s" // diagnostic "%{?}_%s%{;}" // traced diagnostic "%s " // escape suffix "(S%d)" // severity "%{?}, %s%{;} " // description "(%d lines):\n" // number of lines "# TEXT: %s\n" // user text "%{?}# CLAUSE: %s\n%{;}" // clause if not empty "%{?}# FILE: %s\n%{;}" // file if not null "%{?}# LINE: %d\n%{;}", // line if positive diagstr [0], diagstr [1], 0 != traced_diag, traced_diag, diagstr [2], severity, 0 != diagstr [3], diagstr [3], nlines, usrbuf, '\0' != *clause_id, clause_id, 0 != file, file, 0 < line, line); } #if 0 // disabled else {