OSDN Git Service

Set ctime to mtime to ensure we don't break programs that rely on ctime (e.g. rsync).
[android-x86/external-exfat.git] / libexfat / io.c
index c43938a..25988f0 100644 (file)
@@ -1,16 +1,29 @@
 /*
- *  io.c
- *  exFAT file system implementation library.
- *
- *  Created by Andrew Nayenko on 02.09.09.
- *  This software is distributed under the GNU General Public License 
- *  version 3 or any later.
- */
+       io.c (02.09.09)
+       exFAT file system implementation library.
+
+       Copyright (C) 2009, 2010  Andrew Nayenko
+
+       This program is free software: you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation, either version 3 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
 
 #include "exfat.h"
 #include <inttypes.h>
 #include <sys/types.h>
 #include <sys/uio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #define __USE_UNIX98 /* for pread() in Linux */
 #include <unistd.h>
 
        #error You should define _FILE_OFFSET_BITS=64
 #endif
 
+int exfat_open(const char* spec, int ro)
+{
+       int fd;
+       struct stat stbuf;
+
+       fd = open(spec, ro ? O_RDONLY : O_RDWR);
+       if (fd < 0)
+       {
+               exfat_error("failed to open `%s' in read-%s mode", spec,
+                               ro ? "only" : "write");
+               return -1;
+       }
+       if (fstat(fd, &stbuf) != 0)
+       {
+               close(fd);
+               exfat_error("failed to fstat `%s'", spec);
+               return -1;
+       }
+       if (!S_ISBLK(stbuf.st_mode) && !S_ISREG(stbuf.st_mode))
+       {
+               close(fd);
+               exfat_error("`%s' is neither a block device, nor a regular file",
+                               spec);
+               return -1;
+       }
+       return fd;
+}
+
 void exfat_read_raw(void* buffer, size_t size, off_t offset, int fd)
 {
        if (pread(fd, buffer, size, offset) != size)
@@ -67,7 +108,7 @@ ssize_t exfat_read(const struct exfat* ef, struct exfat_node* node,
                remainder -= lsize;
                cluster = exfat_next_cluster(ef, node, cluster);
        }
-       if (!ef->ro)
+       if (!ef->ro && !ef->noatime)
                exfat_update_atime(node);
        return size - remainder;
 }
@@ -111,7 +152,6 @@ ssize_t exfat_write(struct exfat* ef, struct exfat_node* node,
                remainder -= lsize;
                cluster = exfat_next_cluster(ef, node, cluster);
        }
-       node->mtime = time(NULL);
-       node->flags |= EXFAT_ATTRIB_DIRTY;
+       exfat_update_mtime(node);
        return size - remainder;
 }