summaryrefslogtreecommitdiff
path: root/src-diclib/filemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src-diclib/filemap.c')
-rw-r--r--src-diclib/filemap.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/src-diclib/filemap.c b/src-diclib/filemap.c
new file mode 100644
index 0000000..7b3317d
--- /dev/null
+++ b/src-diclib/filemap.c
@@ -0,0 +1,135 @@
+/* mmapを抽象化する
+ *
+ * *Unix系のシステムコールをソース中に散らさないため
+ * *将来的には一つのファイルを複数の目的にmapすることも考慮
+ *
+ * Copyright (C) 2005 TABATA Yusuke
+ *
+ */
+/*
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include <anthy/filemap.h>
+#include <anthy/logger.h>
+
+struct filemapping {
+ /* 書き込みモード */
+ int wr;
+ /* mmapしたアドレス */
+ void *ptr;
+ /* mmapした領域の長さ */
+ size_t size;
+};
+
+struct filemapping *
+anthy_mmap(const char *fn, int wr)
+{
+ int fd;
+ void *ptr;
+ int r;
+ struct filemapping *m;
+ struct stat st;
+ int prot;
+ int flags;
+ mode_t mode;
+
+ if (wr) {
+ prot = PROT_READ | PROT_WRITE;
+ flags = O_RDWR;
+ mode = S_IRUSR | S_IWUSR;
+ } else {
+ prot = PROT_READ;
+ flags = O_RDONLY;
+ mode = S_IRUSR;
+ }
+
+ fd = open(fn, flags, mode);
+
+ if (fd == -1) {
+ anthy_log(0, "Failed to open (%s).\n", fn);
+ return NULL;
+ }
+
+ r = fstat(fd, &st);
+ if (r == -1) {
+ anthy_log(0, "Failed to stat() (%s).\n", fn);
+ close(fd);
+ return NULL;
+ }
+ if (st.st_size == 0) {
+ anthy_log(0, "Failed to mmap 0size file (%s).\n", fn);
+ close(fd);
+ return NULL;
+ }
+
+ ptr = mmap(NULL, st.st_size, prot, MAP_SHARED, fd, 0);
+ close(fd);
+ if (ptr == MAP_FAILED) {
+ anthy_log(0, "Failed to mmap() (%s).\n", fn);
+ return NULL;
+ }
+
+ /* mmapに成功したので情報を返す */
+ m = malloc(sizeof(struct filemapping));
+ m->size = st.st_size;
+ m->ptr = ptr;
+ m->wr = wr;
+
+ return m;
+}
+
+void *
+anthy_mmap_address(struct filemapping *m)
+{
+ if (!m) {
+ return NULL;
+ }
+ return m->ptr;
+}
+
+int
+anthy_mmap_size(struct filemapping *m)
+{
+ if (!m) {
+ return 0;
+ }
+ return m->size;
+}
+
+int
+anthy_mmap_is_writable(struct filemapping *m)
+{
+ if (!m) {
+ return 0;
+ }
+ return m->wr;
+}
+
+void
+anthy_munmap(struct filemapping *m)
+{
+ if (!m) {
+ return ;
+ }
+ munmap(m->ptr, m->size);
+ free(m);
+}