]> wimlib.net Git - wimlib/blobdiff - src/mount_image.c
Add Windows implementations of pread(), pwrite(), writev()
[wimlib] / src / mount_image.c
index 785620197c857492f30cf83b1c63e4af15e2a178..b658effd07e28240a82cf979ee4e5ee53f8cba9f 100644 (file)
@@ -160,54 +160,6 @@ flags_writable(int open_flags)
        return open_flags & (O_RDWR | O_WRONLY);
 }
 
-/* Like pread(), but keep trying until everything has been read or we know for
- * sure that there was an error. */
-static ssize_t
-full_pread(int fd, void *buf, size_t count, off_t offset)
-{
-       ssize_t bytes_remaining = count;
-       ssize_t bytes_read;
-
-       while (bytes_remaining > 0) {
-               bytes_read = pread(fd, buf, bytes_remaining, offset);
-               if (bytes_read <= 0) {
-                       if (bytes_read < 0) {
-                               if (errno == EINTR)
-                                       continue;
-                       } else {
-                               errno = EIO;
-                       }
-                       break;
-               }
-               bytes_remaining -= bytes_read;
-               buf += bytes_read;
-               offset += bytes_read;
-       }
-       return count - bytes_remaining;
-}
-
-/* Like pwrite(), but keep trying until everything has been written or we know
- * for sure that there was an error. */
-static ssize_t
-full_pwrite(int fd, const void *buf, size_t count, off_t offset)
-{
-       ssize_t bytes_remaining = count;
-       ssize_t bytes_written;
-
-       while (bytes_remaining > 0) {
-               bytes_written = pwrite(fd, buf, bytes_remaining, offset);
-               if (bytes_written < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       break;
-               }
-               bytes_remaining -= bytes_written;
-               buf += bytes_written;
-               offset += bytes_written;
-       }
-       return count - bytes_remaining;
-}
-
 /*
  * Allocate a file descriptor for a stream.
  *
@@ -347,6 +299,15 @@ close_wimfs_fd(struct wimfs_fd *fd)
        return 0;
 }
 
+static mode_t
+fuse_mask_mode(mode_t mode, struct fuse_context *fuse_ctx)
+{
+#if FUSE_MAJOR_VERSION > 2 || (FUSE_MAJOR_VERSION == 2 && FUSE_MINOR_VERSION >= 8)
+       mode &= ~fuse_ctx->umask;
+#endif
+       return mode;
+}
+
 /*
  * Add a new dentry with a new inode to a WIM image.
  *
@@ -385,7 +346,7 @@ create_dentry(struct fuse_context *fuse_ctx, const char *path,
                if (inode_set_unix_data(new->d_inode,
                                        fuse_ctx->uid,
                                        fuse_ctx->gid,
-                                       mode & ~fuse_ctx->umask,
+                                       fuse_mask_mode(mode, fuse_ctx),
                                        wimfs_ctx->wim->lookup_table,
                                        UNIX_DATA_ALL | UNIX_DATA_CREATE))
                {
@@ -1678,8 +1639,8 @@ wimfs_getxattr(const char *path, const char *name, char *value,
        if (res_size > size)
                return -ERANGE;
 
-       ret = read_full_resource_into_buf(lte, value, true);
-       if (ret != 0)
+       ret = read_full_resource_into_buf(lte, value);
+       if (ret)
                return -EIO;
 
        return res_size;
@@ -1944,7 +1905,7 @@ wimfs_read(const char *path, char *buf, size_t size,
                break;
        case RESOURCE_IN_WIM:
                if (read_partial_wim_resource_into_buf(fd->f_lte, size,
-                                                      offset, buf, true))
+                                                      offset, buf))
                        ret = -errno;
                else
                        ret = size;
@@ -2024,10 +1985,16 @@ wimfs_readlink(const char *path, char *buf, size_t buf_len)
                return -errno;
        if (!inode_is_symlink(inode))
                return -EINVAL;
-
-       ret = inode_readlink(inode, buf, buf_len, ctx->wim, true);
-       if (ret > 0)
+       if (buf_len == 0)
+               return -ENAMETOOLONG;
+       ret = wim_inode_readlink(inode, buf, buf_len - 1);
+       if (ret >= 0) {
+               wimlib_assert(ret <= buf_len - 1);
+               buf[ret] = '\0';
                ret = 0;
+       } else if (ret == -ENAMETOOLONG) {
+               buf[buf_len - 1] = '\0';
+       }
        return ret;
 }
 
@@ -2211,11 +2178,14 @@ wimfs_symlink(const char *to, const char *from)
                            FILE_ATTRIBUTE_REPARSE_POINT, &dentry);
        if (ret == 0) {
                dentry->d_inode->i_reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK;
-               if (inode_set_symlink(dentry->d_inode, to,
-                                     wimfs_ctx->wim->lookup_table, NULL))
-               {
+               ret = wim_inode_set_symlink(dentry->d_inode, to,
+                                           wimfs_ctx->wim->lookup_table);
+               if (ret) {
                        remove_dentry(dentry, wimfs_ctx->wim->lookup_table);
-                       ret = -ENOMEM;
+                       if (ret == WIMLIB_ERR_NOMEM)
+                               ret = -ENOMEM;
+                       else
+                               ret = -EIO;
                }
        }
        return ret;
@@ -2508,7 +2478,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
        }
 
        if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
-               ret = lock_wim(wim, wim->fp);
+               ret = lock_wim(wim, wim->in_fd);
                if (ret)
                        goto out;
        }