aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-07-13 21:27:34 +0200
committerChristian Ruppert <idl0r@gentoo.org>2011-07-13 21:31:20 +0200
commitfdaf1c65cdcba2d9b83e02cc0d08fb6dbbd80a80 (patch)
tree6a106882bb41f58f7d6b06075569372d97c9774a
parentef22868f3668fe833cdf297e619afe5b721f7716 (diff)
Add a new function, bool rc_getfile(const char *, char **, size_t *)
<snip> Read the entire @file into the buffer and set @len to the size of the buffer when finished. For C strings, this will be strlen(buffer) + 1. Don't forget to free the buffer afterwards! </snip> We also fix bug 374899 by adding this new function. X-Gentoo-Bug: 374899 X-Gentoo-Bug-URL: http://bugs.gentoo.org/374899
-rw-r--r--src/librc/librc-misc.c48
-rw-r--r--src/librc/librc.h1
-rw-r--r--src/librc/rc.h.in3
-rw-r--r--src/librc/rc.map1
-rw-r--r--src/test/rc.funcs.list2
5 files changed, 55 insertions, 0 deletions
diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c
index 7244deef..97fa54c8 100644
--- a/src/librc/librc-misc.c
+++ b/src/librc/librc-misc.c
@@ -54,6 +54,54 @@ rc_yesno(const char *value)
}
librc_hidden_def(rc_yesno)
+
+/**
+ * Read the entire @file into the buffer and set @len to the
+ * size of the buffer when finished. For C strings, this will
+ * be strlen(buffer) + 1.
+ * Don't forget to free the buffer afterwards!
+ */
+bool
+rc_getfile(const char *file, char **buffer, size_t *len)
+{
+ bool ret = false;
+ FILE *fp;
+ int fd;
+ struct stat st;
+ size_t done, left;
+
+ fp = fopen(file, "re");
+ if (!fp)
+ return false;
+
+ /* assume fileno() never fails */
+ fd = fileno(fp);
+
+ if (fstat(fd, &st))
+ goto finished;
+
+ left = st.st_size;
+ *len = left + 1; /* NUL terminator */
+ *buffer = xrealloc(*buffer, *len);
+ while (left) {
+ done = fread(*buffer, sizeof(*buffer[0]), left, fp);
+ if (done == 0 && ferror(fp))
+ goto finished;
+ left -= done;
+ }
+ ret = true;
+
+ finished:
+ if (!ret) {
+ free(*buffer);
+ *len = 0;
+ } else
+ (*buffer)[*len - 1] = '\0';
+ fclose(fp);
+ return ret;
+}
+librc_hidden_def(rc_getfile)
+
ssize_t
rc_getline(char **line, size_t *len, FILE *fp)
{
diff --git a/src/librc/librc.h b/src/librc/librc.h
index 43b01570..876c0472 100644
--- a/src/librc/librc.h
+++ b/src/librc/librc.h
@@ -84,6 +84,7 @@ librc_hidden_proto(rc_deptree_order)
librc_hidden_proto(rc_deptree_update)
librc_hidden_proto(rc_deptree_update_needed)
librc_hidden_proto(rc_find_pids)
+librc_hidden_proto(rc_getfile)
librc_hidden_proto(rc_getline)
librc_hidden_proto(rc_newer_than)
librc_hidden_proto(rc_older_than)
diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in
index 2a7c054a..350f518e 100644
--- a/src/librc/rc.h.in
+++ b/src/librc/rc.h.in
@@ -544,6 +544,9 @@ typedef LIST_HEAD(rc_pidlist, rc_pid) RC_PIDLIST;
* @return NULL terminated list of pids */
RC_PIDLIST *rc_find_pids(const char *, const char *const *, uid_t, pid_t);
+/* Basically the same as rc_getline() below, it just returns multiple lines */
+bool rc_getfile(const char *, char **, size_t *);
+
/* getline is a handy glibc function that not all libcs have, so
* we have our own */
ssize_t rc_getline(char **, size_t *, FILE *);
diff --git a/src/librc/rc.map b/src/librc/rc.map
index c5f10ade..0f45cdfe 100644
--- a/src/librc/rc.map
+++ b/src/librc/rc.map
@@ -14,6 +14,7 @@ global:
rc_deptree_update_needed;
rc_environ_fd;
rc_find_pids;
+ rc_getfile;
rc_getline;
rc_newer_than;
rc_older_than;
diff --git a/src/test/rc.funcs.list b/src/test/rc.funcs.list
index a8b011ff..f0416b7d 100644
--- a/src/test/rc.funcs.list
+++ b/src/test/rc.funcs.list
@@ -24,6 +24,8 @@ rc_deptree_update_needed
rc_deptree_update_needed@@RC_1.0
rc_find_pids
rc_find_pids@@RC_1.0
+rc_getfile
+rc_getfile@@RC_1.0
rc_getline
rc_getline@@RC_1.0
rc_newer_than