Skip to content

Instantly share code, notes, and snippets.

@andyvand
Created December 13, 2025 15:13
Show Gist options
  • Select an option

  • Save andyvand/7d6d1f9aee2a7f68545604c56042a9fc to your computer and use it in GitHub Desktop.

Select an option

Save andyvand/7d6d1f9aee2a7f68545604c56042a9fc to your computer and use it in GitHub Desktop.
wimlib 1.14.4 for macOS
diff -Nur wimlib-1.14.4/src/mount_image.c wimlib-1.14.4-macOS/src/mount_image.c
--- wimlib-1.14.4/src/mount_image.c 2023-07-23 01:55:59
+++ wimlib-1.14.4-macOS/src/mount_image.c 2025-12-13 14:59:37
@@ -45,7 +45,11 @@
#include <errno.h>
#include <fuse.h>
#include <limits.h>
+
+#ifndef __APPLE__
#include <mqueue.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -1104,6 +1108,7 @@
commit_progress_func(enum wimlib_progress_msg msg,
union wimlib_progress_info *info, void *progctx)
{
+#ifndef __APPLE__
mqd_t mq = *(mqd_t *)progctx;
struct commit_progress_report report;
@@ -1112,10 +1117,13 @@
if (info)
report.info = *info;
mq_send(mq, (const char *)&report, sizeof(report), 1);
+#endif
+
return WIMLIB_PROGRESS_STATUS_CONTINUE;
}
/* Commit the mounted image to the underlying WIM file. */
+#ifndef __APPLE__
static int
commit_image(struct wimfs_context *ctx, int unmount_flags, mqd_t mq)
{
@@ -1147,7 +1155,34 @@
return wimlib_overwrite(ctx->wim, write_flags, 0);
}
+#else
+static int
+commit_image(struct wimfs_context *ctx, int unmount_flags)
+{
+ int write_flags;
+ if (unmount_flags & WIMLIB_UNMOUNT_FLAG_NEW_IMAGE) {
+ int ret = renew_current_image(ctx);
+ if (ret)
+ return ret;
+ }
+ delete_empty_blobs(ctx);
+
+ write_flags = 0;
+
+ if (unmount_flags & WIMLIB_UNMOUNT_FLAG_CHECK_INTEGRITY)
+ write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;
+
+ if (unmount_flags & WIMLIB_UNMOUNT_FLAG_REBUILD)
+ write_flags |= WIMLIB_WRITE_FLAG_REBUILD;
+
+ if (unmount_flags & WIMLIB_UNMOUNT_FLAG_RECOMPRESS)
+ write_flags |= WIMLIB_WRITE_FLAG_RECOMPRESS;
+
+ return wimlib_overwrite(ctx->wim, write_flags, 0);
+}
+#endif
+
/* In the case of an allow_other mount, only the mount owner and root are
* allowed to unmount the filesystem. */
static bool
@@ -1168,13 +1203,16 @@
struct wimfs_context *wimfs_ctx = WIMFS_CTX(fuse_ctx);
const struct wimfs_unmount_info *info = &wimfs_ctx->unmount_info;
int unmount_flags = info->unmount_flags;
- mqd_t mq = (mqd_t)-1;
+#ifndef __APPLE__
+ mqd_t mq = (mqd_t)-1;
+#endif
int ret;
/* Ignore COMMIT if the image is mounted read-only. */
if (!(wimfs_ctx->mount_flags & WIMLIB_MOUNT_FLAG_READWRITE))
unmount_flags &= ~WIMLIB_UNMOUNT_FLAG_COMMIT;
+#ifndef __APPLE__
if (unmount_flags & WIMLIB_UNMOUNT_FLAG_SEND_PROGRESS) {
mq = mq_open(info->mq_name, O_WRONLY | O_NONBLOCK);
if (mq == (mqd_t)-1) {
@@ -1182,6 +1220,7 @@
goto out;
}
}
+#endif
if (wimfs_ctx->num_open_fds) {
@@ -1202,7 +1241,11 @@
}
if (unmount_flags & WIMLIB_UNMOUNT_FLAG_COMMIT)
+#ifdef __APPLE__
+ ret = commit_image(wimfs_ctx, unmount_flags);
+#else
ret = commit_image(wimfs_ctx, unmount_flags, mq);
+#endif
else
ret = 0; /* Read-only mount, or discarding changes to
a read-write mount */
@@ -1215,14 +1258,24 @@
unlock_wim_for_append(wimfs_ctx->wim);
fuse_exit(fuse_ctx->fuse);
}
- if (mq != (mqd_t)-1)
+
+#ifndef __APPLE__
+ if (mq != (mqd_t)-1)
mq_close(mq);
+#endif
+
return ret;
}
+#ifdef __APPLE__
static void *
+wimfs_init(struct fuse_conn_info *conn)
+#else
+static void *
wimfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
+#endif
{
+#ifndef __APPLE__
/*
* Cache positive name lookups indefinitely, since names can only be
* added, removed, or modified through the mounted filesystem itself.
@@ -1274,12 +1327,18 @@
* read().
*/
cfg->nullpath_ok = 1;
+#endif
return wimfs_get_context();
}
+#ifdef __APPLE__
static int
+wimfs_chmod(const char *path, mode_t mask)
+#else
+static int
wimfs_chmod(const char *path, mode_t mask, struct fuse_file_info *fi)
+#endif
{
const struct wimfs_context *ctx = wimfs_get_context();
struct wim_inode *inode;
@@ -1288,13 +1347,18 @@
if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
return -EOPNOTSUPP;
+#ifndef __APPLE__
if (fi) {
inode = WIMFS_FD(fi)->f_inode;
} else {
+#endif
inode = wim_pathname_to_inode(ctx->wim, path);
if (!inode)
return -errno;
+#ifndef __APPLE__
}
+#endif
+
unix_data.uid = ctx->owner_uid;
unix_data.gid = ctx->owner_gid;
unix_data.mode = mask;
@@ -1306,8 +1370,13 @@
return 0;
}
+#ifdef __APPLE__
static int
+wimfs_chown(const char *path, uid_t uid, gid_t gid)
+#else
+static int
wimfs_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi)
+#endif
{
const struct wimfs_context *ctx = wimfs_get_context();
struct wim_inode *inode;
@@ -1317,13 +1386,17 @@
if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
return -EOPNOTSUPP;
+#ifndef __APPLE__
if (fi) {
inode = WIMFS_FD(fi)->f_inode;
} else {
+#endif
inode = wim_pathname_to_inode(ctx->wim, path);
if (!inode)
return -errno;
+#ifndef __APPLE__
}
+#endif
which = 0;
@@ -1348,20 +1421,27 @@
return 0;
}
+#ifdef __APPLE__
static int
+wimfs_getattr(const char *path, struct stat *stbuf)
+#else
+static int
wimfs_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
+#endif
{
const struct wimfs_context *ctx = wimfs_get_context();
const struct wim_inode *inode;
const struct blob_descriptor *blob;
int ret;
+#ifndef __APPLE__
if (fi) {
const struct wimfs_fd *fd = WIMFS_FD(fi);
inode = fd->f_inode;
blob = fd->f_blob;
} else {
+#endif
struct wim_dentry *dentry;
struct wim_inode_stream *strm;
@@ -1372,7 +1452,9 @@
return ret;
inode = dentry->d_inode;
blob = stream_blob_resolved(strm);
+#ifndef __APPLE__
}
+#endif
return inode_to_stbuf(inode, blob, stbuf);
}
@@ -1388,9 +1470,15 @@
return srcsize;
}
+#ifdef __APPLE__
static int
wimfs_getxattr(const char *path, const char *name, char *value,
+ size_t size, uint32_t unused)
+#else
+static int
+wimfs_getxattr(const char *path, const char *name, char *value,
size_t size)
+#endif
{
const struct wimfs_context *ctx = wimfs_get_context();
const struct wim_inode *inode;
@@ -1687,17 +1775,25 @@
int raw_fd;
raw_fd = openat(blob->staging_dir_fd, blob->staging_file_name,
- (fi->flags & (O_ACCMODE | O_TRUNC)) |
+#ifndef __APPLE__
+ (fi->flags & (O_ACCMODE | O_TRUNC)) |
+#else
+ O_RDWR | O_TRUNC |
+#endif
O_NOFOLLOW);
if (raw_fd < 0) {
close_wimfs_fd(fd);
return -errno;
}
filedes_init(&fd->f_staging_fd, raw_fd);
+#ifndef __APPLE__
if (fi->flags & O_TRUNC) {
+#endif
blob->size = 0;
file_contents_changed(inode);
+#ifndef __APPLE__
}
+#endif
}
fi->fh = (uintptr_t)fd;
return 0;
@@ -1771,22 +1867,37 @@
return ret;
}
+#ifdef __APPLE__
static int
wimfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
+ off_t offset, struct fuse_file_info *fi)
+#else
+static int
+wimfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
+#endif
{
struct wimfs_fd *fd = WIMFS_FD(fi);
+
const struct wim_inode *inode;
const struct wim_dentry *child;
int ret;
inode = fd->f_inode;
+#ifdef __APPLE__
+ ret = filler(buf, ".", NULL, 0);
+ if (ret)
+ return ret;
+ ret = filler(buf, "..", NULL, 0);
+#else
ret = filler(buf, ".", NULL, 0, 0);
if (ret)
return ret;
ret = filler(buf, "..", NULL, 0, 0);
+#endif
+
if (ret)
return ret;
@@ -1798,8 +1909,14 @@
&name, &name_nbytes))
return -errno;
+#ifdef __APPLE__
+ ret = filler(buf, name, NULL, 0);
+#else
ret = filler(buf, name, NULL, 0, 0);
+#endif
+
FREE(name);
+
if (ret)
return ret;
}
@@ -1829,6 +1946,7 @@
/* We use this for both release() and releasedir(), since in both cases we
* simply need to close the file descriptor. */
+
static int
wimfs_release(const char *path, struct fuse_file_info *fi)
{
@@ -1866,14 +1984,25 @@
return 0;
}
+#ifdef __APPLE__
static int
+wimfs_rename(const char *from, const char *to)
+#else
+static int
wimfs_rename(const char *from, const char *to, unsigned int flags)
+#endif
{
+#ifndef __APPLE__
if (flags & RENAME_EXCHANGE)
return -EINVAL;
+#endif
return rename_wim_path(wimfs_get_WIMStruct(), from, to,
WIMLIB_CASE_SENSITIVE,
+#ifndef __APPLE__
(flags & RENAME_NOREPLACE), NULL);
+#else
+ 0, NULL);
+#endif
}
static int
@@ -1897,9 +2026,15 @@
return 0;
}
+#ifdef __APPLE__
static int
wimfs_setxattr(const char *path, const char *name,
+ const char *value, size_t size, int flags, uint32_t unused)
+#else
+static int
+wimfs_setxattr(const char *path, const char *name,
const char *value, size_t size, int flags)
+#endif
{
struct wimfs_context *ctx = wimfs_get_context();
struct wim_inode *inode;
@@ -2014,8 +2149,13 @@
return 0;
}
+#ifdef __APPLE__
static int
+wimfs_truncate(const char *path, off_t size)
+#else
+static int
wimfs_truncate(const char *path, off_t size, struct fuse_file_info *fi)
+#endif
{
const struct wimfs_context *ctx = wimfs_get_context();
struct wim_dentry *dentry;
@@ -2024,12 +2164,14 @@
int ret;
int staging_fd;
+#ifndef __APPLE__
if (fi) {
struct wimfs_fd *fd = WIMFS_FD(fi);
return do_truncate(fd->f_staging_fd.fd, size, fd->f_inode,
fd->f_blob);
}
+#endif
ret = wim_pathname_to_stream(ctx, path, 0, &dentry, &strm);
if (ret)
@@ -2083,19 +2225,28 @@
*
* Note that alternate data streams do not have their own timestamps.
*/
+#ifdef __APPLE__
static int
+wimfs_utimens(const char *path, const struct timespec tv[2])
+#else
+static int
wimfs_utimens(const char *path, const struct timespec tv[2],
struct fuse_file_info *fi)
+#endif
{
struct wim_inode *inode;
+#ifndef __APPLE__
if (fi) {
inode = WIMFS_FD(fi)->f_inode;
} else {
+#endif
inode = wim_pathname_to_inode(wimfs_get_WIMStruct(), path);
if (!inode)
return -errno;
+#ifndef __APPLE__
}
+#endif
if (tv[0].tv_nsec != UTIME_OMIT) {
if (tv[0].tv_nsec == UTIME_NOW)
@@ -2127,6 +2278,7 @@
fd->f_blob->size = offset + size;
file_contents_changed(fd->f_inode);
+
return ret;
}
@@ -2306,6 +2458,7 @@
return ret;
}
+#ifndef __APPLE__
struct commit_progress_thread_args {
mqd_t mq;
wimlib_progress_func_t progfunc;
@@ -2370,6 +2523,7 @@
umask(umask_save);
return mq;
}
+#endif
/* Unmount a read-only or read-write mounted WIM image. */
static int
@@ -2378,7 +2532,12 @@
int status;
ssize_t len;
+#ifdef __APPLE__
+ len = getxattr(dir, "wimfs.unmount", &status, sizeof(int), 0, 0);
+#else
len = getxattr(dir, "wimfs.unmount", &status, sizeof(int));
+#endif
+
if (len == sizeof(int))
return status;
else if (len < 0 && (errno == EACCES || errno == EPERM))
@@ -2390,8 +2549,13 @@
static int
set_unmount_info(const char *dir, const struct wimfs_unmount_info *unmount_info)
{
+#ifdef __APPLE__
+ if (!setxattr(dir, "wimfs.unmount_info",
+ unmount_info, sizeof(struct wimfs_unmount_info), 0, 0))
+#else
if (!setxattr(dir, "wimfs.unmount_info",
unmount_info, sizeof(struct wimfs_unmount_info), 0))
+#endif
return 0;
else if (errno == EROFS)
return 0;
@@ -2421,14 +2585,17 @@
wimlib_progress_func_t progfunc, void *progctx)
{
struct wimfs_unmount_info unmount_info;
- mqd_t mq = (mqd_t)-1;
+#ifndef __APPLE__
+ mqd_t mq = (mqd_t)-1;
struct commit_progress_thread_args args;
+#endif
struct thread commit_progress_tid;
int ret;
memset(&unmount_info, 0, sizeof(unmount_info));
unmount_info.unmount_flags = unmount_flags;
+#ifndef __APPLE__
/* The current thread will be stuck in getxattr() until the image is
* committed. Create a thread to handle the progress messages. */
if (progfunc) {
@@ -2449,21 +2616,27 @@
}
unmount_info.unmount_flags |= WIMLIB_UNMOUNT_FLAG_SEND_PROGRESS;
}
+#endif
ret = set_unmount_info(dir, &unmount_info);
if (!ret)
ret = do_unmount(dir);
+#ifndef __APPLE__
if (progfunc) {
/* Terminate the progress thread. */
char empty[1];
mq_send(mq, empty, 0, 1);
thread_join(&commit_progress_tid);
}
+#endif
out_delete_mq:
+#ifndef __APPLE__
if (progfunc) {
mq_close(mq);
mq_unlink(unmount_info.mq_name);
}
+#endif
+
return ret;
}
@@ -2476,8 +2649,14 @@
int wim_filename_len;
union wimlib_progress_info progress;
- if (getxattr(dir, "wimfs.mount_flags",
- &mount_flags, sizeof(int)) != sizeof(int))
+#ifdef __APPLE__
+ if (getxattr(dir, "wimfs.mount_flags",
+ &mount_flags, sizeof(int), 0, 0) != sizeof(int))
+#else
+ if (getxattr(dir, "wimfs.mount_flags",
+ &mount_flags, sizeof(int)) != sizeof(int))
+#endif
+
return WIMLIB_ERR_NOT_A_MOUNTPOINT;
*mount_flags_ret = mount_flags;
@@ -2485,17 +2664,32 @@
if (!progfunc)
return 0;
+#ifdef __APPLE__
+ if (getxattr(dir, "wimfs.mounted_image",
+ &mounted_image, sizeof(int), 0, 0) != sizeof(int))
+#else
if (getxattr(dir, "wimfs.mounted_image",
&mounted_image, sizeof(int)) != sizeof(int))
+#endif
return WIMLIB_ERR_NOT_A_MOUNTPOINT;
+#ifdef __APPLE__
+ wim_filename_len = getxattr(dir, "wimfs.wim_filename", NULL, 0, 0, 0);
+#else
wim_filename_len = getxattr(dir, "wimfs.wim_filename", NULL, 0);
+#endif
+
if (wim_filename_len < 0)
return WIMLIB_ERR_NOT_A_MOUNTPOINT;
char wim_filename[wim_filename_len + 1];
+#ifdef __APPLE__
+ if (getxattr(dir, "wimfs.wim_filename",
+ wim_filename, wim_filename_len, 0, 0) != wim_filename_len)
+#else
if (getxattr(dir, "wimfs.wim_filename",
wim_filename, wim_filename_len) != wim_filename_len)
+#endif
return WIMLIB_ERR_NOT_A_MOUNTPOINT;
wim_filename[wim_filename_len] = '\0';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment