]> wimlib.net Git - wimlib/blobdiff - src/mount_image.c
Update timestamp code; use utimensat()
[wimlib] / src / mount_image.c
index 6c5ec885ceea017a4d306d6247083fbc280d71cd..d9688765514f81baff478c2c39b15b877b2a25d6 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /*
- * Copyright (C) 2012 Eric Biggers
+ * Copyright (C) 2012, 2013 Eric Biggers
  *
  * This file is part of wimlib, a library for working with WIM files.
  *
 
 #ifdef WITH_FUSE
 
-#include "sha1.h"
-#include "lookup_table.h"
-#include "xml.h"
 #include "buffer_io.h"
+#include "lookup_table.h"
+#include "sha1.h"
 #include "timestamp.h"
+#include "xml.h"
+
+#include <errno.h>
+#include <ftw.h>
 #include <limits.h>
+#include <mqueue.h>
+#include <signal.h>
 #include <stdlib.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#define FUSE_USE_VERSION 26
-#include <errno.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <sys/time.h>
-#include <fuse.h>
-#include <ftw.h>
-#include <mqueue.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
 #include <utime.h>
-#include <signal.h>
+
+#define FUSE_USE_VERSION 26
+#include <fuse.h>
 
 #ifdef ENABLE_XATTR
 #include <attr/xattr.h>
@@ -416,13 +420,26 @@ static int inode_to_stbuf(const struct wim_inode *inode,
                stbuf->st_size = 0;
        }
 
+#ifdef HAVE_STAT_NANOSECOND_PRECISION
+       stbuf->st_atim = wim_timestamp_to_timespec(inode->i_last_access_time);
+       stbuf->st_mtim = wim_timestamp_to_timespec(inode->i_last_write_time);
+       stbuf->st_ctim = stbuf->st_mtim;
+#else
        stbuf->st_atime = wim_timestamp_to_unix(inode->i_last_access_time);
        stbuf->st_mtime = wim_timestamp_to_unix(inode->i_last_write_time);
-       stbuf->st_ctime = wim_timestamp_to_unix(inode->i_creation_time);
+       stbuf->st_ctime = stbuf->st_mtime;
+#endif
        stbuf->st_blocks = (stbuf->st_size + 511) / 512;
        return 0;
 }
 
+static void touch_inode(struct wim_inode *inode)
+{
+       u64 now = get_wim_timestamp();
+       inode->i_last_access_time = now;
+       inode->i_last_write_time = now;
+}
+
 /* Creates a new staging file and returns its file descriptor opened for
  * writing.
  *
@@ -2115,7 +2132,6 @@ static int wimfs_setxattr(const char *path, const char *name,
        if (existing_ads_entry) {
                if (flags & XATTR_CREATE)
                        return -EEXIST;
-               inode_remove_ads(inode, ads_idx, ctx->wim->lookup_table);
        } else {
                if (flags & XATTR_REPLACE)
                        return -ENOATTR;
@@ -2123,7 +2139,13 @@ static int wimfs_setxattr(const char *path, const char *name,
 
        ret = inode_add_ads_with_data(inode, name, (const u8*)value,
                                      size, ctx->wim->lookup_table);
-       return ret ? -ENOMEM : 0;
+       if (ret == 0) {
+               if (existing_ads_entry)
+                       inode_remove_ads(inode, ads_idx, ctx->wim->lookup_table);
+       } else {
+               ret = -ENOMEM;
+       }
+       return ret;
 }
 #endif
 
@@ -2232,13 +2254,13 @@ static int wimfs_utimens(const char *path, const struct timespec tv[2])
                if (tv[0].tv_nsec == UTIME_NOW)
                        inode->i_last_access_time = get_wim_timestamp();
                else
-                       inode->i_last_access_time = timespec_to_wim_timestamp(&tv[0]);
+                       inode->i_last_access_time = timespec_to_wim_timestamp(tv[0]);
        }
        if (tv[1].tv_nsec != UTIME_OMIT) {
                if (tv[1].tv_nsec == UTIME_NOW)
                        inode->i_last_write_time = get_wim_timestamp();
                else
-                       inode->i_last_write_time = timespec_to_wim_timestamp(&tv[1]);
+                       inode->i_last_write_time = timespec_to_wim_timestamp(tv[1]);
        }
        return 0;
 }
@@ -2287,9 +2309,8 @@ static int wimfs_write(const char *path, const char *buf, size_t size,
        if (ret == -1)
                return -errno;
 
-       now = get_wim_timestamp();
-       fd->f_inode->i_last_write_time = now;
-       fd->f_inode->i_last_access_time = now;
+       /* Update timestamps */
+       touch_inode(fd->f_inode);
        return ret;
 }
 
@@ -2620,8 +2641,12 @@ out:
 
 static inline int mount_unsupported_error()
 {
+#if defined(__WIN32__)
+       ERROR("Sorry-- Mounting WIM images is not supported on Windows!");
+#else
        ERROR("wimlib was compiled with --without-fuse, which disables support "
              "for mounting WIMs.");
+#endif
        return WIMLIB_ERR_UNSUPPORTED;
 }