Created
December 13, 2025 15:13
-
-
Save andyvand/7d6d1f9aee2a7f68545604c56042a9fc to your computer and use it in GitHub Desktop.
wimlib 1.14.4 for macOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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