summaryrefslogtreecommitdiff
path: root/evutil.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-12-07 17:21:13 -0500
committerNick Mathewson <nickm@torproject.org>2010-01-08 19:36:35 -0500
commit0f7144fd8b05e95788ac2877caaf2b7c4688bf82 (patch)
tree624546c5f43414bde01c78f9e43730d53e0f6df8 /evutil.c
parenteaaf27f1f7b834bf60a1003c4d9c32a9a346b1dc (diff)
downloadlibevent-0f7144fd8b05e95788ac2877caaf2b7c4688bf82.tar.gz
Refactor code from evdns into a new internal "read a file" function.
Diffstat (limited to 'evutil.c')
-rw-r--r--evutil.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/evutil.c b/evutil.c
index 8caf2825..bfe554ed 100644
--- a/evutil.c
+++ b/evutil.c
@@ -67,6 +67,7 @@
#include <sys/timeb.h>
#include <time.h>
#endif
+#include <sys/stat.h>
#include "event2/util.h"
#include "util-internal.h"
@@ -76,6 +77,67 @@
#include "strlcpy-internal.h"
#include "ipv6-internal.h"
+/**
+ Read the contents of 'filename' into a newly allocated NUL-terminated
+ string. Set *content_out to hold this string, and *len_out to hold its
+ length (not including the appended NUL). If 'is_binary', open the file in
+ binary mode.
+
+ Returns 0 on success, -1 if the open fails, and -2 for all other failures.
+
+ Used internally only; may go away in a future version.
+ */
+int
+evutil_read_file(const char *filename, char **content_out, size_t *len_out,
+ int is_binary)
+{
+ int fd, r;
+ struct stat st;
+ char *mem;
+ size_t read_so_far=0;
+ int mode = O_RDONLY;
+
+ EVUTIL_ASSERT(content_out);
+ EVUTIL_ASSERT(len_out);
+ *content_out = NULL;
+ *len_out = 0;
+
+#ifdef O_BINARY
+ if (is_binary)
+ mode |= O_BINARY;
+#endif
+
+ fd = open(filename, mode);
+ if (fd < 0)
+ return -1;
+ if (fstat(fd, &st)) {
+ close(fd);
+ return -2;
+ }
+ mem = mm_malloc(st.st_size + 1);
+ if (!mem) {
+ close(fd);
+ return -2;
+ }
+ read_so_far = 0;
+ while ((r = read(fd, mem+read_so_far, st.st_size - read_so_far)) > 0) {
+ read_so_far += r;
+ if (read_so_far >= st.st_size)
+ break;
+ EVUTIL_ASSERT(read_so_far < st.st_size);
+ }
+ if (r < 0) {
+ close(fd);
+ mm_free(mem);
+ return -2;
+ }
+ mem[read_so_far] = 0;
+
+ *len_out = read_so_far;
+ *content_out = mem;
+ return 0;
+}
+
int
evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
{