From: "Daniel P. Berrange" <berrange(a)redhat.com>
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(a)redhat.com>
---
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