X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=fd.c;h=83c6cd5b4d39c77f723aef5f67553b60d6653a31;hp=10a3cf608cfbc1f5c9818f38ecc69495e041fbab;hb=97f53e18953fc2013c0b14f0261ac385e45b0284;hpb=941a6eda36695c14848df25a48281aa9f20841a0 diff --git a/fd.c b/fd.c index 10a3cf60..83c6cd5b 100644 --- a/fd.c +++ b/fd.c @@ -243,7 +243,6 @@ int para_opendir(const char *dirname, DIR **dir, int *cwd) return 1; ret = -ERRNO_TO_PARA_ERROR(errno); /* Ignore return value of fchdir() and close(). We're busted anyway. */ -change_to_orig_dir: if (cwd) fchdir(*cwd); close_cwd: @@ -280,3 +279,56 @@ int para_mkdir(const char *path, mode_t mode) return 1; return -ERRNO_TO_PARA_ERROR(errno); } + +/** + * Map a file into memory. + * + * \param path Name of the regular file to map. + * \param open_mode Either \p O_RDONLY or \p O_RDWR. + * \param obj On success, the mapping is returned here. + * + * \return Positive on success, negative on errors. Possible errors include: \p + * E_FSTAT, any errors returned by para_open(), \p E_EMPTY, \p E_MMAP. + * + * \sa para_open(), mmap(2). + */ +int mmap_full_file(const char *path, int open_mode, void **map, + size_t *size, int *fd_ptr) +{ + int fd, ret, mmap_prot, mmap_flags; + struct stat file_status; + + if (open_mode == O_RDONLY) { + mmap_prot = PROT_READ; + mmap_flags = MAP_PRIVATE; + } else { + mmap_prot = PROT_READ | PROT_WRITE; + mmap_flags = MAP_SHARED; + } + ret = para_open(path, open_mode, 0); + if (ret < 0) + return ret; + fd = ret; + if (fstat(fd, &file_status) < 0) { + ret = -ERRNO_TO_PARA_ERROR(errno); + goto out; + } + *size = file_status.st_size; + ret = -E_EMPTY; + PARA_DEBUG_LOG("%s: size %zu\n", path, *size); + if (!*size) + goto out; + *map = mmap(NULL, *size, mmap_prot, mmap_flags, fd, 0); + if (*map == MAP_FAILED) { + *map = NULL; + ret = -E_MMAP; + goto out; + } + ret = 1; +out: + if (ret < 0 || !fd_ptr) + close(fd); + else + *fd_ptr = fd; + return ret; +}