X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=libexfat%2Fio.c;h=32c144c4b4160fbc4a761236d9b84ca6e67447dd;hb=0bf92e47799832298bed8c5a111e4c3259944d02;hp=0a04aa136bacd4df44d2b21083fc3c9076329310;hpb=f25007bee6377f0977f07d6e1ca94730570b5452;p=android-x86%2Fexternal-exfat.git diff --git a/libexfat/io.c b/libexfat/io.c index 0a04aa1..32c144c 100644 --- a/libexfat/io.c +++ b/libexfat/io.c @@ -26,19 +26,19 @@ #include #include #include +#ifdef __APPLE__ +#include +#endif #ifdef USE_UBLIO #include #include #endif -#if !defined(_FILE_OFFSET_BITS) || (_FILE_OFFSET_BITS != 64) - #error You should define _FILE_OFFSET_BITS=64 -#endif - struct exfat_dev { int fd; enum exfat_mode mode; + off_t size; /* in bytes */ #ifdef USE_UBLIO off_t pos; ublio_filehandle_t ufh; @@ -142,6 +142,42 @@ struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) return NULL; } +#ifdef __APPLE__ + if (!S_ISREG(stbuf.st_mode)) + { + uint32_t block_size = 0; + uint64_t blocks = 0; + + if (ioctl(dev->fd, DKIOCGETBLOCKSIZE, &block_size) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get block size"); + return NULL; + } + if (ioctl(dev->fd, DKIOCGETBLOCKCOUNT, &blocks) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get blocks count"); + return NULL; + } + dev->size = blocks * block_size; + } + else +#endif + { + /* works for Linux, FreeBSD, Solaris */ + dev->size = exfat_seek(dev, 0, SEEK_END); + if (dev->size <= 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get device size"); + return NULL; + } + } + #ifdef USE_UBLIO memset(&up, 0, sizeof(struct ublio_param)); up.up_blocksize = 256 * 1024; @@ -198,6 +234,11 @@ enum exfat_mode exfat_get_mode(const struct exfat_dev* dev) return dev->mode; } +off_t exfat_get_size(const struct exfat_dev* dev) +{ + return dev->size; +} + off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence) { #ifdef USE_UBLIO @@ -304,11 +345,8 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, off_t lsize, loffset, remainder; if (offset + size > node->size) - { - int rc = exfat_truncate(ef, node, offset + size); - if (rc != 0) - return rc; - } + if (exfat_truncate(ef, node, offset + size) != 0) + return -1; if (size == 0) return 0;