]> granicus.if.org Git - libevent/commitdiff
Refactor code from evdns into a new internal "read a file" function.
authorNick Mathewson <nickm@torproject.org>
Mon, 7 Dec 2009 22:21:13 +0000 (17:21 -0500)
committerNick Mathewson <nickm@torproject.org>
Sat, 9 Jan 2010 00:36:35 +0000 (19:36 -0500)
evutil.c
util-internal.h

index 8caf28252627815274dd1928c704e8b81a110c58..bfe554ed493439fdc40841f21bc1233e0d6c40d3 100644 (file)
--- 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"
 #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])
 {
index af68a9e31199c25f7532d2c6a4fd178c3b6853a6..cd4afd195fa4136e85a0cb04c404bff0599ca639 100644 (file)
@@ -136,6 +136,8 @@ extern const char EVUTIL_TOLOWER_TABLE[];
 #define EVUTIL_UPCAST(ptr, type, field)                                \
        ((type *)(((char*)(ptr)) - evutil_offsetof(type, field)))
 
+int evutil_read_file(const char *filename, char **content_out, size_t *len_out,
+    int is_binary);
 
 int evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen);