diff options
Diffstat (limited to 'src-diclib/filemap.c')
-rw-r--r-- | src-diclib/filemap.c | 135 |
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); +} |