diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 58 |
1 files changed, 54 insertions, 4 deletions
@@ -56,7 +56,7 @@ typedef struct { LIST_AUTO(C4GroupEntryData, GroupEntryList) #define ForeachGroupEntry(list) LIST_FOREACH(GroupEntryList, list, entry) -__off_t fileSizeFd(int fd) +off_t fileSizeFd(int fd) { struct stat st; @@ -292,8 +292,52 @@ int main(int argc, char* argv[]) size_t uncompressedSize = last->Offset + last->Size; currentSize += uncompressedSize; - header = realloc(header, currentSize); - uint8_t* data = (void*)(header) + sizeof(C4GroupHeader) + sizeof(C4GroupEntryCore) * header->Entries; + +#define TMP_FILE "cc4group.tmp" + int tmpFile = open(TMP_FILE, O_CREAT | O_RDWR | O_TRUNC | O_EXCL, 0600); + if(tmpFile == -1) + { + fprintf(stderr, "ERROR: Opening tmp file \"%s\": %s\n", "cc4group.tmp", strerror(errno)); + return EXIT_FAILURE; + } + + if(unlink(TMP_FILE) == -1) + { + fprintf(stderr, "ERROR: Deleting tmp file \"%s\". Manual deletion is required: %s\n", TMP_FILE, strerror(errno)); + } +#undef TMP_FILE + + // allocate file size + // https://gist.github.com/marcetcheverry/991042 + if(lseek(tmpFile, currentSize - 1, SEEK_SET) == -1) + { + fprintf(stderr, "ERROR: Seeking the tmp file to the end: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + if(write(tmpFile, "", 1) == -1) + { + fprintf(stderr, "ERROR: Writing to the tmp file's end: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + uint8_t* mmappedHeader = mmap(NULL, currentSize, PROT_READ | PROT_WRITE, MAP_SHARED, tmpFile, 0); + if(mmappedHeader == MAP_FAILED) + { + fprintf(stderr, "ERROR: Mapping tmp file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + if(close(tmpFile) == -1) + { + fprintf(stderr, "ERROR: Closing tmp file \"cc4group.tmp\": %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + uint8_t* data = (void*)(mmappedHeader) + sizeof(C4GroupHeader) + sizeof(C4GroupEntryCore) * header->Entries; + + // write alredy decompressed header and cores into the file + memcpy(mmappedHeader, header, data - mmappedHeader); strm.next_out = data; strm.avail_out = uncompressedSize; @@ -313,7 +357,7 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } - C4GroupEntryData root = {.data = (uint8_t*)header, .children = NULL}; + C4GroupEntryData root = {.data = (uint8_t*)mmappedHeader, .children = NULL}; buildChildren(&root); handleChildren(root.children, 0, argv[2]); @@ -322,5 +366,11 @@ int main(int argc, char* argv[]) free(header); + if(munmap(mmappedHeader, size) == -1) + { + fprintf(stderr, "ERROR: Unmapping tmp file: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } |
