int exfat_close(struct exfat_dev* dev);
int exfat_fsync(struct exfat_dev* dev);
enum exfat_mode exfat_get_mode(const struct exfat_dev* dev);
+off_t exfat_get_size(const struct exfat_dev* dev);
off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence);
ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size);
ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size);
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
+#ifdef __APPLE__
+#include <sys/disk.h>
+#endif
#ifdef USE_UBLIO
#include <sys/uio.h>
#include <ublio.h>
{
int fd;
enum exfat_mode mode;
+ off_t size; /* in bytes */
#ifdef USE_UBLIO
off_t pos;
ublio_filehandle_t ufh;
return NULL;
}
+#ifdef __APPLE__
+ if (S_ISBLK(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;
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
return get_sector_size() << get_spc_bits();
}
-static off_t setup_volume_size(struct exfat_dev* dev)
-{
- off_t size = exfat_seek(dev, 0, SEEK_END);
- if (size == (off_t) -1)
- exfat_error("failed to get volume size");
- return size;
-}
-
static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size)
{
int i;
{
param.sector_bits = sector_bits;
param.first_sector = first_sector;
-
- param.volume_size = setup_volume_size(dev);
- if (param.volume_size == (off_t) -1)
- return 1;
+ param.volume_size = exfat_get_size(dev);
param.spc_bits = setup_spc_bits(sector_bits, spc_bits, param.volume_size);
if (param.spc_bits == -1)