summaryrefslogtreecommitdiffstats
path: root/src/lib/mmap-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/mmap-util.c')
-rw-r--r--src/lib/mmap-util.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/lib/mmap-util.c b/src/lib/mmap-util.c
new file mode 100644
index 0000000..8754226
--- /dev/null
+++ b/src/lib/mmap-util.c
@@ -0,0 +1,63 @@
+/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "mmap-util.h"
+
+#include <sys/stat.h>
+
+void *mmap_file(int fd, size_t *length, int prot)
+{
+ struct stat st;
+
+ if (fstat(fd, &st) < 0)
+ return MAP_FAILED;
+
+#if OFF_T_MAX > SSIZE_T_MAX
+ if (st.st_size > SSIZE_T_MAX) {
+ /* too large file to map into memory */
+ errno = EFBIG;
+ return MAP_FAILED;
+ }
+#endif
+
+ *length = (size_t)st.st_size;
+ if (*length == 0)
+ return NULL;
+
+ i_assert(*length > 0 && *length < SSIZE_T_MAX);
+
+ return mmap(NULL, *length, prot, MAP_SHARED, fd, 0);
+}
+
+void *mmap_ro_file(int fd, size_t *length)
+{
+ return mmap_file(fd, length, PROT_READ);
+}
+
+void *mmap_rw_file(int fd, size_t *length)
+{
+ return mmap_file(fd, length, PROT_READ | PROT_WRITE);
+}
+
+#undef madvise
+int my_madvise(void *start ATTR_UNUSED, size_t length ATTR_UNUSED,
+ int advice ATTR_UNUSED)
+{
+#ifdef HAVE_MADVISE
+ /* Ignore ENOSYS errors, which happen if the kernel hasn't implemented
+ the syscall even if libc has. */
+ if (madvise(start, length, advice) < 0 && errno != ENOSYS)
+ return -1;
+#endif
+ return 0;
+}
+
+size_t mmap_get_page_size(void)
+{
+ static size_t size = 0;
+
+ if (size != 0)
+ return size;
+ size = getpagesize();
+ return size;
+}