diff --git a/include/fat12.h b/include/fat12.h index 5106e52..546318f 100644 --- a/include/fat12.h +++ b/include/fat12.h @@ -3,6 +3,7 @@ #include +struct pang_io; struct fat12_partition; struct fat12_dirent { char filename[256]; @@ -29,7 +30,7 @@ uint32_t fat12_read_u32(void *ptr); void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value); uint32_t fat12_get_cluster(void *fat, uint32_t cluster); -int fat12_defrag(int fd); -int fat12_mkfs(int fd, uint32_t bytes); +int fat12_defrag(struct pang_io *io); +int fat12_mkfs(struct pang_io *io, uint32_t bytes); #endif /* PANG_O_LIN_FAT12_H__ */ \ No newline at end of file diff --git a/include/io.h b/include/io.h index 53423ff..db46f38 100644 --- a/include/io.h +++ b/include/io.h @@ -11,10 +11,11 @@ #include #endif -ssize_t pang_write(int fd, const void *buf, size_t count); -ssize_t pang_read(int fd, void *buf, size_t count); -off_t pang_seek(int fd, off_t offset, int whence); -int pang_open(const char *pathname, int flags); -int pang_close(int fd); +struct pang_io; + +ssize_t pang_write(struct pang_io *io, off_t offset, const void *buf, size_t count); +ssize_t pang_read(struct pang_io *io, off_t offset, void *buf, size_t count); +struct pang_io *pang_open(const char *pathname); +int pang_close(struct pang_io **io); #endif /* PANG_O_LIN_IO_H__ */ \ No newline at end of file diff --git a/src/fat12.c b/src/fat12.c index d5414f0..e86bf9c 100644 --- a/src/fat12.c +++ b/src/fat12.c @@ -5,7 +5,7 @@ #include struct fat12_partition { - int fd; + struct pang_io *io; // Number of bytes in a sector (512) uint32_t sector_size; @@ -105,18 +105,15 @@ int fat12_open(struct fat12_partition *part, const char *filename) { if (!part) return -1; - if (part->fd > 0) + if (part->io) return -1; - part->fd = pang_open(filename, O_RDWR); - if (part->fd == -1) { - part->fd = 0; + part->io = pang_open(filename); + if (!part->io) return -1; - } - if (pang_read(part->fd, part->sector_buffer, sizeof(part->sector_buffer)) != sizeof(part->sector_buffer)) { + if (pang_read(part->io, 0, part->sector_buffer, sizeof(part->sector_buffer)) != sizeof(part->sector_buffer)) return -1; - } part->sector_size = fat12_read_u16(part->sector_buffer + 0x0b); @@ -165,8 +162,7 @@ static int fat12_ls_foreach_sector(struct fat12_partition *part, uint32_t sector struct fat12_dirent dirent; uint8_t buf[part->sector_size]; uint32_t offset; - pang_seek(part->fd, sector * part->sector_size, SEEK_SET); - pang_read(part->fd, buf, sizeof(buf)); + pang_read(part->io, sector * part->sector_size, buf, sizeof(buf)); for (offset = 0; offset < count; offset++) { struct fat_directory_entry *entry = &((struct fat_directory_entry *)buf)[offset]; @@ -211,14 +207,10 @@ int fat12_close(struct fat12_partition *part) { if (!part) return -1; - if (part->fd <= 0) - return -1; - - if (-1 == pang_close(part->fd)) { + if (-1 == pang_close(&part->io)) { return -1; } - part->fd = 0; return 0; } @@ -229,6 +221,9 @@ void fat12_free(struct fat12_partition **part) { if (!*part) return; + if ((*part)->io) + fat12_close(*part); + free(*part); *part = NULL; } \ No newline at end of file diff --git a/src/io.c b/src/io.c index c061c00..d22fca8 100644 --- a/src/io.c +++ b/src/io.c @@ -4,24 +4,41 @@ #include "io.h" #ifdef unix -ssize_t pang_write(int fd, const void *buf, size_t count) { - return write(fd, buf, count); + +struct pang_io { + int fd; +}; + +ssize_t pang_write(struct pang_io *io, off_t offset, const void *buf, size_t count) { + if (-1 == lseek(io->fd, offset, SEEK_SET)) + return -1; + return write(io->fd, buf, count); } -ssize_t pang_read(int fd, void *buf, size_t count) { - return read(fd, buf, count); +ssize_t pang_read(struct pang_io *io, off_t offset, void *buf, size_t count) { + if (-1 == lseek(io->fd, offset, SEEK_SET)) + return -1; + return read(io->fd, buf, count); } -off_t pang_seek(int fd, off_t offset, int whence) { - return lseek(fd, offset, whence); +struct pang_io *pang_open(const char *pathname) { + int fd = open(pathname, O_RDWR | O_TRUNC | O_CREAT, 0777); + if (-1 == fd) + return NULL; + struct pang_io *io = malloc(sizeof(struct pang_io)); + io->fd = fd; + return io; } -int pang_open(const char *pathname, int flags) { - return open(pathname, flags); -} - -int pang_close(int fd) { - return close(fd); +int pang_close(struct pang_io **io) { + if (!io) + return -1; + if (!*io) + return -1; + int ret = close((*io)->fd); + free(*io); + *io = NULL; + return ret; } #endif \ No newline at end of file diff --git a/src/mkfat.c b/src/mkfat.c index 350a937..3753eb8 100644 --- a/src/mkfat.c +++ b/src/mkfat.c @@ -12,8 +12,9 @@ // with length _bytes_. // It will define a root directory size and padding size so that the file sectors // end up on 4096-byte boundaries. -int fat12_mkfs(int fd, uint32_t bytes) { +int fat12_mkfs(struct pang_io *io, uint32_t bytes) { uint8_t mbr[512]; + off_t offset = 0; const uint32_t sector_size = 512; uint32_t cluster_size = 4096 / sector_size; // 4 kiB cluster sizes match flash erase block size if (bytes > 16000000) { @@ -118,9 +119,10 @@ int fat12_mkfs(int fd, uint32_t bytes) { fat12_write_u8(mbr + 0xff, 0xaa); // Write MBR to disk - if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { + if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { return -1; } + offset += sector_size; memset(mbr, 0, sizeof(mbr)); @@ -131,25 +133,28 @@ int fat12_mkfs(int fd, uint32_t bytes) { // Root directory is only one cluster // fat12_set_cluster(mbr, 2, 0xfff); - if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { + if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { return -1; } + offset += sector_size; // Fill in the rest of the FAT uint32_t fat_sector; memset(mbr, 0, sizeof(mbr)); for (fat_sector = 1; fat_sector < fat_size_sectors; fat_sector++) { - if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { + if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { return -1; } + offset += sector_size; } // Fill in the root directory uint32_t root_directory_sector; for (root_directory_sector = 0; root_directory_sector < cluster_size; root_directory_sector++) { - if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) { + if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) { return -1; } + offset += sector_size; } return 0; diff --git a/tests/fragment-file.c b/tests/fragment-file.c index 44d3c09..777961c 100644 --- a/tests/fragment-file.c +++ b/tests/fragment-file.c @@ -7,21 +7,22 @@ #include #include "fat12.h" +#include "io.h" static int make_image(const char *name, uint32_t size) { - int fd = open(name, O_WRONLY | O_CREAT, 0777); - if (-1 == fd) { + struct pang_io *io = pang_open(name); + if (!io) { fprintf(stderr, "couldn't open %s: %s\n", name, strerror(errno)); return 1; } - if (-1 == fat12_mkfs(fd, size)) { + if (-1 == fat12_mkfs(io, size)) { fprintf(stderr, "couldn't make fat12 on %s: %s\n", name, strerror(errno)); - close(fd); + pang_close(&io); return 1; } - close(fd); + pang_close(&io); return 0; } diff --git a/tests/mkfs-simple.c b/tests/mkfs-simple.c index 9e69aa4..93ef7d5 100644 --- a/tests/mkfs-simple.c +++ b/tests/mkfs-simple.c @@ -7,21 +7,22 @@ #include #include "fat12.h" +#include "io.h" static int make_image(const char *name, uint32_t size) { - int fd = open(name, O_WRONLY | O_CREAT, 0777); - if (-1 == fd) { + struct pang_io *io = pang_open(name); + if (!io) { fprintf(stderr, "couldn't open %s: %s\n", name, strerror(errno)); return 1; } - if (-1 == fat12_mkfs(fd, size)) { + if (-1 == fat12_mkfs(io, size)) { fprintf(stderr, "couldn't make fat12 on %s: %s\n", name, strerror(errno)); - close(fd); + pang_close(&io); return 1; } - close(fd); + pang_close(&io); return 0; }