summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in4
-rw-r--r--src/common/compat.c60
-rw-r--r--src/common/compat.h3
3 files changed, 65 insertions, 2 deletions
diff --git a/configure.in b/configure.in
index 23d535fd63..57f67d66d8 100644
--- a/configure.in
+++ b/configure.in
@@ -345,9 +345,9 @@ AC_CHECK_HEADERS(zlib.h, , AC_MSG_ERROR(Zlib header (zlib.h) not found. Tor requ
dnl These headers are not essential
-AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h syslog.h sys/time.h sys/resource.h stddef.h inttypes.h utime.h sys/utime.h)
+AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h syslog.h sys/time.h sys/resource.h stddef.h inttypes.h utime.h sys/utime.h sys/mman.h)
-AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit setrlimit strlcat strlcpy strtoull getpwnam getpwuid ftello getaddrinfo localtime_r gmtime_r event_get_version event_get_method event_set_log_callback memmem)
+AC_CHECK_FUNCS(gettimeofday ftime socketpair uname inet_aton strptime getrlimit setrlimit strlcat strlcpy strtoull getpwnam getpwuid ftello getaddrinfo localtime_r gmtime_r event_get_version event_get_method event_set_log_callback memmem mmap)
if test $enable_threads = "yes"; then
AC_CHECK_HEADERS(pthread.h)
diff --git a/src/common/compat.c b/src/common/compat.c
index 3d70045eb5..c3e42dbc20 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -87,6 +87,9 @@ const char compat_c_id[] =
#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
#include "log.h"
#include "util.h"
@@ -104,6 +107,63 @@ const char compat_c_id[] =
#define INADDR_NONE ((unsigned long) -1)
#endif
+#ifdef HAVE_SYS_MMAP
+const char *
+tor_mmap_file(const char *filename, size_t *size)
+{
+ int fd; /* router file */
+ char *string;
+ int page_size;
+
+ tor_assert(filename);
+ tor_assert(size);
+
+ fd = open(filename, O_RDONLY, 0);
+ if (fd<0) {
+ log_warn(LD_FS,"Could not open \"%s\" for mmap().",filename);
+ return NULL;
+ }
+
+ *size = lseek(fd, 0, SEEK_END);
+ lseek(fd, 0, SEEK_SET);
+ /* ensure page alignment */
+ page_size = getpagesize();
+ *size += (page_size + (page_size-(*size%page_size)));
+
+ string = mmap(0, *size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if(string == MAP_FAILED) {
+ log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename,
+ strerror(errno));
+ return NULL;
+ }
+
+ close(fd);
+
+ return string;
+}
+
+void
+tor_munmap_file(const char *memory, size_t size)
+{
+ munmap((char*)memory, size);
+}
+#else
+const char *
+tor_mmap_file(const char *filename, size_t *size)
+{
+ char *res = read_file_to_str(filename, 1);
+ *size = strlen(res) + 1;
+ return res;
+}
+
+void
+tor_munmap_file(const char *memory, size_t size)
+{
+ char *mem = (char*) memory;
+ tor_free(mem);
+}
+#endif
+
/** Replacement for snprintf. Differs from platform snprintf in two
* ways: First, always NUL-terminates its output. Second, always
* returns -1 if the result is truncated. (Note that this return
diff --git a/src/common/compat.h b/src/common/compat.h
index 25876ef18d..43199d9302 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -101,6 +101,9 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
#define U64_LITERAL(n) (n ## llu)
#endif
+const char *tor_mmap_file(const char *filename, size_t *size);
+void tor_munmap_file(const char *memory, size_t size);
+
int tor_snprintf(char *str, size_t size, const char *format, ...)
CHECK_PRINTF(3,4);
int tor_vsnprintf(char *str, size_t size, const char *format, va_list args);