Commit 575e82180aa41c12a56f88f1c9dd01d1bac56424

Stefan Sperling 2019-10-07T10:26:33

more mechanical conversions to struct got_error: buf_load() and buf_alloc()

diff --git a/lib/buf.c b/lib/buf.c
index b744f0f..a2d26a3 100644
--- a/lib/buf.c
+++ b/lib/buf.c
@@ -49,7 +49,7 @@ struct buf {
 	size_t	 cb_len;
 };
 
-#define SIZE_LEFT(b)	(b->cb_size - b->cb_len)
+#define SIZE_LEFT(b)	((b)->cb_size - (b)->cb_len)
 
 static const struct got_error *buf_grow(BUF *, size_t);
 
@@ -58,28 +58,30 @@ static const struct got_error *buf_grow(BUF *, size_t);
  * uses dynamically-allocated memory and must be freed with buf_free(), once
  * the buffer is no longer needed.
  */
-BUF *
-buf_alloc(size_t len)
+const struct got_error *
+buf_alloc(BUF **b, size_t len)
 {
-	BUF *b;
+	const struct got_error *err = NULL;
 
-	b = malloc(sizeof(*b));
-	if (b == NULL)
+	*b = malloc(sizeof(**b));
+	if (*b == NULL)
 		return NULL;
 	/* Postpone creation of zero-sized buffers */
 	if (len > 0) {
-		b->cb_buf = calloc(1, len);
-		if (b->cb_buf == NULL) {
-			free(b);
-			return NULL;
+		(*b)->cb_buf = calloc(1, len);
+		if ((*b)->cb_buf == NULL) {
+			err = got_error_from_errno("calloc");
+			free(*b);
+			*b = NULL;
+			return err;
 		}
 	} else
-		b->cb_buf = NULL;
+		(*b)->cb_buf = NULL;
 
-	b->cb_size = len;
-	b->cb_len = 0;
+	(*b)->cb_size = len;
+	(*b)->cb_len = 0;
 
-	return (b);
+	return NULL;
 }
 
 /*
@@ -88,57 +90,54 @@ buf_alloc(size_t len)
  * Returns the loaded buffer on success or NULL on failure.
  * Sets errno on error.
  */
-BUF *
-buf_load(const char *path)
+const struct got_error *
+buf_load(BUF **buf, const char *path)
 {
+	const struct got_error *err = NULL;
 	int fd;
 	ssize_t ret;
 	size_t len;
 	u_char *bp;
 	struct stat st;
-	BUF *buf;
 
-	buf = NULL;
+	*buf = NULL;
 
-	if ((fd = open(path, O_RDONLY, 0600)) == -1)
-		goto out;
+	fd = open(path, O_RDONLY, 0600);
+	if (fd == -1)
+		return got_error_from_errno2("open", path);
 
-	if (fstat(fd, &st) == -1)
+	if (fstat(fd, &st) == -1) {
+		err = got_error_from_errno2("fstat", path);
 		goto out;
+	}
 
 	if ((uintmax_t)st.st_size > SIZE_MAX) {
-		errno = EFBIG;
+		err = got_error_set_errno(EFBIG, path);
 		goto out;
 	}
-	buf = buf_alloc(st.st_size);
-	for (bp = buf->cb_buf; ; bp += (size_t)ret) {
-		len = SIZE_LEFT(buf);
+	err = buf_alloc(buf, st.st_size);
+	if (err)
+		goto out;
+	for (bp = (*buf)->cb_buf; ; bp += (size_t)ret) {
+		len = SIZE_LEFT(*buf);
 		ret = read(fd, bp, len);
 		if (ret == -1) {
-			int saved_errno;
-
-			saved_errno = errno;
-			buf_free(buf);
-			buf = NULL;
-			errno = saved_errno;
+			err = got_error_from_errno2("read", path);
 			goto out;
 		} else if (ret == 0)
 			break;
 
-		buf->cb_len += (size_t)ret;
+		(*buf)->cb_len += (size_t)ret;
 	}
 
 out:
-	if (fd != -1) {
-		int saved_errno;
-
-		/* We may want to preserve errno here. */
-		saved_errno = errno;
-		(void)close(fd);
-		errno = saved_errno;
+	if (close(fd) == -1 && err == NULL)
+		err = got_error_from_errno2("close", path);
+	if (err) {
+		buf_free(*buf);
+		*buf = NULL;
 	}
-
-	return (buf);
+	return err;
 }
 
 void
diff --git a/lib/buf.h b/lib/buf.h
index 9e3cb7e..6bc2401 100644
--- a/lib/buf.h
+++ b/lib/buf.h
@@ -43,8 +43,8 @@
 typedef struct buf BUF;
 struct wklhead;
 
-BUF		*buf_alloc(size_t);
-BUF		*buf_load(const char *);
+const struct got_error *buf_alloc(BUF **, size_t);
+const struct got_error *buf_load(BUF **, const char *);
 void		 buf_free(BUF *);
 void		*buf_release(BUF *);
 u_char		 buf_getc(BUF *, size_t);
diff --git a/lib/diff3.c b/lib/diff3.c
index 1811956..7b3015b 100644
--- a/lib/diff3.c
+++ b/lib/diff3.c
@@ -243,9 +243,7 @@ diffreg(BUF **d, const char *path1, const char *path2)
 		goto done;
 	}
 
-	*d = buf_load(outpath);
-	if (*d == NULL)
-		err = got_error_from_errno("buf_load");
+	err = buf_load(d, outpath);
 done:
 	if (outpath) {
 		unlink(outpath);
@@ -288,14 +286,19 @@ got_merge_diff3(int *overlapcnt, int outfd, const char *p1, const char *p2,
 	dp13 = dp23 = path1 = path2 = path3 = NULL;
 	data = patch = NULL;
 
-	if ((b1 = buf_load(p1)) == NULL)
+	err = buf_load(&b1, p1);
+	if (err)
 		goto out;
-	if ((b2 = buf_load(p2)) == NULL)
+	err = buf_load(&b2, p2);
+	if (err)
 		goto out;
-	if ((b3 = buf_load(p3)) == NULL)
+	err = buf_load(&b3, p3);
+	if (err)
 		goto out;
 
-	diffb = buf_alloc(128);
+	err = buf_alloc(&diffb, 128);
+	if (err)
+		goto out;
 
 	if (asprintf(&path1, "/tmp/got-diff1.XXXXXXXX") == -1) {
 		err = got_error_from_errno("asprintf");
diff --git a/lib/rcsutil.c b/lib/rcsutil.c
index dbc118f..ac95dc7 100644
--- a/lib/rcsutil.c
+++ b/lib/rcsutil.c
@@ -99,6 +99,7 @@ BUF *
 rcs_patchfile(u_char *data, size_t dlen, u_char *patch, size_t plen,
     int (*p)(struct rcs_lines *, struct rcs_lines *))
 {
+	const struct got_error *err = NULL;
 	struct rcs_lines *dlines, *plines;
 	struct rcs_line *lp;
 	BUF *res;
@@ -113,7 +114,9 @@ rcs_patchfile(u_char *data, size_t dlen, u_char *patch, size_t plen,
 		return (NULL);
 	}
 
-	res = buf_alloc(1024);
+	err = buf_alloc(&res, 1024);
+	if (err)
+		return NULL;
 	TAILQ_FOREACH(lp, &dlines->l_lines, l_list) {
 		if (lp->l_line == NULL)
 			continue;