From: Daniel P. Berrange Date: Mon, 28 Apr 2008 15:14:59 +0000 (+0000) Subject: Change virBuffer API to prevent common usage errors. Update all users of APIs X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=642b26fab2644c811a92269ff41586b027f1a5e9;p=libvirt.git Change virBuffer API to prevent common usage errors. Update all users of APIs --- diff --git a/ChangeLog b/ChangeLog index 56af7fa01a..9b1ba0eccb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Mon Apr 28 10:24:22 EST 2008 Daniel P. Berrange + + * src/buf.c, src/buf.h: Change API to move errors checks to + a single place + * src/capabilities.c, src/conf.c, src/lxc_conf.c, src/qemu_conf.c, + src/qparams.c, src/storage_conf.c, src/test.c, src/virsh.c, + src/xend_internal.c, src/xm_internal.c, src/xml.c, src/xmlrpc.c, + src/xmlrpc.h, tests/xmlrpctest.c: Update to conform with new + virBuffer API + * src/libvirt_sym.version: Add new virBuffer APIs for virsh + Mon Apr 28 16:11:22 CEST 2008 Jim Meyering fix typo in bootstrap script diff --git a/src/buf.c b/src/buf.c index a542fda437..2e17fbbf91 100644 --- a/src/buf.c +++ b/src/buf.c @@ -18,8 +18,37 @@ #include #include +#define __VIR_BUFFER_C__ + #include "buf.h" + +/* If adding more fields, ensure to edit buf.h to match + the number of fields */ +struct _virBuffer { + unsigned int size; + unsigned int use; + unsigned int error; + char *content; +}; + +/** + * virBufferFail + * @buf: the buffer + * + * Mark the buffer has having failed a memory allocation, + * freeing the content and setting the error flag. + */ +static void +virBufferNoMemory(const virBufferPtr buf) +{ + free(buf->content); + buf->content = NULL; + buf->size = 0; + buf->use = 0; + buf->error = 1; +} + /** * virBufferGrow: * @buf: the buffer @@ -27,7 +56,7 @@ * * Grow the available space of a buffer to at least @len bytes. * - * Returns the new available space or -1 in case of error + * Returns zero on success or -1 on error */ static int virBufferGrow(virBufferPtr buf, unsigned int len) @@ -35,18 +64,22 @@ virBufferGrow(virBufferPtr buf, unsigned int len) int size; char *newbuf; - if (buf == NULL) - return (-1); - if (len + buf->use < buf->size) - return (0); + if (buf->error) + return -1; + + if ((len + buf->use) < buf->size) + return 0; size = buf->use + len + 1000; newbuf = realloc(buf->content, size); - if (newbuf == NULL) return -1; + if (newbuf == NULL) { + virBufferNoMemory(buf); + return -1; + } buf->content = newbuf; buf->size = size; - return (buf->size - buf->use); + return 0; } /** @@ -58,33 +91,29 @@ virBufferGrow(virBufferPtr buf, unsigned int len) * Add a string range to an XML buffer. if len == -1, the length of * str is recomputed to the full string. * - * Returns 0 successful, -1 in case of internal or API error. */ -int -__virBufferAdd(virBufferPtr buf, const char *str, int len) +void +__virBufferAdd(const virBufferPtr buf, const char *str, int len) { unsigned int needSize; - if ((str == NULL) || (buf == NULL)) { - return -1; - } - if (len == 0) - return 0; + if ((str == NULL) || (buf == NULL) || (len == 0)) + return; + + if (buf->error) + return; if (len < 0) len = strlen(str); needSize = buf->use + len + 2; - if (needSize > buf->size) { - if (!virBufferGrow(buf, needSize - buf->use)) { - return (-1); - } - } + if (needSize > buf->size && + virBufferGrow(buf, needSize - buf->use) < 0) + return; memcpy (&buf->content[buf->use], str, len); buf->use += len; - buf->content[buf->use] = 0; - return (0); + buf->content[buf->use] = '\0'; } /** @@ -94,89 +123,85 @@ __virBufferAdd(virBufferPtr buf, const char *str, int len) * * Add a single character 'c' to a buffer. * - * Returns 0 if successful, -1 in the case of error. */ -int +void __virBufferAddChar (virBufferPtr buf, char c) { unsigned int needSize; if (buf == NULL) - return -1; + return; + + if (buf->error) + return; needSize = buf->use + 2; - if (needSize > buf->size) - if (!virBufferGrow (buf, needSize - buf->use)) - return -1; + if (needSize > buf->size && + virBufferGrow (buf, needSize - buf->use) < 0) + return; buf->content[buf->use++] = c; - buf->content[buf->use] = 0; - - return 0; + buf->content[buf->use] = '\0'; } /** - * virBufferNew: - * @size: creation size in bytes + * virBufferContentAndReset: + * @buf: Buffer * - * Creates a new buffer + * Get the content from the buffer and free (only) the buffer structure. + * The caller owns the returned string & should free it when no longer + * required. The buffer object is reset to its initial state. * - * Returns a pointer to the buffer or NULL in case of error + * Returns the buffer content or NULL in case of error. */ -virBufferPtr -virBufferNew(unsigned int size) +char * +__virBufferContentAndReset(const virBufferPtr buf) { - virBufferPtr buf; + char *str; + if (buf == NULL) + return NULL; - if (!(buf = malloc(sizeof(*buf)))) return NULL; - if (size && (buf->content = malloc(size))==NULL) { - free(buf); + if (buf->error) { + memset(buf, 0, sizeof(*buf)); return NULL; } - buf->size = size; - buf->use = 0; - return buf; + str = buf->content; + memset(buf, 0, sizeof(*buf)); + return str; } /** - * virBufferFree: - * @buf: the buffer to deallocate + * virBufferError: + * @buf: the buffer * - * Free the set of resources used by a buffer. + * Check to see if the buffer is in an error state due + * to failed memory allocation + * + * Return true if in error, 0 if normal */ - -void -virBufferFree(virBufferPtr buf) +int +__virBufferError(const virBufferPtr buf) { - if (buf) { - free(buf->content); - free(buf); - } + if (buf == NULL) + return 1; + + return buf->error; } /** - * virBufferContentAndFree: - * @buf: Buffer + * virBufferUse: + * @buf: the usage of the string in the buffer * - * Get the content from the buffer and free (only) the buffer structure. - * - * Returns the buffer content or NULL in case of error. + * Return the string usage in bytes */ -char * -virBufferContentAndFree (virBufferPtr buf) +unsigned int +virBufferUse(const virBufferPtr buf) { - char *content; - if (buf == NULL) - return(NULL); - - content = buf->content; - if (content != NULL) - content[buf->use] = 0; + return 0; - free (buf); - return(content); + return buf->use; } /** @@ -186,22 +211,22 @@ virBufferContentAndFree (virBufferPtr buf) * @...: the variable list of arguments * * Do a formatted print to an XML buffer. - * - * Returns 0 successful, -1 in case of internal or API error. */ -int -__virBufferVSprintf(virBufferPtr buf, const char *format, ...) +void +__virBufferVSprintf(const virBufferPtr buf, const char *format, ...) { int size, count, grow_size; va_list locarg, argptr; - if ((format == NULL) || (buf == NULL)) { - return (-1); - } + if ((format == NULL) || (buf == NULL)) + return; + + if (buf->error) + return; if (buf->size == 0 && virBufferGrow(buf, 100) < 0) - return -1; + return; size = buf->size - buf->use - 1; va_start(argptr, format); @@ -210,17 +235,17 @@ __virBufferVSprintf(virBufferPtr buf, const char *format, ...) locarg)) < 0) || (count >= size - 1)) { buf->content[buf->use] = 0; va_end(locarg); + grow_size = (count > 1000) ? count : 1000; - if (virBufferGrow(buf, grow_size) < 0) { - return (-1); - } + if (virBufferGrow(buf, grow_size) < 0) + return; + size = buf->size - buf->use - 1; va_copy(locarg, argptr); } va_end(locarg); buf->use += count; - buf->content[buf->use] = 0; - return (0); + buf->content[buf->use] = '\0'; } /** @@ -231,25 +256,27 @@ __virBufferVSprintf(virBufferPtr buf, const char *format, ...) * * Do a formatted print with a single string to an XML buffer. The string * is escaped to avoid generating a not well-formed XML instance. - * - * Returns 0 successful, -1 in case of internal or API error. */ -int -virBufferEscapeString(virBufferPtr buf, const char *format, const char *str) +void +virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str) { int size, count, len, grow_size; char *escaped, *out; const char *cur; - if ((format == NULL) || (buf == NULL) || (str == NULL)) { - return (-1); - } + if ((format == NULL) || (buf == NULL) || (str == NULL)) + return; + + if (buf->error) + return; len = strlen(str); escaped = malloc(5 * len + 1); if (escaped == NULL) { - return (-1); + virBufferNoMemory(buf); + return; } + cur = str; out = escaped; while (*cur != 0) { @@ -290,14 +317,13 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str) grow_size = (count > 1000) ? count : 1000; if (virBufferGrow(buf, grow_size) < 0) { free(escaped); - return (-1); + return; } size = buf->size - buf->use - 1; } buf->use += count; - buf->content[buf->use] = 0; + buf->content[buf->use] = '\0'; free(escaped); - return (0); } /** @@ -308,10 +334,8 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str) * Append the string to the buffer. The string will be URI-encoded * during the append (ie any non alpha-numeric characters are replaced * with '%xx' hex sequences). - * - * Returns 0 successful, -1 in case of internal or API error. */ -int +void virBufferURIEncodeString (virBufferPtr buf, const char *str) { int grow_size = 0; @@ -319,6 +343,12 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str) unsigned char uc; const char *hex = "0123456789abcdef"; + if ((buf == NULL) || (str == NULL)) + return; + + if (buf->error) + return; + for (p = str; *p; ++p) { /* This may not work on EBCDIC. */ if ((*p >= 'a' && *p <= 'z') || @@ -329,8 +359,8 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str) grow_size += 3; /* %ab */ } - if (virBufferGrow (buf, grow_size) == -1) - return -1; + if (virBufferGrow (buf, grow_size) < 0) + return; for (p = str; *p; ++p) { /* This may not work on EBCDIC. */ @@ -347,7 +377,6 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str) } buf->content[buf->use] = '\0'; - return 0; } /** @@ -356,15 +385,16 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str) * @...: the variable list of strings, the last argument must be NULL * * Concatenate strings to an XML buffer. - * - * Returns 0 successful, -1 in case of internal or API error. */ -int +void virBufferStrcat(virBufferPtr buf, ...) { va_list ap; char *str; + if (buf->error) + return; + va_start(ap, buf); while ((str = va_arg(ap, char *)) != NULL) { @@ -372,13 +402,12 @@ virBufferStrcat(virBufferPtr buf, ...) unsigned int needSize = buf->use + len + 2; if (needSize > buf->size) { - if (!virBufferGrow(buf, needSize - buf->use)) - return -1; + if (virBufferGrow(buf, needSize - buf->use) < 0) + return; } memcpy(&buf->content[buf->use], str, len); buf->use += len; buf->content[buf->use] = 0; } va_end(ap); - return 0; } diff --git a/src/buf.h b/src/buf.h index fc15fe1286..e253448ce5 100644 --- a/src/buf.h +++ b/src/buf.h @@ -20,22 +20,30 @@ */ typedef struct _virBuffer virBuffer; typedef virBuffer *virBufferPtr; + +#ifndef __VIR_BUFFER_C__ +#define VIR_BUFFER_INITIALIZER { 0, 0, 0, NULL } + +/* This struct must be kept in syn with the real struct + in the buf.c impl file */ struct _virBuffer { - char *content; /* The buffer content UTF8 */ - unsigned int use; /* The buffer size used */ - unsigned int size; /* The buffer size */ + unsigned int a; + unsigned int b; + unsigned int c; + char *d; }; +#endif -virBufferPtr virBufferNew(unsigned int size); -void virBufferFree(virBufferPtr buf); -char *virBufferContentAndFree(virBufferPtr buf); -int __virBufferAdd(virBufferPtr buf, const char *str, int len); -int __virBufferAddChar(virBufferPtr buf, char c); -int __virBufferVSprintf(virBufferPtr buf, const char *format, ...) +char *__virBufferContentAndReset(const virBufferPtr buf); +int __virBufferError(const virBufferPtr buf); +unsigned int virBufferUse(const virBufferPtr buf); +void __virBufferAdd(const virBufferPtr buf, const char *str, int len); +void __virBufferAddChar(const virBufferPtr buf, char c); +void __virBufferVSprintf(const virBufferPtr buf, const char *format, ...) ATTRIBUTE_FORMAT(printf, 2, 3); -int virBufferStrcat(virBufferPtr buf, ...); -int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str); -int virBufferURIEncodeString (virBufferPtr buf, const char *str); +void virBufferStrcat(const virBufferPtr buf, ...); +void virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str); +void virBufferURIEncodeString (const virBufferPtr buf, const char *str); #define virBufferAddLit(buf_, literal_string_) \ __virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1) @@ -44,4 +52,7 @@ int virBufferURIEncodeString (virBufferPtr buf, const char *str); #define virBufferAddChar(b,c) __virBufferAddChar((b),(c)) #define virBufferVSprintf(b,f,...) __virBufferVSprintf((b),(f), __VA_ARGS__) +#define virBufferContentAndReset(b) __virBufferContentAndReset((b)) +#define virBufferError(b) __virBufferError((b)) + #endif /* __VIR_BUFFER_H__ */ diff --git a/src/capabilities.c b/src/capabilities.c index 18fc2a337d..8965c11cb5 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -521,172 +521,127 @@ virCapabilitiesDefaultGuestEmulator(virCapsPtr caps, char * virCapabilitiesFormatXML(virCapsPtr caps) { - virBuffer xml = { NULL, 0, 0 }; + virBuffer xml = VIR_BUFFER_INITIALIZER; int i, j, k; - if (virBufferAddLit(&xml, "\n\n") < 0) - goto no_memory; - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; - if (virBufferVSprintf(&xml, " %s\n", - caps->host.arch) < 0) - goto no_memory; + virBufferAddLit(&xml, "\n\n"); + virBufferAddLit(&xml, " \n"); + virBufferAddLit(&xml, " \n"); + virBufferVSprintf(&xml, " %s\n", + caps->host.arch); if (caps->host.nfeatures) { - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); for (i = 0 ; i < caps->host.nfeatures ; i++) { - if (virBufferVSprintf(&xml, " <%s/>\n", - caps->host.features[i]) <0) - goto no_memory; + virBufferVSprintf(&xml, " <%s/>\n", + caps->host.features[i]); } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); if (caps->host.offlineMigrate) { - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; - if (caps->host.liveMigrate && - virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); + if (caps->host.liveMigrate) + virBufferAddLit(&xml, " \n"); if (caps->host.nmigrateTrans) { - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); for (i = 0 ; i < caps->host.nmigrateTrans ; i++) { - if (virBufferVSprintf(&xml, " %s\n", - caps->host.migrateTrans[i]) < 0) - goto no_memory; + virBufferVSprintf(&xml, " %s\n", + caps->host.migrateTrans[i]); } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); } if (caps->host.nnumaCell) { - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; - if (virBufferVSprintf(&xml, " \n", - caps->host.nnumaCell) < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); + virBufferVSprintf(&xml, " \n", + caps->host.nnumaCell); for (i = 0 ; i < caps->host.nnumaCell ; i++) { - if (virBufferVSprintf(&xml, " \n", - caps->host.numaCell[i]->num) < 0) - goto no_memory; - if (virBufferVSprintf(&xml, " \n", - caps->host.numaCell[i]->ncpus) < 0) - goto no_memory; + virBufferVSprintf(&xml, " \n", + caps->host.numaCell[i]->num); + virBufferVSprintf(&xml, " \n", + caps->host.numaCell[i]->ncpus); for (j = 0 ; j < caps->host.numaCell[i]->ncpus ; j++) - if (virBufferVSprintf(&xml, " \n", - caps->host.numaCell[i]->cpus[j]) < 0) - goto no_memory; - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferVSprintf(&xml, " \n", + caps->host.numaCell[i]->cpus[j]); + virBufferAddLit(&xml, " \n"); + virBufferAddLit(&xml, " \n"); } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); + virBufferAddLit(&xml, " \n"); } - if (virBufferAddLit(&xml, " \n\n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n\n"); for (i = 0 ; i < caps->nguests ; i++) { - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; - if (virBufferVSprintf(&xml, " %s\n", - caps->guests[i]->ostype) < 0) - goto no_memory; - if (virBufferVSprintf(&xml, " \n", - caps->guests[i]->arch.name) < 0) - goto no_memory; - if (virBufferVSprintf(&xml, " %d\n", - caps->guests[i]->arch.wordsize) < 0) - goto no_memory; - if (caps->guests[i]->arch.defaultInfo.emulator && + virBufferAddLit(&xml, " \n"); + virBufferVSprintf(&xml, " %s\n", + caps->guests[i]->ostype); + virBufferVSprintf(&xml, " \n", + caps->guests[i]->arch.name); + virBufferVSprintf(&xml, " %d\n", + caps->guests[i]->arch.wordsize); + if (caps->guests[i]->arch.defaultInfo.emulator) virBufferVSprintf(&xml, " %s\n", - caps->guests[i]->arch.defaultInfo.emulator) < 0) - goto no_memory; - if (caps->guests[i]->arch.defaultInfo.loader && - virBufferVSprintf(&xml, " %s\n", - caps->guests[i]->arch.defaultInfo.loader) < 0) - goto no_memory; + caps->guests[i]->arch.defaultInfo.emulator); + if (caps->guests[i]->arch.defaultInfo.loader) + virBufferVSprintf(&xml, " %s\n", + caps->guests[i]->arch.defaultInfo.loader); for (j = 0 ; j < caps->guests[i]->arch.defaultInfo.nmachines ; j++) { - if (virBufferVSprintf(&xml, " %s\n", - caps->guests[i]->arch.defaultInfo.machines[j]) < 0) - goto no_memory; + virBufferVSprintf(&xml, " %s\n", + caps->guests[i]->arch.defaultInfo.machines[j]); } for (j = 0 ; j < caps->guests[i]->arch.ndomains ; j++) { - if (virBufferVSprintf(&xml, " \n", - caps->guests[i]->arch.domains[j]->type) < 0) - goto no_memory; - if (caps->guests[i]->arch.domains[j]->info.emulator && + virBufferVSprintf(&xml, " \n", + caps->guests[i]->arch.domains[j]->type); + if (caps->guests[i]->arch.domains[j]->info.emulator) virBufferVSprintf(&xml, " %s\n", - caps->guests[i]->arch.domains[j]->info.emulator) < 0) - goto no_memory; - if (caps->guests[i]->arch.domains[j]->info.loader && + caps->guests[i]->arch.domains[j]->info.emulator); + if (caps->guests[i]->arch.domains[j]->info.loader) virBufferVSprintf(&xml, " %s\n", - caps->guests[i]->arch.domains[j]->info.loader) < 0) - goto no_memory; + caps->guests[i]->arch.domains[j]->info.loader); for (k = 0 ; k < caps->guests[i]->arch.domains[j]->info.nmachines ; k++) { - if (virBufferVSprintf(&xml, " %s\n", - caps->guests[i]->arch.domains[j]->info.machines[k]) < 0) - goto no_memory; + virBufferVSprintf(&xml, " %s\n", + caps->guests[i]->arch.domains[j]->info.machines[k]); } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); if (caps->guests[i]->nfeatures) { - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); for (j = 0 ; j < caps->guests[i]->nfeatures ; j++) { if (STREQ(caps->guests[i]->features[j]->name, "pae") || STREQ(caps->guests[i]->features[j]->name, "nonpae") || STREQ(caps->guests[i]->features[j]->name, "ia64_be")) { - if (virBufferVSprintf(&xml, " <%s/>\n", - caps->guests[i]->features[j]->name) < 0) - goto no_memory; + virBufferVSprintf(&xml, " <%s/>\n", + caps->guests[i]->features[j]->name); } else { - if (virBufferVSprintf(&xml, " <%s default='%s' toggle='%s'/>\n", - caps->guests[i]->features[j]->name, - caps->guests[i]->features[j]->defaultOn ? "on" : "off", - caps->guests[i]->features[j]->toggle ? "yes" : "no") < 0) - goto no_memory; + virBufferVSprintf(&xml, " <%s default='%s' toggle='%s'/>\n", + caps->guests[i]->features[j]->name, + caps->guests[i]->features[j]->defaultOn ? "on" : "off", + caps->guests[i]->features[j]->toggle ? "yes" : "no"); } } - if (virBufferAddLit(&xml, " \n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n"); } - - if (virBufferAddLit(&xml, " \n\n") < 0) - goto no_memory; + virBufferAddLit(&xml, " \n\n"); } - if (virBufferAddLit(&xml, "\n") < 0) - goto no_memory; + virBufferAddLit(&xml, "\n"); - return xml.content; + if (virBufferError(&xml)) + return NULL; - no_memory: - free(xml.content); - return NULL; + return virBufferContentAndReset(&xml); } diff --git a/src/conf.c b/src/conf.c index 6cbcde538a..bc369c7ead 100644 --- a/src/conf.c +++ b/src/conf.c @@ -877,43 +877,45 @@ __virConfSetValue (virConfPtr conf, int __virConfWriteFile(const char *filename, virConfPtr conf) { - virBufferPtr buf; + virBuffer buf = VIR_BUFFER_INITIALIZER; virConfEntryPtr cur; int ret; int fd; + char *content; + unsigned int use; if (conf == NULL) return(-1); - buf = virBufferNew(500); - if (buf == NULL) { - virConfError(NULL, VIR_ERR_NO_MEMORY, _("failed to allocate buffer"), 0); - return(-1); - } - cur = conf->entries; while (cur != NULL) { - virConfSaveEntry(buf, cur); + virConfSaveEntry(&buf, cur); cur = cur->next; } + if (virBufferError(&buf)) { + virConfError(NULL, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0); + return -1; + } + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR ); if (fd < 0) { virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to open file"), 0); - ret = -1; - goto error; + free(virBufferContentAndReset(&buf)); + return -1; } - ret = safewrite(fd, buf->content, buf->use); + use = virBufferUse(&buf); + content = virBufferContentAndReset(&buf); + ret = safewrite(fd, content, use); + free(content); close(fd); - if (ret != (int) buf->use) { + if (ret != (int)use) { virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to save content"), 0); - ret = -1; - goto error; + return -1; } -error: - virBufferFree(buf); - return(ret); + + return ret; } /** @@ -932,34 +934,35 @@ error: int __virConfWriteMem(char *memory, int *len, virConfPtr conf) { - virBufferPtr buf; + virBuffer buf = VIR_BUFFER_INITIALIZER; virConfEntryPtr cur; - int ret; + char *content; + unsigned int use; if ((memory == NULL) || (len == NULL) || (*len <= 0) || (conf == NULL)) return(-1); - buf = virBufferNew(500); - if (buf == NULL) { - virConfError(NULL, VIR_ERR_NO_MEMORY, _("failed to allocate buffer"), 0); - return(-1); - } - cur = conf->entries; while (cur != NULL) { - virConfSaveEntry(buf, cur); + virConfSaveEntry(&buf, cur); cur = cur->next; } - if ((int) buf->use >= *len) { - *len = buf->use; - ret = -1; - goto error; + if (virBufferError(&buf)) { + virConfError(NULL, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0); + return -1; } - memcpy(memory, buf->content, buf->use); - ret = buf->use; - *len = buf->use; -error: - virBufferFree(buf); - return(ret); + + use = virBufferUse(&buf); + content = virBufferContentAndReset(&buf); + + if ((int)use >= *len) { + *len = (int)use; + free(content); + return -1; + } + memcpy(memory, content, use); + free(content); + *len = use; + return use; } diff --git a/src/libvirt_sym.version b/src/libvirt_sym.version index 694e0415b5..77f0b5534e 100644 --- a/src/libvirt_sym.version +++ b/src/libvirt_sym.version @@ -184,6 +184,8 @@ __virBufferVSprintf; __virBufferAdd; __virBufferAddChar; + __virBufferContentAndReset; + __virBufferError; __virMacAddrCompare; diff --git a/src/lxc_conf.c b/src/lxc_conf.c index 8f01844180..f9bd20ab46 100644 --- a/src/lxc_conf.c +++ b/src/lxc_conf.c @@ -688,99 +688,49 @@ char *lxcGenerateXML(virConnectPtr conn, lxc_vm_t *vm, lxc_vm_def_t *def) { - virBufferPtr buf = 0; + virBuffer buf = VIR_BUFFER_INITIALIZER; unsigned char *uuid; char uuidstr[VIR_UUID_STRING_BUFLEN]; lxc_mount_t *mount; - buf = virBufferNew(LXC_MAX_XML_LENGTH); - if (!buf) { - goto no_memory; - } + if (lxcIsActiveVM(vm)) + virBufferVSprintf(&buf, "\n", + LXC_DOMAIN_TYPE, vm->def->id); + else + virBufferVSprintf(&buf, "\n", + LXC_DOMAIN_TYPE); - if (lxcIsActiveVM(vm)) { - if (virBufferVSprintf(buf, "\n", - LXC_DOMAIN_TYPE, vm->def->id) < 0) { - goto no_memory; - } - } else { - if (virBufferVSprintf(buf, "\n", - LXC_DOMAIN_TYPE) < 0) { - goto no_memory; - } - } - - if (virBufferVSprintf(buf, " %s\n", def->name) < 0) { - goto no_memory; - } + virBufferVSprintf(&buf, " %s\n", def->name); uuid = def->uuid; virUUIDFormat(uuid, uuidstr); - if (virBufferVSprintf(buf, " %s\n", uuidstr) < 0) { - goto no_memory; - } - - if (virBufferAddLit(buf, " \n") < 0) { - goto no_memory; - } - - if (virBufferVSprintf(buf, " %s\n", def->init) < 0) { - goto no_memory; - } - - if (virBufferAddLit(buf, " \n") < 0) { - goto no_memory; - } - - if (virBufferVSprintf(buf, " %d\n", def->maxMemory) < 0) { - goto no_memory; - } - - if (virBufferAddLit(buf, " \n") < 0) { - goto no_memory; - } + virBufferVSprintf(&buf, " %s\n", uuidstr); + virBufferAddLit(&buf, " \n"); + virBufferVSprintf(&buf, " %s\n", def->init); + virBufferAddLit(&buf, " \n"); + virBufferVSprintf(&buf, " %d\n", def->maxMemory); + virBufferAddLit(&buf, " \n"); /* loop adding mounts */ for (mount = def->mounts; mount; mount = mount->next) { - if (virBufferAddLit(buf, " \n") < 0) { - goto no_memory; - } - - if (virBufferVSprintf(buf, " \n", - mount->source) < 0) { - goto no_memory; - } - - if (virBufferVSprintf(buf, " \n", - mount->target) < 0) { - goto no_memory; - } - - if (virBufferAddLit(buf, " \n") < 0) { - goto no_memory; - } - - } - - if (virBufferVSprintf(buf, " \n", def->tty) < 0) { - goto no_memory; + virBufferAddLit(&buf, " \n"); + virBufferVSprintf(&buf, " \n", + mount->source); + virBufferVSprintf(&buf, " \n", + mount->target); + virBufferAddLit(&buf, " \n"); } - if (virBufferAddLit(buf, " \n") < 0) { - goto no_memory; - } + virBufferVSprintf(&buf, " \n", def->tty); + virBufferAddLit(&buf, " \n"); + virBufferAddLit(&buf, "\n"); - if (virBufferAddLit(buf, "\n") < 0) { - goto no_memory; + if (virBufferError(&buf)) { + lxcError(conn, NULL, VIR_ERR_NO_MEMORY,_("allocate buffer")); + return NULL; } - return virBufferContentAndFree(buf); - -no_memory: - lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "generateXml"); - virBufferFree(buf); - - return NULL; + return virBufferContentAndReset(&buf); } void lxcFreeVMDef(lxc_vm_def_t *vmdef) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 2d048d36ff..07dfe47d8b 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -3359,14 +3359,12 @@ static int qemudGenerateXMLChar(virBufferPtr buf, if (STREQ(type, "console") && dev->srcType == QEMUD_CHR_SRC_TYPE_PTY && dev->srcData.file.path[0] != '\0') { - if (virBufferVSprintf(buf, " <%s type='%s' tty='%s'>\n", - type, types[dev->srcType], - dev->srcData.file.path) < 0) - return -1; + virBufferVSprintf(buf, " <%s type='%s' tty='%s'>\n", + type, types[dev->srcType], + dev->srcData.file.path); } else { - if (virBufferVSprintf(buf, " <%s type='%s'>\n", - type, types[dev->srcType]) < 0) - return -1; + virBufferVSprintf(buf, " <%s type='%s'>\n", + type, types[dev->srcType]); } switch (dev->srcType) { @@ -3382,74 +3380,62 @@ static int qemudGenerateXMLChar(virBufferPtr buf, case QEMUD_CHR_SRC_TYPE_PIPE: if (dev->srcType != QEMUD_CHR_SRC_TYPE_PTY || dev->srcData.file.path[0]) { - if (virBufferVSprintf(buf, " \n", - dev->srcData.file.path) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.file.path); } break; case QEMUD_CHR_SRC_TYPE_UDP: if (dev->srcData.udp.bindService[0] != '\0' && dev->srcData.udp.bindHost[0] != '\0') { - if (virBufferVSprintf(buf, " \n", - dev->srcData.udp.bindHost, - dev->srcData.udp.bindService) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.udp.bindHost, + dev->srcData.udp.bindService); } else if (dev->srcData.udp.bindHost[0] !='\0') { - if (virBufferVSprintf(buf, " \n", - dev->srcData.udp.bindHost) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.udp.bindHost); } else if (dev->srcData.udp.bindService[0] != '\0') { - if (virBufferVSprintf(buf, " \n", - dev->srcData.udp.bindService) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.udp.bindService); } if (dev->srcData.udp.connectService[0] != '\0' && dev->srcData.udp.connectHost[0] != '\0') { - if (virBufferVSprintf(buf, " \n", - dev->srcData.udp.connectHost, - dev->srcData.udp.connectService) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.udp.connectHost, + dev->srcData.udp.connectService); } else if (dev->srcData.udp.connectHost[0] != '\0') { - if (virBufferVSprintf(buf, " \n", - dev->srcData.udp.connectHost) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.udp.connectHost); } else if (dev->srcData.udp.connectService[0] != '\0') { - if (virBufferVSprintf(buf, " \n", - dev->srcData.udp.connectService) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.udp.connectService); } break; case QEMUD_CHR_SRC_TYPE_TCP: - if (virBufferVSprintf(buf, " \n", - dev->srcData.tcp.listen ? "bind" : "connect", - dev->srcData.tcp.host, - dev->srcData.tcp.service) < 0) - return -1; - if (virBufferVSprintf(buf, " \n", - dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET - ? "telnet" : "raw") < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.tcp.listen ? "bind" : "connect", + dev->srcData.tcp.host, + dev->srcData.tcp.service); + virBufferVSprintf(buf, " \n", + dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET + ? "telnet" : "raw"); break; case QEMUD_CHR_SRC_TYPE_UNIX: - if (virBufferVSprintf(buf, " \n", - dev->srcData.nix.listen ? "bind" : "connect", - dev->srcData.nix.path) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->srcData.nix.listen ? "bind" : "connect", + dev->srcData.nix.path); break; } - if (virBufferVSprintf(buf, " \n", - dev->dstPort) < 0) - return -1; + virBufferVSprintf(buf, " \n", + dev->dstPort); - if (virBufferVSprintf(buf, " \n", - type) < 0) - return -1; + virBufferVSprintf(buf, " \n", + type); return 0; } @@ -3461,7 +3447,7 @@ char *qemudGenerateXML(virConnectPtr conn, struct qemud_vm *vm, struct qemud_vm_def *def, int live) { - virBufferPtr buf = 0; + virBuffer buf = VIR_BUFFER_INITIALIZER; unsigned char *uuid; char uuidstr[VIR_UUID_STRING_BUFLEN]; const struct qemud_vm_disk_def *disk; @@ -3471,10 +3457,6 @@ char *qemudGenerateXML(virConnectPtr conn, const char *type = NULL; int n; - buf = virBufferNew (QEMUD_MAX_XML_LEN); - if (!buf) - goto no_memory; - switch (def->virtType) { case QEMUD_VIRT_QEMU: type = "qemu"; @@ -3492,49 +3474,34 @@ char *qemudGenerateXML(virConnectPtr conn, goto cleanup; } - if (qemudIsActiveVM(vm) && live) { - if (virBufferVSprintf(buf, "\n", type, vm->id) < 0) - goto no_memory; - } else { - if (virBufferVSprintf(buf, "\n", type) < 0) - goto no_memory; - } + if (qemudIsActiveVM(vm) && live) + virBufferVSprintf(&buf, "\n", type, vm->id); + else + virBufferVSprintf(&buf, "\n", type); - if (virBufferVSprintf(buf, " %s\n", def->name) < 0) - goto no_memory; + virBufferVSprintf(&buf, " %s\n", def->name); uuid = def->uuid; virUUIDFormat(uuid, uuidstr); - if (virBufferVSprintf(buf, " %s\n", uuidstr) < 0) - goto no_memory; - if (virBufferVSprintf(buf, " %lu\n", def->maxmem) < 0) - goto no_memory; - if (virBufferVSprintf(buf, " %lu\n", def->memory) < 0) - goto no_memory; - if (virBufferVSprintf(buf, " %d\n", def->vcpus) < 0) - goto no_memory; + virBufferVSprintf(&buf, " %s\n", uuidstr); - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; + virBufferVSprintf(&buf, " %lu\n", def->maxmem); + virBufferVSprintf(&buf, " %lu\n", def->memory); + virBufferVSprintf(&buf, " %d\n", def->vcpus); + virBufferAddLit(&buf, " \n"); - if (def->virtType == QEMUD_VIRT_QEMU) { - if (virBufferVSprintf(buf, " %s\n", - def->os.arch, def->os.machine, def->os.type) < 0) - goto no_memory; - } else { - if (virBufferVSprintf(buf, " %s\n", def->os.type) < 0) - goto no_memory; - } + if (def->virtType == QEMUD_VIRT_QEMU) + virBufferVSprintf(&buf, " %s\n", + def->os.arch, def->os.machine, def->os.type); + else + virBufferVSprintf(&buf, " %s\n", def->os.type); if (def->os.kernel[0]) - if (virBufferVSprintf(buf, " %s\n", def->os.kernel) < 0) - goto no_memory; + virBufferVSprintf(&buf, " %s\n", def->os.kernel); if (def->os.initrd[0]) - if (virBufferVSprintf(buf, " %s\n", def->os.initrd) < 0) - goto no_memory; + virBufferVSprintf(&buf, " %s\n", def->os.initrd); if (def->os.cmdline[0]) - if (virBufferVSprintf(buf, " %s\n", def->os.cmdline) < 0) - goto no_memory; + virBufferVSprintf(&buf, " %s\n", def->os.cmdline); for (n = 0 ; n < def->os.nBootDevs ; n++) { const char *boottype = "hd"; @@ -3552,41 +3519,29 @@ char *qemudGenerateXML(virConnectPtr conn, boottype = "network"; break; } - if (virBufferVSprintf(buf, " \n", boottype) < 0) - goto no_memory; + virBufferVSprintf(&buf, " \n", boottype); } - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; + virBufferAddLit(&buf, " \n"); if (def->features & QEMUD_FEATURE_ACPI) { - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; + virBufferAddLit(&buf, " \n"); + virBufferAddLit(&buf, " \n"); + virBufferAddLit(&buf, " \n"); } - virBufferVSprintf(buf, " \n", def->localtime ? "localtime" : "utc"); + virBufferVSprintf(&buf, " \n", def->localtime ? "localtime" : "utc"); - if (virBufferAddLit(buf, " destroy\n") < 0) - goto no_memory; - if (def->noReboot) { - if (virBufferAddLit(buf, " destroy\n") < 0) - goto no_memory; - } else { - if (virBufferAddLit(buf, " restart\n") < 0) - goto no_memory; - } - if (virBufferAddLit(buf, " destroy\n") < 0) - goto no_memory; + virBufferAddLit(&buf, " destroy\n"); + if (def->noReboot) + virBufferAddLit(&buf, " destroy\n"); + else + virBufferAddLit(&buf, " restart\n"); - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; + virBufferAddLit(&buf, " destroy\n"); + virBufferAddLit(&buf, " \n"); - if (virBufferVSprintf(buf, " %s\n", def->os.binary) < 0) - goto no_memory; + virBufferVSprintf(&buf, " %s\n", def->os.binary); disk = def->disks; while (disk) { @@ -3603,24 +3558,19 @@ char *qemudGenerateXML(virConnectPtr conn, "cdrom", "floppy", }; - if (virBufferVSprintf(buf, " \n", - types[disk->type], devices[disk->device]) < 0) - goto no_memory; + virBufferVSprintf(&buf, " \n", + types[disk->type], devices[disk->device]); if (disk->src[0]) - if (virBufferVSprintf(buf, " \n", - typeAttrs[disk->type], disk->src) < 0) - goto no_memory; + virBufferVSprintf(&buf, " \n", + typeAttrs[disk->type], disk->src); - if (virBufferVSprintf(buf, " \n", disk->dst) < 0) - goto no_memory; + virBufferVSprintf(&buf, " \n", disk->dst); if (disk->readonly) - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; + virBufferAddLit(&buf, " \n"); - if (virBufferAddLit(buf, " \n") < 0) - goto no_memory; + virBufferAddLit(&buf, " \n"); disk = disk->next; } @@ -3636,69 +3586,53 @@ char *qemudGenerateXML(virConnectPtr conn, "network", "bridge", }; - if (virBufferVSprintf(buf, " \n", - types[net->type]) < 0) - goto no_memory; + virBufferVSprintf(&buf, " \n", + types[net->type]); - if (virBufferVSprintf(buf, " \n", - net->mac[0], net->mac[1], net->mac[2], - net->mac[3], net->mac[4], net->mac[5]) < 0) - goto no_memory; + virBufferVSprintf(&buf, " \n", + net->mac[0], net->mac[1], net->mac[2], + net->mac[3], net->mac[4], net->mac[5]); switch (net->type) { case QEMUD_NET_NETWORK: - if (virBufferVSprintf(buf, " \n", net->dst.network.name) < 0) - goto no_memory; + virBufferVSprintf(&buf, " \n", net->dst.network.name); - if (net->dst.network.ifname[0] != '\0') { - if (virBufferVSprintf(buf, " \n", net->dst.network.ifname) < 0) - goto no_memory; - } + if (net->dst.network.ifname[0] != '\0') + virBufferVSprintf(&buf, " \n", net->dst.network.ifname); break; case QEMUD_NET_ETHERNET: - if (net->dst.ethernet.ifname[0] != '\0') { - if (virBufferVSprintf(buf, " \n", net->dst.ethernet.ifname) < 0) - goto no_memory; - } - if (net->dst.ethernet.script[0] != '\0') { - if (virBufferVSprintf(buf, "