X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=blobdiff_plain;f=fd.c;h=cb6724a2c473827b36d8b3716872ebab6a0d588e;hp=e1d243e1e8f34006326bdfab72f24455ad801eff;hb=bc747651f044d98cc633da689eb4ff7a67e755ae;hpb=4e757d60f7642c61e09a20a2a1de442b23208966 diff --git a/fd.c b/fd.c index e1d243e..cb6724a 100644 --- a/fd.c +++ b/fd.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Andre Noll + * Copyright (C) 2006-2008 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -9,9 +9,12 @@ #include #include #include +#include #include "adu.h" #include "error.h" +#include "string.h" +#include "fd.h" /** * Wrapper for the write system call. @@ -27,7 +30,7 @@ * * \sa write(2). */ -ssize_t __write(int fd, const void *buf, size_t size) +static ssize_t __write(int fd, const void *buf, size_t size) { ssize_t ret; @@ -122,7 +125,7 @@ out: * * \return Standard. */ -int __chdir(const char *path) +static int __chdir(const char *path) { int ret = chdir(path); @@ -196,36 +199,25 @@ int adu_fchdir(int fd) } /** - * Open a file and map it into memory. + * Open a file read-only and map it into memory. * * \param path Name of the regular file to map. - * \param open_mode Either \p O_RDONLY or \p O_RDWR. * \param map On success, the mapping is returned here. - * \param size size of the mapping. - * \param fd_ptr The file descriptor of the mapping. + * \param size Result parameter: size of the mapping in bytes. * - * If \a fd_ptr is \p NULL, the file descriptor resulting from the underlying - * open call is closed after mmap(). Otherwise the file is kept open and the - * file descriptor is returned in \a fd_ptr. + * The file will be mapped privately with memory protection PROT_READ. The file + * descriptor resulting from the underlying open call is closed after mmap(). * * \return Standard. * * \sa mmap(2). */ -int mmap_full_file(const char *path, int open_mode, void **map, - size_t *size, int *fd_ptr) +int mmap_file_ro(const char *path, void **map, size_t *size) { - int fd, ret, mmap_prot, mmap_flags; + int fd, ret; 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 = __open(path, open_mode, 0); + ret = __open(path, O_RDONLY, 0); if (ret < 0) return ret; fd = ret; @@ -238,7 +230,7 @@ int mmap_full_file(const char *path, int open_mode, void **map, DEBUG_LOG("%s: size %zu\n", path, *size); if (!*size) goto out; - *map = mmap(NULL, *size, mmap_prot, mmap_flags, fd, 0); + *map = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0); if (*map == MAP_FAILED) { *map = NULL; ret = -E_MMAP; @@ -246,10 +238,7 @@ int mmap_full_file(const char *path, int open_mode, void **map, } ret = 1; out: - if (ret < 0 || !fd_ptr) - close(fd); - else - *fd_ptr = fd; + close(fd); return ret; } @@ -273,3 +262,54 @@ int adu_munmap(void *start, size_t length) strerror(err)); return -ERRNO_TO_ERROR(err); } + +__must_check __malloc static char *adu_dirname(const char *name) +{ + char *p, *ret; + + if (!name || !*name) + return NULL; + ret = adu_strdup(name); + p = strrchr(ret, '/'); + if (!p) + *ret = '\0'; + else + *p = '\0'; + return ret; +} + +/** + * Recursive mkdir + * + * \param p Full path that should be created. + * + * \param mode Use this mode when creating directories. + * + * \return 0 if successful, -E_MKDIR on errors. + */ +int mkpath(const char *p, mode_t mode) +{ + char *parent, *path; + int ret = -E_MKDIR; + + DEBUG_LOG("%s\n", p); + if (strcmp(p, ".") == 0 || strcmp(p, "/") == 0 || strcmp(p, "") == 0) { + DEBUG_LOG("reached beginning of path\n"); + return 0; + } + path = adu_strdup(p); + parent = adu_dirname(p); + if (!parent) + goto out; + ret = mkpath(parent, mode); + if (ret < 0) + goto out; + INFO_LOG("making dir %s\n", path); + ret = 0; + if ((mkdir(path, mode) == -1) && (errno != EEXIST)) + ret = -E_MKDIR; +out: + free(parent); + free(path); + return ret; +}