
Hi Rich, On Tue, 2007-05-22 at 15:10 +0100, Richard W.M. Jones wrote:
+static char * +readFile (vshControl *ctl, const char *filename) +{ + char *buffer = NULL, *oldbuffer; + int len = 0, fd, r; + char b[1024]; + + fd = open (filename, O_RDONLY); + if (fd == -1) { + file_error: + vshError (ctl, FALSE, "%s: %s", filename, strerror (errno)); + error: + if (buffer) free (buffer); + if (fd >= 0) close (fd); + return NULL; + } + + for (;;) { + r = read (fd, b, sizeof b); + if (r == -1) goto file_error; + if (r == 0) break; /* End of file. */ + oldbuffer = buffer; + buffer = realloc (buffer, len+r); + if (buffer == NULL) { + out_of_memory: + vshError (ctl, FALSE, "realloc: %s", strerror (errno)); + goto error; + } + memcpy (buffer+len, b, r); + len += r; + } + + buffer = realloc (buffer, len+1); + if (buffer == NULL) goto out_of_memory; + buffer[len] = '\0'; + return buffer; +}
Truly, the way you're using gotos here gives me a serious headache. Following the logic of the function involves jumping back and forth around the code way too much. I noticed you using that style in the remote patch too. I'd suggest something more like: static char * readFile(vshControl *ctl, const char *filename) { char *retval; int len = 0, fd; if ((fd = open(filename, O_RDONLY)) < 0) { vshError (ctl, FALSE, "Failed to open '%s': %s", filename, strerror (errno)); return NULL; } if (!(retval = malloc(len + 1))) goto out_of_memory; while (1) { char buffer[1024]; char *new; int ret; if ((ret = read(fd, buffer, sizeof(buffer))) == 0) break; if (ret == -1) { if (errno == EINTR) continue; vshError (ctl, FALSE, "Failed to open '%s': %s", filename, strerror (errno)); goto error; } if (!(new = realloc(retval, len + ret + 1))) goto out_of_memory; retval = new; memcpy(retval + len, buffer, ret); len += ret; } retval[len] = '\0'; return buffer; out_of_memory: vshError (ctl, FALSE, "Error allocating memory: %s", strerror(errno)); error: if (retval) free(retval); close(fd); return NULL; } You can read this version straight through without having to jump back to an earlier part of the function. Cheers, Mark.