提交 a2619962 编写于 作者: D Daniel P. Berrange 提交者: Eric Blake

Introduce virFilePrintf() as a portable fprintf()

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: NDaniel P. Berrange <berrange@redhat.com>
上级 fae2505e
...@@ -1305,6 +1305,7 @@ virFileMatchesNameSuffix; ...@@ -1305,6 +1305,7 @@ virFileMatchesNameSuffix;
virFileNBDDeviceAssociate; virFileNBDDeviceAssociate;
virFileOpenAs; virFileOpenAs;
virFileOpenTty; virFileOpenTty;
virFilePrintf;
virFileReadAll; virFileReadAll;
virFileReadLimFD; virFileReadLimFD;
virFileResolveAllLinks; virFileResolveAllLinks;
......
...@@ -2318,3 +2318,37 @@ virFileSanitizePath(const char *path) ...@@ -2318,3 +2318,37 @@ virFileSanitizePath(const char *path)
return cleanpath; 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;
}
...@@ -229,4 +229,7 @@ void virFileWaitForDevices(void); ...@@ -229,4 +229,7 @@ void virFileWaitForDevices(void);
virBuildPathInternal(path, __VA_ARGS__, NULL) virBuildPathInternal(path, __VA_ARGS__, NULL)
int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL; int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL;
int virFilePrintf(FILE *fp, const char *msg, ...)
ATTRIBUTE_FMT_PRINTF(2, 3);
#endif /* __VIR_FILE_H */ #endif /* __VIR_FILE_H */
...@@ -105,16 +105,16 @@ static int testFDStreamReadCommon(const char *scratchdir, bool blocking) ...@@ -105,16 +105,16 @@ static int testFDStreamReadCommon(const char *scratchdir, bool blocking)
usleep(20 * 1000); usleep(20 * 1000);
goto reread; goto reread;
} }
fprintf(stderr, "Failed to read stream: %s\n", virFilePrintf(stderr, "Failed to read stream: %s\n",
virGetLastErrorMessage()); virGetLastErrorMessage());
goto cleanup; goto cleanup;
} }
if (got == 0) { if (got == 0) {
/* Expect EOF 1/2 through last pattern */ /* Expect EOF 1/2 through last pattern */
if (i == 9 && want == (PATTERN_LEN / 2)) if (i == 9 && want == (PATTERN_LEN / 2))
break; break;
fprintf(stderr, "Unexpected EOF block %zu want %zu\n", virFilePrintf(stderr, "Unexpected EOF block %zu want %zu\n",
i, want); i, want);
goto cleanup; goto cleanup;
} }
offset += got; offset += got;
...@@ -122,25 +122,25 @@ static int testFDStreamReadCommon(const char *scratchdir, bool blocking) ...@@ -122,25 +122,25 @@ static int testFDStreamReadCommon(const char *scratchdir, bool blocking)
} }
if (i == 0) { if (i == 0) {
if (memcmp(buf, pattern + (PATTERN_LEN / 2), PATTERN_LEN / 2) != 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; goto cleanup;
} }
} else if (i == 9) { } else if (i == 9) {
if (memcmp(buf, pattern, PATTERN_LEN / 2) != 0) { 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; goto cleanup;
} }
} else { } else {
if (memcmp(buf, pattern, PATTERN_LEN) != 0) { 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; goto cleanup;
} }
} }
} }
if (st->driver->streamFinish(st) != 0) { if (st->driver->streamFinish(st) != 0) {
fprintf(stderr, "Failed to finish stream: %s\n", virFilePrintf(stderr, "Failed to finish stream: %s\n",
virGetLastErrorMessage()); virGetLastErrorMessage());
goto cleanup; goto cleanup;
} }
...@@ -229,8 +229,8 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) ...@@ -229,8 +229,8 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking)
if (i == 9 && if (i == 9 &&
want == (PATTERN_LEN / 2)) want == (PATTERN_LEN / 2))
break; break;
fprintf(stderr, "Failed to write stream: %s\n", virFilePrintf(stderr, "Failed to write stream: %s\n",
virGetLastErrorMessage()); virGetLastErrorMessage());
goto cleanup; goto cleanup;
} }
offset += got; offset += got;
...@@ -239,8 +239,8 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) ...@@ -239,8 +239,8 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking)
} }
if (st->driver->streamFinish(st) != 0) { if (st->driver->streamFinish(st) != 0) {
fprintf(stderr, "Failed to finish stream: %s\n", virFilePrintf(stderr, "Failed to finish stream: %s\n",
virGetLastErrorMessage()); virGetLastErrorMessage());
goto cleanup; goto cleanup;
} }
...@@ -255,7 +255,7 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) ...@@ -255,7 +255,7 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking)
want = PATTERN_LEN; want = PATTERN_LEN;
if (saferead(fd, buf, want) != want) { if (saferead(fd, buf, want) != want) {
fprintf(stderr, "Short read from data\n"); virFilePrintf(stderr, "Short read from data\n");
goto cleanup; goto cleanup;
} }
...@@ -263,22 +263,22 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking) ...@@ -263,22 +263,22 @@ static int testFDStreamWriteCommon(const char *scratchdir, bool blocking)
size_t j; size_t j;
for (j = 0; j < (PATTERN_LEN / 2); j++) { for (j = 0; j < (PATTERN_LEN / 2); j++) {
if (buf[j] != 0) { if (buf[j] != 0) {
fprintf(stderr, "Mismatched pattern data iteration %zu\n", i); virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i);
goto cleanup; goto cleanup;
} }
} }
if (memcmp(buf + (PATTERN_LEN / 2), pattern, PATTERN_LEN / 2) != 0) { 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; goto cleanup;
} }
} else if (i == 9) { } else if (i == 9) {
if (memcmp(buf, pattern, PATTERN_LEN / 2) != 0) { 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; goto cleanup;
} }
} else { } else {
if (memcmp(buf, pattern, PATTERN_LEN) != 0) { 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; goto cleanup;
} }
} }
...@@ -324,7 +324,7 @@ mymain(void) ...@@ -324,7 +324,7 @@ mymain(void)
virFDStreamSetIOHelper(iohelper); virFDStreamSetIOHelper(iohelper);
if (!mkdtemp(scratchdir)) { if (!mkdtemp(scratchdir)) {
fprintf(stderr, "Cannot create fakesysfsdir"); virFilePrintf(stderr, "Cannot create fakesysfsdir");
abort(); abort();
} }
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include "testutils.h" #include "testutils.h"
#include "virerror.h" #include "virerror.h"
#include "viralloc.h" #include "viralloc.h"
#include "virfile.h"
#include "virlog.h" #include "virlog.h"
#include "virstring.h" #include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
...@@ -62,18 +62,18 @@ static int testSplit(const void *args) ...@@ -62,18 +62,18 @@ static int testSplit(const void *args)
tmp2 = data->tokens; tmp2 = data->tokens;
while (*tmp1 && *tmp2) { while (*tmp1 && *tmp2) {
if (STRNEQ(*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; goto cleanup;
} }
tmp1++; tmp1++;
tmp2++; tmp2++;
} }
if (*tmp1) { if (*tmp1) {
fprintf(stderr, "Too many pieces returned\n"); virFilePrintf(stderr, "Too many pieces returned\n");
goto cleanup; goto cleanup;
} }
if (*tmp2) { if (*tmp2) {
fprintf(stderr, "Too few pieces returned\n"); virFilePrintf(stderr, "Too few pieces returned\n");
goto cleanup; goto cleanup;
} }
...@@ -96,7 +96,7 @@ static int testJoin(const void *args) ...@@ -96,7 +96,7 @@ static int testJoin(const void *args)
return -1; return -1;
} }
if (STRNEQ(got, data->string)) { 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; goto cleanup;
} }
...@@ -143,49 +143,49 @@ testStrdup(const void *data ATTRIBUTE_UNUSED) ...@@ -143,49 +143,49 @@ testStrdup(const void *data ATTRIBUTE_UNUSED)
value = VIR_STRDUP(array[i++], testStrdupLookup1(j++)); value = VIR_STRDUP(array[i++], testStrdupLookup1(j++));
if (value != 1) { 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; goto cleanup;
} }
if (i != 1) { 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; goto cleanup;
} }
if (j != 1) { 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; goto cleanup;
} }
if (STRNEQ_NULLABLE(array[0], "hello") || array[1]) { if (STRNEQ_NULLABLE(array[0], "hello") || array[1]) {
fprintf(stderr, "incorrect array contents '%s' '%s'\n", virFilePrintf(stderr, "incorrect array contents '%s' '%s'\n",
NULLSTR(array[0]), NULLSTR(array[1])); NULLSTR(array[0]), NULLSTR(array[1]));
goto cleanup; goto cleanup;
} }
value = VIR_STRNDUP(array[i++], testStrdupLookup1(j++), value = VIR_STRNDUP(array[i++], testStrdupLookup1(j++),
testStrdupLookup2(k++)); testStrdupLookup2(k++));
if (value != 0) { 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; goto cleanup;
} }
if (i != 2) { 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; goto cleanup;
} }
if (j != 2) { 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; goto cleanup;
} }
if (k != 1) { 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; goto cleanup;
} }
if (STRNEQ_NULLABLE(array[0], "hello") || array[1]) { if (STRNEQ_NULLABLE(array[0], "hello") || array[1]) {
fprintf(stderr, "incorrect array contents '%s' '%s'\n", virFilePrintf(stderr, "incorrect array contents '%s' '%s'\n",
NULLSTR(array[0]), NULLSTR(array[1])); NULLSTR(array[0]), NULLSTR(array[1]));
goto cleanup; goto cleanup;
} }
if (fail) { if (fail) {
fprintf(stderr, "side effects failed\n"); virFilePrintf(stderr, "side effects failed\n");
goto cleanup; goto cleanup;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册