From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> We can't use GNULIB's fprintf-posix due to licensing incompatibilities. We do already have a portable formatting via virAsprintf() which we got from GNULIB though. We can use to create a virFilePrintf() function. But really gnulib could just provide a 'fprintf' module, that depended on just its 'asprintf' module. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virfile.c | 35 +++++++++++++++++++++++++++++++++++ src/util/virfile.h | 3 +++ tests/fdstreamtest.c | 38 +++++++++++++++++++------------------- tests/virstringtest.c | 34 +++++++++++++++++----------------- 5 files changed, 75 insertions(+), 36 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 392357f..5365827 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1302,6 +1302,7 @@ virFileMatchesNameSuffix; virFileNBDDeviceAssociate; virFileOpenAs; virFileOpenTty; +virFilePrintf; virFileReadAll; virFileReadLimFD; virFileResolveAllLinks; diff --git a/src/util/virfile.c b/src/util/virfile.c index 4637919..42607c7 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -2322,3 +2322,38 @@ virFileSanitizePath(const char *path) return cleanpath; } + + +/** + * virFilePrintf: + * + * A replacement for fprintf() which uses virVasprintf to + * ensure that portable string format placeholders can be + * used, since gnulib's fprintf() replacement is not + * LGPLV2+ compatible + */ +int virFilePrintf(FILE *fp, const char *msg, ...) +{ + va_list vargs; + char *str; + int ret; + + va_start(vargs, msg); + + if ((ret = virVasprintf(&str, msg, vargs)) < 0) + goto cleanup; + + if (fwrite(str, 1, ret, fp) != ret) { + virReportSystemError(errno, "%s", + _("Could not write to stream")); + ret = -1; + } + + VIR_FREE(str); + +cleanup: + va_end(vargs); + + return ret; +} + diff --git a/src/util/virfile.h b/src/util/virfile.h index beaad86..72d35ce 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -229,4 +229,7 @@ void virFileWaitForDevices(void); virBuildPathInternal(path, __VA_ARGS__, NULL) int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL; +int virFilePrintf(FILE *fp, const char *msg, ...) + ATTRIBUTE_FMT_PRINTF(2, 3); + #endif /* __VIR_FILE_H */ diff --git a/tests/fdstreamtest.c b/tests/fdstreamtest.c index 9f780c9..edfda6a 100644 --- a/tests/fdstreamtest.c +++ b/tests/fdstreamtest.c @@ -105,16 +105,16 @@ static int testFDStreamReadCommon(const char *scratchdir, bool blocking) usleep(20 * 1000); goto reread; } - fprintf(stderr, "Failed to read stream: %s\n", - virGetLastErrorMessage()); + virFilePrintf(stderr, "Failed to read stream: %s\n", + virGetLastErrorMessage()); goto cleanup; } if (got == 0) { /* Expect EOF 1/2 through last pattern */ if (i == 9 && want == (PATTERN_LEN / 2)) break; - fprintf(stderr, "Unexpected EOF block %zu want %zu\n", - i, want); + virFilePrintf(stderr, "Unexpected EOF block %zu want %zu\n", + i, want); goto cleanup; } offset += got; @@ -122,25 +122,25 @@ static int testFDStreamReadCommon(const char *scratchdir, bool blocking) } if (i == 0) { if (memcmp(buf, pattern + (PATTERN_LEN / 2), PATTERN_LEN / 2) != 0) { - fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); + virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i); goto cleanup; } } else if (i == 9) { if (memcmp(buf, pattern, PATTERN_LEN / 2) != 0) { - fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); + virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i); goto cleanup; } } else { if (memcmp(buf, pattern, PATTERN_LEN) != 0) { - fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); + virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i); goto cleanup; } } } if (st->driver->streamFinish(st) != 0) { - fprintf(stderr, "Failed to finish stream: %s\n", - virGetLastErrorMessage()); + virFilePrintf(stderr, "Failed to finish stream: %s\n", + virGetLastErrorMessage()); goto cleanup; } @@ -229,8 +229,8 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) if (i == 9 && want == (PATTERN_LEN / 2)) break; - fprintf(stderr, "Failed to write stream: %s\n", - virGetLastErrorMessage()); + virFilePrintf(stderr, "Failed to write stream: %s\n", + virGetLastErrorMessage()); goto cleanup; } offset += got; @@ -239,8 +239,8 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) } if (st->driver->streamFinish(st) != 0) { - fprintf(stderr, "Failed to finish stream: %s\n", - virGetLastErrorMessage()); + virFilePrintf(stderr, "Failed to finish stream: %s\n", + virGetLastErrorMessage()); goto cleanup; } @@ -255,7 +255,7 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) want = PATTERN_LEN; if (saferead(fd, buf, want) != want) { - fprintf(stderr, "Short read from data\n"); + virFilePrintf(stderr, "Short read from data\n"); goto cleanup; } @@ -263,22 +263,22 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) size_t j; for (j = 0 ; j < (PATTERN_LEN / 2) ; j++) { if (buf[j] != 0) { - fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); + virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i); goto cleanup; } } if (memcmp(buf + (PATTERN_LEN / 2), pattern, PATTERN_LEN / 2) != 0) { - fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); + virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i); goto cleanup; } } else if (i == 9) { if (memcmp(buf, pattern, PATTERN_LEN / 2) != 0) { - fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); + virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i); goto cleanup; } } else { if (memcmp(buf, pattern, PATTERN_LEN) != 0) { - fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); + virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i); goto cleanup; } } @@ -324,7 +324,7 @@ mymain(void) virFDStreamSetIOHelper(iohelper); if (!mkdtemp(scratchdir)) { - fprintf(stderr, "Cannot create fakesysfsdir"); + virFilePrintf(stderr, "Cannot create fakesysfsdir"); abort(); } diff --git a/tests/virstringtest.c b/tests/virstringtest.c index da06c0f..98f0a56 100644 --- a/tests/virstringtest.c +++ b/tests/virstringtest.c @@ -25,8 +25,8 @@ #include "testutils.h" #include "virerror.h" #include "viralloc.h" +#include "virfile.h" #include "virlog.h" - #include "virstring.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -62,18 +62,18 @@ static int testSplit(const void *args) tmp2 = data->tokens; while (*tmp1 && *tmp2) { if (STRNEQ(*tmp1, *tmp2)) { - fprintf(stderr, "Mismatch '%s' vs '%s'\n", *tmp1, *tmp2); + virFilePrintf(stderr, "Mismatch '%s' vs '%s'\n", *tmp1, *tmp2); goto cleanup; } tmp1++; tmp2++; } if (*tmp1) { - fprintf(stderr, "Too many pieces returned\n"); + virFilePrintf(stderr, "Too many pieces returned\n"); goto cleanup; } if (*tmp2) { - fprintf(stderr, "Too few pieces returned\n"); + virFilePrintf(stderr, "Too few pieces returned\n"); goto cleanup; } @@ -96,7 +96,7 @@ static int testJoin(const void *args) return -1; } if (STRNEQ(got, data->string)) { - fprintf(stderr, "Mismatch '%s' vs '%s'\n", got, data->string); + virFilePrintf(stderr, "Mismatch '%s' vs '%s'\n", got, data->string); goto cleanup; } @@ -143,49 +143,49 @@ testStrdup(const void *data ATTRIBUTE_UNUSED) value = VIR_STRDUP(array[i++], testStrdupLookup1(j++)); if (value != 1) { - fprintf(stderr, "unexpected strdup result %d, expected 1\n", value); + virFilePrintf(stderr, "unexpected strdup result %d, expected 1\n", value); goto cleanup; } if (i != 1) { - fprintf(stderr, "unexpected side effects i=%zu, expected 1\n", i); + virFilePrintf(stderr, "unexpected side effects i=%zu, expected 1\n", i); goto cleanup; } if (j != 1) { - fprintf(stderr, "unexpected side effects j=%zu, expected 1\n", j); + virFilePrintf(stderr, "unexpected side effects j=%zu, expected 1\n", j); goto cleanup; } if (STRNEQ_NULLABLE(array[0], "hello") || array[1]) { - fprintf(stderr, "incorrect array contents '%s' '%s'\n", - NULLSTR(array[0]), NULLSTR(array[1])); + virFilePrintf(stderr, "incorrect array contents '%s' '%s'\n", + NULLSTR(array[0]), NULLSTR(array[1])); goto cleanup; } value = VIR_STRNDUP(array[i++], testStrdupLookup1(j++), testStrdupLookup2(k++)); if (value != 0) { - fprintf(stderr, "unexpected strdup result %d, expected 0\n", value); + virFilePrintf(stderr, "unexpected strdup result %d, expected 0\n", value); goto cleanup; } if (i != 2) { - fprintf(stderr, "unexpected side effects i=%zu, expected 2\n", i); + virFilePrintf(stderr, "unexpected side effects i=%zu, expected 2\n", i); goto cleanup; } if (j != 2) { - fprintf(stderr, "unexpected side effects j=%zu, expected 2\n", j); + virFilePrintf(stderr, "unexpected side effects j=%zu, expected 2\n", j); goto cleanup; } if (k != 1) { - fprintf(stderr, "unexpected side effects k=%zu, expected 1\n", k); + virFilePrintf(stderr, "unexpected side effects k=%zu, expected 1\n", k); goto cleanup; } if (STRNEQ_NULLABLE(array[0], "hello") || array[1]) { - fprintf(stderr, "incorrect array contents '%s' '%s'\n", - NULLSTR(array[0]), NULLSTR(array[1])); + virFilePrintf(stderr, "incorrect array contents '%s' '%s'\n", + NULLSTR(array[0]), NULLSTR(array[1])); goto cleanup; } if (fail) { - fprintf(stderr, "side effects failed\n"); + virFilePrintf(stderr, "side effects failed\n"); goto cleanup; } -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list