Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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 {