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.