/* * Add a command line argument created by a printf-style format */ void virCommandAddArgFormat(virCommandPtr cmd, const char *format, ...) { char *arg; va_list list; if (!cmd || cmd->has_error) return; va_start(list, format); if (virVasprintf(&arg, format, list) < 0) { cmd->has_error = ENOMEM; va_end(list); return; } va_end(list); /* Arg plus trailing NULL. */ if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) { VIR_FREE(arg); cmd->has_error = ENOMEM; return; } cmd->args[cmd->nargs++] = arg; }
/** * sexpr_fmt_node: * @sexpr: a pointer to a parsed S-Expression * @fmt: a path for the node to lookup in the S-Expression * @... extra data to build the path * * Search a node value in the S-Expression based on its path * * Returns the value of the node or NULL if not found. */ const char * sexpr_fmt_node(const struct sexpr *sexpr, const char *fmt, ...) { int result; va_list ap; char *node; const char *value; va_start(ap, fmt); result = virVasprintf(&node, fmt, ap); va_end(ap); if (result < 0) { return NULL; } value = sexpr_node(sexpr, node); VIR_FREE(node); return value; }
void virtTestResult(const char *name, int ret, const char *msg, ...) { va_list vargs; va_start(vargs, msg); if (testCounter == 0 && !virTestGetVerbose()) fprintf(stderr, " "); testCounter++; if (virTestGetVerbose()) { fprintf(stderr, "%3d) %-60s ", testCounter, name); if (ret == 0) fprintf(stderr, "OK\n"); else { fprintf(stderr, "FAILED\n"); if (msg) { char *str; if (virVasprintf(&str, msg, vargs) == 0) { fprintf(stderr, "%s", str); VIR_FREE(str); } } } } else { if (testCounter != 1 && !((testCounter-1) % 40)) { fprintf(stderr, " %-3d\n", (testCounter-1)); fprintf(stderr, " "); } if (ret == 0) fprintf(stderr, "."); else fprintf(stderr, "!"); } va_end(vargs); }
/** * virLogMessage: * @category: where is that message coming from * @priority: the priority level * @funcname: the function emitting the (debug) message * @linenr: line where the message was emitted * @flags: extra flags, 1 if coming from the error handler * @fmt: the string format * @...: the arguments * * Call the libvirt logger with some information. Based on the configuration * the message may be stored, sent to output or just discarded */ void virLogMessage(const char *category, int priority, const char *funcname, long long linenr, unsigned int flags, const char *fmt, ...) { static bool logVersionStderr = true; char *str = NULL; char *msg = NULL; char timestamp[VIR_TIME_STRING_BUFLEN]; int fprio, i, ret; int saved_errno = errno; int emit = 1; va_list ap; if (!virLogInitialized) virLogStartup(); if (fmt == NULL) goto cleanup; /* * check against list of specific logging patterns */ fprio = virLogFiltersCheck(category); if (fprio == 0) { if (priority < virLogDefaultPriority) emit = 0; } else if (priority < fprio) { emit = 0; } if ((emit == 0) && ((virLogBuffer == NULL) || (virLogSize <= 0))) goto cleanup; /* * serialize the error message, add level and timestamp */ va_start(ap, fmt); if (virVasprintf(&str, fmt, ap) < 0) { va_end(ap); goto cleanup; } va_end(ap); ret = virLogFormatString(&msg, funcname, linenr, priority, str); VIR_FREE(str); if (ret < 0) goto cleanup; if (virTimeStringNowRaw(timestamp) < 0) timestamp[0] = '\0'; /* * Log based on defaults, first store in the history buffer, * then if emit push the message on the outputs defined, if none * use stderr. * NOTE: the locking is a single point of contention for multiple * threads, but avoid intermixing. Maybe set up locks per output * to improve paralellism. */ virLogLock(); virLogStr(timestamp); virLogStr(msg); virLogUnlock(); if (emit == 0) goto cleanup; virLogLock(); for (i = 0; i < virLogNbOutputs; i++) { if (priority >= virLogOutputs[i].priority) { if (virLogOutputs[i].logVersion) { char *ver = NULL; if (virLogVersionString(&ver) >= 0) virLogOutputs[i].f(category, VIR_LOG_INFO, __func__, __LINE__, timestamp, ver, virLogOutputs[i].data); VIR_FREE(ver); virLogOutputs[i].logVersion = false; } virLogOutputs[i].f(category, priority, funcname, linenr, timestamp, msg, virLogOutputs[i].data); } } if ((virLogNbOutputs == 0) && (flags != 1)) { if (logVersionStderr) { char *ver = NULL; if (virLogVersionString(&ver) >= 0) virLogOutputToFd(category, VIR_LOG_INFO, __func__, __LINE__, timestamp, ver, (void *) STDERR_FILENO); VIR_FREE(ver); logVersionStderr = false; } virLogOutputToFd(category, priority, funcname, linenr, timestamp, msg, (void *) STDERR_FILENO); } virLogUnlock(); cleanup: VIR_FREE(msg); errno = saved_errno; }