summaryrefslogtreecommitdiff
path: root/usr.bin/rcs/buf.c
diff options
context:
space:
mode:
authorRay Lai <ray@cvs.openbsd.org>2006-08-16 07:39:16 +0000
committerRay Lai <ray@cvs.openbsd.org>2006-08-16 07:39:16 +0000
commitdd109580266c56df7b5feb24de5100e6d457579f (patch)
treeb386c6f592769599dd4e9d5d096971816e90aa69 /usr.bin/rcs/buf.c
parent65bc33032d45046943c4d18a409e2c0e7d02b696 (diff)
Improve rcs_buf_load() by setting errno appropriately on failure and
never print errors or quit on error. Fix usages of rcs_buf_load() and rcs_set_description. Also plug an fd leak. OK xsa@
Diffstat (limited to 'usr.bin/rcs/buf.c')
-rw-r--r--usr.bin/rcs/buf.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/usr.bin/rcs/buf.c b/usr.bin/rcs/buf.c
index 525f7000c01..bb52670ffb2 100644
--- a/usr.bin/rcs/buf.c
+++ b/usr.bin/rcs/buf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buf.c,v 1.7 2006/08/02 03:28:50 ray Exp $ */
+/* $OpenBSD: buf.c,v 1.8 2006/08/16 07:39:15 ray Exp $ */
/*
* Copyright (c) 2003 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -81,7 +81,8 @@ rcs_buf_alloc(size_t len, u_int flags)
*
* Open the file specified by <path> and load all of its contents into a
* buffer.
- * Returns the loaded buffer on success.
+ * Returns the loaded buffer on success or NULL on failure.
+ * Sets errno on error.
*/
BUF *
rcs_buf_load(const char *path, u_int flags)
@@ -93,28 +94,45 @@ rcs_buf_load(const char *path, u_int flags)
struct stat st;
BUF *buf;
- if ((fd = open(path, O_RDONLY, 0600)) == -1) {
- warn("%s", path);
- return (NULL);
- }
+ buf = NULL;
+
+ if ((fd = open(path, O_RDONLY, 0600)) == -1)
+ goto out;
if (fstat(fd, &st) == -1)
- err(1, "%s", path);
+ goto out;
- buf = rcs_buf_alloc((size_t)st.st_size, flags);
+ if (st.st_size > SIZE_MAX) {
+ errno = EFBIG;
+ goto out;
+ }
+ buf = rcs_buf_alloc(st.st_size, flags);
for (bp = buf->cb_cur; ; bp += (size_t)ret) {
len = SIZE_LEFT(buf);
ret = read(fd, bp, len);
if (ret == -1) {
+ int saved_errno;
+
+ saved_errno = errno;
rcs_buf_free(buf);
- err(1, "rcs_buf_load");
+ buf = NULL;
+ errno = saved_errno;
+ goto out;
} else if (ret == 0)
break;
buf->cb_len += (size_t)ret;
}
- (void)close(fd);
+out:
+ if (fd != -1) {
+ int saved_errno;
+
+ /* We may want to preserve errno here. */
+ saved_errno = errno;
+ (void)close(fd);
+ errno = saved_errno;
+ }
return (buf);
}