#include "wimlib/paths.h"
#include "wimlib/reparse.h"
#include "wimlib/resource.h"
-#include "wimlib/swm.h"
#include "wimlib/timestamp.h"
#include "wimlib/version.h"
#include "wimlib/write.h"
struct wimfs_fd {
struct wim_inode *f_inode;
struct wim_lookup_table_entry *f_lte;
- int staging_fd;
+ struct filedes staging_fd;
u16 idx;
u32 stream_id;
};
/* Name and message queue descriptors for message queues between the
* filesystem daemon process and the unmount process. These are used
* when the filesystem is unmounted and the process running
- * wimlib_unmount_image() (i.e. the `imagex unmount' command) needs to
- * communicate with the filesystem daemon running fuse_main() (i.e. the
- * daemon created by the `imagex mount' or `imagex mountrw' commands */
+ * wimlib_unmount_image() needs to communicate with the filesystem
+ * daemon running fuse_main() (i.e. the process created by a call to
+ * wimlib_mount_image(). */
char *unmount_to_daemon_mq_name;
char *daemon_to_unmount_mq_name;
mqd_t unmount_to_daemon_mq;
ret = -ENOMEM;
break;
}
- fd->f_inode = inode;
- fd->f_lte = lte;
- fd->staging_fd = -1;
- fd->idx = i;
- fd->stream_id = stream_id;
- *fd_ret = fd;
- inode->i_fds[i] = fd;
+ fd->f_inode = inode;
+ fd->f_lte = lte;
+ filedes_invalidate(&fd->staging_fd);
+ fd->idx = i;
+ fd->stream_id = stream_id;
+ *fd_ret = fd;
+ inode->i_fds[i] = fd;
inode->i_num_opened_fds++;
if (lte && !readonly)
lte->num_opened_fds++;
/* Close staging file descriptor if needed. */
if (lte->resource_location == RESOURCE_IN_STAGING_FILE
- && fd->staging_fd != -1)
+ && filedes_valid(&fd->staging_fd))
{
- if (close(fd->staging_fd) != 0) {
+ if (filedes_close(&fd->staging_fd)) {
ERROR_WITH_ERRNO("Failed to close staging file");
return -errno;
}
static const size_t STAGING_FILE_NAME_LEN = 20;
name_len = ctx->staging_dir_name_len + 1 + STAGING_FILE_NAME_LEN;
- name = MALLOC(name_len + 1);
+ name = MALLOC(name_len + 1);
if (!name) {
errno = ENOMEM;
return -1;
/* Extract the stream to the staging file (possibly truncated) */
if (old_lte) {
+ struct filedes wimlib_fd;
+ filedes_init(&wimlib_fd, fd);
extract_size = min(wim_resource_size(old_lte), size);
- ret = extract_wim_resource_to_fd(old_lte, fd, extract_size);
+ ret = extract_wim_resource_to_fd(old_lte, &wimlib_fd,
+ extract_size);
} else {
ret = 0;
extract_size = 0;
struct wimfs_fd *fd = inode->i_fds[i];
if (fd) {
if (fd->stream_id == stream_id) {
+ int raw_fd;
+
wimlib_assert(fd->f_lte == old_lte);
- wimlib_assert(fd->staging_fd == -1);
+ wimlib_assert(!filedes_valid(&fd->staging_fd));
fd->f_lte = new_lte;
new_lte->num_opened_fds++;
- fd->staging_fd = open(staging_file_name, O_RDONLY);
- if (fd->staging_fd == -1) {
+ raw_fd = open(staging_file_name, O_RDONLY);
+ if (raw_fd < 0) {
ret = -errno;
goto out_revert_fd_changes;
}
+ filedes_init(&fd->staging_fd, raw_fd);
}
j++;
}
struct wimfs_fd *fd = inode->i_fds[i];
if (fd && fd->stream_id == stream_id && fd->f_lte == new_lte) {
fd->f_lte = old_lte;
- if (fd->staging_fd != -1) {
- close(fd->staging_fd);
- fd->staging_fd = -1;
+ if (filedes_valid(&fd->staging_fd)) {
+ filedes_close(&fd->staging_fd);
+ filedes_invalidate(&fd->staging_fd);
}
j++;
}
char *p;
int ret;
- dir_path = realpath(mount_dir, NULL);
+ dir_path = realpath(mount_dir, NULL);
if (!dir_path) {
ERROR_WITH_ERRNO("Failed to resolve path \"%s\"", mount_dir);
if (errno == ENOMEM)
if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
return -EPERM;
- ret = lookup_resource(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
- &dentry, NULL, NULL);
+ ret = wim_pathname_to_stream(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
+ &dentry, NULL, NULL);
if (ret)
return ret;
if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
return -EPERM;
- ret = lookup_resource(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
- &dentry, NULL, NULL);
+ ret = wim_pathname_to_stream(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
+ &dentry, NULL, NULL);
if (ret)
return ret;
wimfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi)
{
struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh;
- int ret = ftruncate(fd->staging_fd, size);
+ int ret = ftruncate(fd->staging_fd.fd, size);
if (ret)
return -errno;
touch_inode(fd->f_inode);
int ret;
struct wimfs_context *ctx = wimfs_get_context();
- ret = lookup_resource(ctx->wim, path,
- get_lookup_flags(ctx) | LOOKUP_FLAG_DIRECTORY_OK,
- &dentry, <e, NULL);
+ ret = wim_pathname_to_stream(ctx->wim, path,
+ get_lookup_flags(ctx) |
+ LOOKUP_FLAG_DIRECTORY_OK,
+ &dentry, <e, NULL);
if (ret != 0)
return ret;
return inode_to_stbuf(dentry->d_inode, lte, stbuf);
return -ERANGE;
ret = read_full_resource_into_buf(lte, value);
- if (ret)
- return -EIO;
-
+ if (ret) {
+ if (errno)
+ return -errno;
+ else
+ return -EIO;
+ }
return res_size;
}
#endif
struct wimfs_context *ctx = wimfs_get_context();
struct wim_lookup_table_entry **back_ptr;
- ret = lookup_resource(ctx->wim, path, get_lookup_flags(ctx),
- &dentry, <e, &stream_idx);
+ ret = wim_pathname_to_stream(ctx->wim, path, get_lookup_flags(ctx),
+ &dentry, <e, &stream_idx);
if (ret)
return ret;
return ret;
if (lte && lte->resource_location == RESOURCE_IN_STAGING_FILE) {
- fd->staging_fd = open(lte->staging_file_name, fi->flags);
- if (fd->staging_fd == -1) {
+ int raw_fd;
+
+ raw_fd = open(lte->staging_file_name, fi->flags);
+ if (raw_fd < 0) {
int errno_save = errno;
close_wimfs_fd(fd);
return -errno_save;
}
+ filedes_init(&fd->staging_fd, raw_fd);
}
fi->fh = (uintptr_t)fd;
return 0;
switch (fd->f_lte->resource_location) {
case RESOURCE_IN_STAGING_FILE:
- ret = full_pread(fd->staging_fd, buf, size, offset);
- if (ret != size)
+ ret = raw_pread(&fd->staging_fd, buf, size, offset);
+ if (ret == -1)
ret = -errno;
break;
case RESOURCE_IN_WIM:
return -EINVAL;
if (buf_len == 0)
return -ENAMETOOLONG;
- ret = wim_inode_readlink(inode, buf, buf_len - 1);
+ ret = wim_inode_readlink(inode, buf, buf_len - 1, NULL);
if (ret >= 0) {
wimlib_assert(ret <= buf_len - 1);
buf[ret] = '\0';
struct wim_inode *inode;
struct wimfs_context *ctx = wimfs_get_context();
- ret = lookup_resource(ctx->wim, path, get_lookup_flags(ctx),
- &dentry, <e, &stream_idx);
+ ret = wim_pathname_to_stream(ctx->wim, path, get_lookup_flags(ctx),
+ &dentry, <e, &stream_idx);
if (ret != 0)
return ret;
if (lte == NULL && size == 0)
return 0;
- if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
+ if (lte != NULL && lte->resource_location == RESOURCE_IN_STAGING_FILE) {
ret = truncate(lte->staging_file_name, size);
if (ret)
ret = -errno;
u16 stream_idx;
struct wimfs_context *ctx = wimfs_get_context();
- ret = lookup_resource(ctx->wim, path, get_lookup_flags(ctx),
- &dentry, <e, &stream_idx);
+ ret = wim_pathname_to_stream(ctx->wim, path, get_lookup_flags(ctx),
+ &dentry, <e, &stream_idx);
if (ret != 0)
return ret;
struct wim_inode *inode;
WIMStruct *wim = wimfs_get_WIMStruct();
- dentry = get_dentry(wim, path);
+ dentry = get_dentry(wim, path);
if (!dentry)
return -errno;
inode = dentry->d_inode;
struct wim_inode *inode;
WIMStruct *wim = wimfs_get_WIMStruct();
- dentry = get_dentry(wim, path);
+ dentry = get_dentry(wim, path);
if (!dentry)
return -errno;
inode = dentry->d_inode;
wimlib_assert(fd->f_lte != NULL);
wimlib_assert(fd->f_lte->staging_file_name != NULL);
- wimlib_assert(fd->staging_fd != -1);
+ wimlib_assert(filedes_valid(&fd->staging_fd));
wimlib_assert(fd->f_inode != NULL);
/* Write the data. */
- ret = full_pwrite(fd->staging_fd, buf, size, offset);
- if (ret != size)
+ ret = raw_pwrite(&fd->staging_fd, buf, size, offset);
+ if (ret == -1)
return -errno;
/* Update file size */
};
-/* Mounts an image from a WIM file. */
+/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
- int mount_flags, WIMStruct **additional_swms,
- unsigned num_additional_swms,
- const char *staging_dir)
+ int mount_flags, const char *staging_dir)
{
int argc;
char *argv[16];
DEBUG("Mount: wim = %p, image = %d, dir = %s, flags = %d, ",
wim, image, dir, mount_flags);
- if (!wim || !dir) {
- ret = WIMLIB_ERR_INVALID_PARAM;
- goto out;
- }
-
- ret = verify_swm_set(wim, additional_swms, num_additional_swms);
- if (ret)
- goto out;
+ if (!wim || !dir)
+ return WIMLIB_ERR_INVALID_PARAM;
if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
ret = can_delete_from_wim(wim);
if (ret)
- goto out;
+ return ret;
}
- if (num_additional_swms)
- merge_lookup_tables(wim, additional_swms, num_additional_swms);
-
ret = select_wim_image(wim, image);
if (ret)
- goto out_restore_lookup_table;
+ return ret;
DEBUG("Selected image %d", image);
if (imd->refcnt != 1) {
ERROR("Cannot mount image that was just exported with "
"wimlib_export_image()");
- ret = WIMLIB_ERR_INVALID_PARAM;
- goto out_restore_lookup_table;
+ return WIMLIB_ERR_INVALID_PARAM;
}
if (imd->modified) {
ERROR("Cannot mount image that was added "
"with wimlib_add_image()");
- ret = WIMLIB_ERR_INVALID_PARAM;
- goto out_restore_lookup_table;
+ return WIMLIB_ERR_INVALID_PARAM;
}
if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
- ret = lock_wim(wim, wim->in_fd);
+ ret = lock_wim(wim, wim->in_fd.fd);
if (ret)
- goto out_restore_lookup_table;
+ return ret;
}
/* Use default stream interface if one was not specified */
goto out_free_message_queue_names;
argc = 0;
- argv[argc++] = IMAGEX_PROGNAME;
+ argv[argc++] = "wimlib";
argv[argc++] = dir_copy;
/* disable multi-threaded operation */
wim->wim_locked = 0;
out_free_message_queue_names:
free_message_queue_names(&ctx);
-out_restore_lookup_table:
- if (num_additional_swms)
- unmerge_lookup_table(wim);
-out:
return ret;
}
-/*
- * Unmounts the WIM file that was previously mounted on @dir by using
- * wimlib_mount_image().
- */
+/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_unmount_image(const char *dir, int unmount_flags,
wimlib_progress_func_t progress_func)
WIMLIBAPI int
wimlib_mount_image(WIMStruct *wim, int image, const tchar *dir,
- int mount_flags, WIMStruct **additional_swms,
- unsigned num_additional_swms,
- const tchar *staging_dir)
+ int mount_flags, const tchar *staging_dir)
{
return mount_unsupported_error();
}