/*
- * Copyright (C) 2006-2008 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2006-2008 Andre Noll <maan@tuebingen.mpg.de>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
#include <sys/types.h>
#include <dirent.h>
#include <sys/mman.h>
+#include <string.h>
#include "adu.h"
#include "error.h"
+#include "string.h"
+#include "fd.h"
/**
* Wrapper for the write system call.
* \param size The length of \a buf in bytes.
*
* This function writes out the given buffer and retries if an interrupt
- * occurred during the write.
+ * occurred during the write. The file descriptor is assumed to be in blocking
+ * mode (i.e., EAGAIN is treated as an error).
*
* \return Standard.
*
* \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;
for (;;) {
ret = write(fd, buf, size);
- if ((ret < 0) && (errno == EAGAIN || errno == EINTR))
+ if (ret < 0 && errno == EINTR)
continue;
return ret >= 0? ret : -ERRNO_TO_ERROR(errno);
}
*
* \return Standard.
*/
-int __chdir(const char *path)
+static int __chdir(const char *path)
{
int ret = chdir(path);
}
/**
- * 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;
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;
}
ret = 1;
out:
- if (ret < 0 || !fd_ptr)
- close(fd);
- else
- *fd_ptr = fd;
+ close(fd);
return ret;
}
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;
+}